]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Mon, 22 Jan 2024 22:48:35 +0000 (17:48 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 22 Jan 2024 22:48:35 +0000 (17:48 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
148 files changed:
queue-6.6/acpi-property-let-args-be-null-in-__acpi_node_get_pr.patch [new file with mode: 0644]
queue-6.6/alsa-hda-properly-setup-hdmi-stream.patch [new file with mode: 0644]
queue-6.6/amt-do-not-use-overwrapped-cb-area.patch [new file with mode: 0644]
queue-6.6/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch [new file with mode: 0644]
queue-6.6/apparmor-fix-possible-memory-leak-in-unpack_trans_ta.patch [new file with mode: 0644]
queue-6.6/apparmor-fix-ref-count-leak-in-task_kill.patch [new file with mode: 0644]
queue-6.6/arm-9330-1-davinci-also-select-pinctrl.patch [new file with mode: 0644]
queue-6.6/arm64-ptrace-don-t-flush-za-zt-storage-when-writing-.patch [new file with mode: 0644]
queue-6.6/arm64-scs-work-around-full-lto-issue-with-dynamic-sc.patch [new file with mode: 0644]
queue-6.6/asoc-mediatek-sof-common-add-null-check-for-normal_l.patch [new file with mode: 0644]
queue-6.6/asoc-sof-ipc4-loader-remove-the-cpc-check-warnings.patch [new file with mode: 0644]
queue-6.6/base-node.c-initialize-the-accessor-list-before-regi.patch [new file with mode: 0644]
queue-6.6/block-ensure-we-hold-a-queue-reference-when-using-qu.patch [new file with mode: 0644]
queue-6.6/bpf-avoid-iter-offset-making-backward-progress-in-bp.patch [new file with mode: 0644]
queue-6.6/bpf-iter_udp-retry-with-a-larger-batch-size-without-.patch [new file with mode: 0644]
queue-6.6/bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch [new file with mode: 0644]
queue-6.6/bus-mhi-ep-do-not-allocate-event-ring-element-on-sta.patch [new file with mode: 0644]
queue-6.6/bus-mhi-ep-pass-mhi_ep_buf_info-struct-to-read-write.patch [new file with mode: 0644]
queue-6.6/bus-mhi-ep-use-slab-allocator-where-applicable.patch [new file with mode: 0644]
queue-6.6/cxl-port-fix-missing-target-list-lock.patch [new file with mode: 0644]
queue-6.6/cxl-region-fix-x9-interleave-typo.patch [new file with mode: 0644]
queue-6.6/drm-amdgpu-fall-back-to-input-power-for-avg-power-vi.patch [new file with mode: 0644]
queue-6.6/drm-amdkfd-fixes-for-hmm-mem-allocation.patch [new file with mode: 0644]
queue-6.6/dt-bindings-gpio-xilinx-fix-node-address-in-gpio.patch [new file with mode: 0644]
queue-6.6/erofs-fix-inconsistent-per-file-compression-format.patch [new file with mode: 0644]
queue-6.6/erofs-simplify-compression-configuration-parser.patch [new file with mode: 0644]
queue-6.6/ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch [new file with mode: 0644]
queue-6.6/gpio-mlxbf3-add-an-error-code-check-in-mlxbf3_gpio_p.patch [new file with mode: 0644]
queue-6.6/hisi_acc_vfio_pci-update-migration-data-pointer-corr.patch [new file with mode: 0644]
queue-6.6/i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch [new file with mode: 0644]
queue-6.6/i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch [new file with mode: 0644]
queue-6.6/iio-adc-ad9467-add-mutex-to-struct-ad9467_state.patch [new file with mode: 0644]
queue-6.6/iio-adc-ad9467-don-t-ignore-error-codes.patch [new file with mode: 0644]
queue-6.6/iio-adc-ad9467-fix-reset-gpio-handling.patch [new file with mode: 0644]
queue-6.6/iio-adc-ad9467-fix-scale-setting.patch [new file with mode: 0644]
queue-6.6/io_uring-adjust-defer-tw-counting.patch [new file with mode: 0644]
queue-6.6/iommu-don-t-reserve-0-length-iova-region.patch [new file with mode: 0644]
queue-6.6/iommu-map-reserved-memory-as-cacheable-if-device-is-.patch [new file with mode: 0644]
queue-6.6/ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch [new file with mode: 0644]
queue-6.6/ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch [new file with mode: 0644]
queue-6.6/kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch [new file with mode: 0644]
queue-6.6/leds-aw200xx-fix-write-to-dim-parameter.patch [new file with mode: 0644]
queue-6.6/leds-aw2013-select-missing-dependency-regmap_i2c.patch [new file with mode: 0644]
queue-6.6/libapi-add-missing-linux-types.h-header-to-get-the-_.patch [new file with mode: 0644]
queue-6.6/loongarch-bpf-prevent-out-of-bounds-memory-access.patch [new file with mode: 0644]
queue-6.6/loop-fix-the-the-direct-i-o-support-check-when-used-.patch [new file with mode: 0644]
queue-6.6/mfd-cs42l43-correct-soundwire-port-list.patch [new file with mode: 0644]
queue-6.6/mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch [new file with mode: 0644]
queue-6.6/mfd-rk8xx-fixup-devices-registration-with-platform_d.patch [new file with mode: 0644]
queue-6.6/mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch [new file with mode: 0644]
queue-6.6/mfd-tps6594-add-null-pointer-check-to-tps6594_device.patch [new file with mode: 0644]
queue-6.6/mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch [new file with mode: 0644]
queue-6.6/mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch [new file with mode: 0644]
queue-6.6/mips-dmi-fix-early-remap-on-mips32.patch [new file with mode: 0644]
queue-6.6/mips-fix-incorrect-max_low_pfn-adjustment.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_acl_tcam-fix-null-pointer-dereference.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch [new file with mode: 0644]
queue-6.6/mlxsw-spectrum_router-register-netdevice-notifier-be.patch [new file with mode: 0644]
queue-6.6/mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch [new file with mode: 0644]
queue-6.6/mptcp-refine-opt_mp_capable-determination.patch [new file with mode: 0644]
queue-6.6/mptcp-relax-check-on-mpc-passive-fallback.patch [new file with mode: 0644]
queue-6.6/mptcp-strict-validation-before-using-mp_opt-hmac.patch [new file with mode: 0644]
queue-6.6/mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch [new file with mode: 0644]
queue-6.6/mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch [new file with mode: 0644]
queue-6.6/net-add-more-sanity-check-in-virtio_net_hdr_to_skb.patch [new file with mode: 0644]
queue-6.6/net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch [new file with mode: 0644]
queue-6.6/net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch [new file with mode: 0644]
queue-6.6/net-micrel-fix-ptp-frame-parsing-for-lan8841.patch [new file with mode: 0644]
queue-6.6/net-netdev_queue-netdev_txq_completed_mb-fix-wake-co.patch [new file with mode: 0644]
queue-6.6/net-netdevsim-don-t-try-to-destroy-phc-on-vfs.patch [new file with mode: 0644]
queue-6.6/net-phy-micrel-populate-.soft_reset-for-ksz9131.patch [new file with mode: 0644]
queue-6.6/net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch [new file with mode: 0644]
queue-6.6/net-ravb-fix-dma_addr_t-truncation-in-error-case.patch [new file with mode: 0644]
queue-6.6/net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch [new file with mode: 0644]
queue-6.6/net-stmmac-fix-ethool-link-settings-ops-for-integrat.patch [new file with mode: 0644]
queue-6.6/net-tls-fix-warniing-in-__sk_msg_free.patch [new file with mode: 0644]
queue-6.6/netfilter-bridge-replace-physindev-with-physinif-in-.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_queue-remove-excess-nf_bridge-variable.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-do-not-allow-mismatch-field-size.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-reject-invalid-set-policy.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch [new file with mode: 0644]
queue-6.6/netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch [new file with mode: 0644]
queue-6.6/netfilter-nfnetlink_log-use-proper-helper-for-fetchi.patch [new file with mode: 0644]
queue-6.6/netfilter-nft_limit-do-not-ignore-unsupported-flags.patch [new file with mode: 0644]
queue-6.6/netfilter-propagate-net-to-nf_bridge_get_physindev.patch [new file with mode: 0644]
queue-6.6/nvme-trace-avoid-memcpy-overflow-warning.patch [new file with mode: 0644]
queue-6.6/nvmet-re-fix-tracing-strncpy-warning.patch [new file with mode: 0644]
queue-6.6/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch [new file with mode: 0644]
queue-6.6/nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch [new file with mode: 0644]
queue-6.6/nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch [new file with mode: 0644]
queue-6.6/octeontx2-af-cn10kb-fix-fifo-length-calculation-for-.patch [new file with mode: 0644]
queue-6.6/pci-avoid-potential-out-of-bounds-read-in-pci_dev_fo.patch [new file with mode: 0644]
queue-6.6/pci-epf-mhi-fix-the-dma-data-direction-of-dma_unmap_.patch [new file with mode: 0644]
queue-6.6/pci-keystone-fix-race-condition-when-initializing-ph.patch [new file with mode: 0644]
queue-6.6/pci-mediatek-gen3-fix-translation-window-size-calcul.patch [new file with mode: 0644]
queue-6.6/perf-db-export-fix-missing-reference-count-get-in-ca.patch [new file with mode: 0644]
queue-6.6/perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch [new file with mode: 0644]
queue-6.6/perf-genelf-set-elf-program-header-addresses-properl.patch [new file with mode: 0644]
queue-6.6/perf-header-fix-one-memory-leakage-in-perf_event__fp.patch [new file with mode: 0644]
queue-6.6/perf-header-fix-segfault-on-build_mem_topology-error.patch [new file with mode: 0644]
queue-6.6/perf-hisi-ptt-fix-one-memory-leakage-in-hisi_ptt_pro.patch [new file with mode: 0644]
queue-6.6/perf-mem-fix-error-on-hybrid-related-to-availability.patch [new file with mode: 0644]
queue-6.6/perf-stat-exit-perf-stat-if-parse-groups-fails.patch [new file with mode: 0644]
queue-6.6/perf-stat-fix-hard-coded-ll-miss-units.patch [new file with mode: 0644]
queue-6.6/perf-test-record-user-regs-fix-mask-for-vg-register.patch [new file with mode: 0644]
queue-6.6/perf-test-remove-atomics-from-test_loop-to-avoid-tes.patch [new file with mode: 0644]
queue-6.6/perf-unwind-libdw-handle-jit-generated-dsos-properly.patch [new file with mode: 0644]
queue-6.6/perf-unwind-libunwind-fix-base-address-for-.eh_frame.patch [new file with mode: 0644]
queue-6.6/perf-vendor-events-arm64-ampereone-rename-bpu_flush_.patch [new file with mode: 0644]
queue-6.6/power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch [new file with mode: 0644]
queue-6.6/power-supply-cw2015-correct-time_to_empty-units-in-s.patch [new file with mode: 0644]
queue-6.6/power-supply-fix-null-pointer-dereference-in-smb2_pr.patch [new file with mode: 0644]
queue-6.6/r8152-choose-our-usb-config-with-choose_configuratio.patch [new file with mode: 0644]
queue-6.6/riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch [new file with mode: 0644]
queue-6.6/riscv-fix-module_alloc-that-did-not-reset-the-linear.patch [new file with mode: 0644]
queue-6.6/riscv-fix-set_direct_map_default_noflush-to-reset-_p.patch [new file with mode: 0644]
queue-6.6/riscv-fix-set_memory_xx-and-set_direct_map_xx-by-spl.patch [new file with mode: 0644]
queue-6.6/riscv-fixed-wrong-register-in-xip_fixup_flash_offset.patch [new file with mode: 0644]
queue-6.6/rxrpc-fix-use-of-don-t-fragment-flag.patch [new file with mode: 0644]
queue-6.6/s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch [new file with mode: 0644]
queue-6.6/selftests-bonding-change-script-interpreter.patch [new file with mode: 0644]
queue-6.6/selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch [new file with mode: 0644]
queue-6.6/selftests-sgx-fix-uninitialized-pointer-dereference-.patch [new file with mode: 0644]
queue-6.6/selftests-sgx-fix-uninitialized-pointer-dereferences.patch [new file with mode: 0644]
queue-6.6/selftests-sgx-include-memory-clobber-for-inline-asm-.patch [new file with mode: 0644]
queue-6.6/selftests-sgx-skip-non-x86_64-platform.patch [new file with mode: 0644]
queue-6.6/serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch [new file with mode: 0644]
queue-6.6/serial-apbuart-fix-console-prompt-on-qemu.patch [new file with mode: 0644]
queue-6.6/serial-imx-correct-clock-error-message-in-function-p.patch [new file with mode: 0644]
queue-6.6/serial-imx-fix-tx-statemachine-deadlock.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/software-node-let-args-be-null-in-software_node_get_.patch [new file with mode: 0644]
queue-6.6/spi-coldfire-qspi-remove-an-erroneous-clk_disable_un.patch [new file with mode: 0644]
queue-6.6/spmi-mtk-pmif-serialize-pmif-status-check-and-comman.patch [new file with mode: 0644]
queue-6.6/srcu-use-try-lock-lockdep-annotation-for-nmi-safe-ac.patch [new file with mode: 0644]
queue-6.6/tty-don-t-check-for-signal_pending-in-send_break.patch [new file with mode: 0644]
queue-6.6/tty-early-return-from-send_break-on-tty_driver_hardw.patch [new file with mode: 0644]
queue-6.6/tty-use-if-in-send_break-instead-of-goto.patch [new file with mode: 0644]
queue-6.6/udp-annotate-data-races-around-up-pending.patch [new file with mode: 0644]
queue-6.6/um-virt-pci-fix-platform-map-offset.patch [new file with mode: 0644]
queue-6.6/usb-cdc-acm-return-correct-error-code-on-unsupported.patch [new file with mode: 0644]
queue-6.6/usb-core-allow-subclassed-usb-drivers-to-override-us.patch [new file with mode: 0644]
queue-6.6/usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch [new file with mode: 0644]
queue-6.6/usb-gadget-webcam-make-g_webcam-loadable-again.patch [new file with mode: 0644]
queue-6.6/usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch [new file with mode: 0644]
queue-6.6/vdpa-fix-an-error-handling-path-in-eni_vdpa_probe.patch [new file with mode: 0644]
queue-6.6/vfio-pds-fix-calculations-in-pds_vfio_dirty_sync.patch [new file with mode: 0644]

diff --git a/queue-6.6/acpi-property-let-args-be-null-in-__acpi_node_get_pr.patch b/queue-6.6/acpi-property-let-args-be-null-in-__acpi_node_get_pr.patch
new file mode 100644 (file)
index 0000000..dfa5ed2
--- /dev/null
@@ -0,0 +1,52 @@
+From d45c46548507b2ee48ad4668f556d1043c0a9f39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Nov 2023 12:10:08 +0200
+Subject: acpi: property: Let args be NULL in
+ __acpi_node_get_property_reference
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit bef52aa0f3de1b7d8c258c13b16e577361dabf3a ]
+
+fwnode_get_property_reference_args() may not be called with args argument
+NULL on ACPI, OF already supports this. Add the missing NULL checks and
+document this.
+
+The purpose is to be able to count the references.
+
+Fixes: 977d5ad39f3e ("ACPI: Convert ACPI reference args to generic fwnode reference args")
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20231109101010.1329587-2-sakari.ailus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/acpi/property.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c
+index 99b4e3355435..4d958a165da0 100644
+--- a/drivers/acpi/property.c
++++ b/drivers/acpi/property.c
+@@ -851,6 +851,7 @@ static int acpi_get_ref_args(struct fwnode_reference_args *args,
+  * @index: Index of the reference to return
+  * @num_args: Maximum number of arguments after each reference
+  * @args: Location to store the returned reference with optional arguments
++ *      (may be NULL)
+  *
+  * Find property with @name, verifify that it is a package containing at least
+  * one object reference and if so, store the ACPI device object pointer to the
+@@ -907,6 +908,9 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
+               if (!device)
+                       return -EINVAL;
++              if (!args)
++                      return 0;
++
+               args->fwnode = acpi_fwnode_handle(device);
+               args->nargs = 0;
+               return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.6/alsa-hda-properly-setup-hdmi-stream.patch b/queue-6.6/alsa-hda-properly-setup-hdmi-stream.patch
new file mode 100644 (file)
index 0000000..8a29a25
--- /dev/null
@@ -0,0 +1,54 @@
+From 6a08b23753a28b2090cb79b879605c53f3375a35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 12:33:49 +0100
+Subject: ALSA: hda: Properly setup HDMI stream
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Amadeusz SÅ‚awiÅ„ski <amadeuszx.slawinski@linux.intel.com>
+
+[ Upstream commit 454abb80e26ab85323a30e52aa7b0ee9aae1d38a ]
+
+Since commit 4005d1ba0a7e ("ASoC: soc-dai: don't call PCM audio ops if
+the stream is not supported") HDMI playback is broken with avs driver.
+This happens because for HDMI stream (unlike generic HDA one)
+channels_min for stream is not set when creating PCMs. Fix this by
+setting the value based on first available converter.
+
+Fixes: 4005d1ba0a7e ("ASoC: soc-dai: don't call PCM audio ops if the stream is not supported")
+Signed-off-by: Amadeusz SÅ‚awiÅ„ski <amadeuszx.slawinski@linux.intel.com>
+Link: https://lore.kernel.org/r/20240112113349.2905328-1-amadeuszx.slawinski@linux.intel.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/pci/hda/patch_hdmi.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index 78cee53fee02..038db8902c9e 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -2301,6 +2301,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
+       codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+       for (idx = 0; idx < pcm_num; idx++) {
++              struct hdmi_spec_per_cvt *per_cvt;
+               struct hda_pcm *info;
+               struct hda_pcm_stream *pstr;
+@@ -2316,6 +2317,11 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
+               pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
+               pstr->substreams = 1;
+               pstr->ops = generic_ops;
++
++              per_cvt = get_cvt(spec, 0);
++              pstr->channels_min = per_cvt->channels_min;
++              pstr->channels_max = per_cvt->channels_max;
++
+               /* pcm number is less than pcm_rec array size */
+               if (spec->pcm_used >= ARRAY_SIZE(spec->pcm_rec))
+                       break;
+-- 
+2.43.0
+
diff --git a/queue-6.6/amt-do-not-use-overwrapped-cb-area.patch b/queue-6.6/amt-do-not-use-overwrapped-cb-area.patch
new file mode 100644 (file)
index 0000000..a9a8faf
--- /dev/null
@@ -0,0 +1,60 @@
+From 747668f39b3e834c7a8f99ea87fd695e69fc9b0c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jan 2024 14:42:41 +0000
+Subject: amt: do not use overwrapped cb area
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit bec161add35b478a7746bf58bcdea6faa19129ef ]
+
+amt driver uses skb->cb for storing tunnel information.
+This job is worked before TC layer and then amt driver load tunnel info
+from skb->cb after TC layer.
+So, its cb area should not be overwrapped with CB area used by TC.
+In order to not use cb area used by TC, it skips the biggest cb
+structure used by TC, which was qdisc_skb_cb.
+But it's not anymore.
+Currently, biggest structure of TC's CB is tc_skb_cb.
+So, it should skip size of tc_skb_cb instead of qdisc_skb_cb.
+
+Fixes: ec624fe740b4 ("net/sched: Extend qdisc control block with tc control block")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Link: https://lore.kernel.org/r/20240107144241.4169520-1-ap420073@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/amt.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/amt.c b/drivers/net/amt.c
+index 2d20be6ffb7e..ddd087c2c3ed 100644
+--- a/drivers/net/amt.c
++++ b/drivers/net/amt.c
+@@ -11,7 +11,7 @@
+ #include <linux/net.h>
+ #include <linux/igmp.h>
+ #include <linux/workqueue.h>
+-#include <net/sch_generic.h>
++#include <net/pkt_sched.h>
+ #include <net/net_namespace.h>
+ #include <net/ip.h>
+ #include <net/udp.h>
+@@ -80,11 +80,11 @@ static struct mld2_grec mldv2_zero_grec;
+ static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb)
+ {
+-      BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct qdisc_skb_cb) >
++      BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) >
+                    sizeof_field(struct sk_buff, cb));
+       return (struct amt_skb_cb *)((void *)skb->cb +
+-              sizeof(struct qdisc_skb_cb));
++              sizeof(struct tc_skb_cb));
+ }
+ static void __amt_source_gc_work(void)
+-- 
+2.43.0
+
diff --git a/queue-6.6/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch b/queue-6.6/apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch
new file mode 100644 (file)
index 0000000..1c83bb1
--- /dev/null
@@ -0,0 +1,82 @@
+From e89edad6c42ad22ed686d2da31329b977f05ed8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Dec 2023 19:07:43 +0300
+Subject: apparmor: avoid crash when parsed profile name is empty
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 55a8210c9e7d21ff2644809699765796d4bfb200 ]
+
+When processing a packed profile in unpack_profile() described like
+
+ "profile :ns::samba-dcerpcd /usr/lib*/samba/{,samba/}samba-dcerpcd {...}"
+
+a string ":samba-dcerpcd" is unpacked as a fully-qualified name and then
+passed to aa_splitn_fqname().
+
+aa_splitn_fqname() treats ":samba-dcerpcd" as only containing a namespace.
+Thus it returns NULL for tmpname, meanwhile tmpns is non-NULL. Later
+aa_alloc_profile() crashes as the new profile name is NULL now.
+
+general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] PREEMPT SMP KASAN NOPTI
+KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007]
+CPU: 6 PID: 1657 Comm: apparmor_parser Not tainted 6.7.0-rc2-dirty #16
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014
+RIP: 0010:strlen+0x1e/0xa0
+Call Trace:
+ <TASK>
+ ? strlen+0x1e/0xa0
+ aa_policy_init+0x1bb/0x230
+ aa_alloc_profile+0xb1/0x480
+ unpack_profile+0x3bc/0x4960
+ aa_unpack+0x309/0x15e0
+ aa_replace_profiles+0x213/0x33c0
+ policy_update+0x261/0x370
+ profile_replace+0x20e/0x2a0
+ vfs_write+0x2af/0xe00
+ ksys_write+0x126/0x250
+ do_syscall_64+0x46/0xf0
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+ </TASK>
+---[ end trace 0000000000000000 ]---
+RIP: 0010:strlen+0x1e/0xa0
+
+It seems such behaviour of aa_splitn_fqname() is expected and checked in
+other places where it is called (e.g. aa_remove_profiles). Well, there
+is an explicit comment "a ns name without a following profile is allowed"
+inside.
+
+AFAICS, nothing can prevent unpacked "name" to be in form like
+":samba-dcerpcd" - it is passed from userspace.
+
+Deny the whole profile set replacement in such case and inform user with
+EPROTO and an explaining message.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: 04dc715e24d0 ("apparmor: audit policy ns specified in policy load")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/policy_unpack.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index a904bca24026..d92788da6704 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -825,6 +825,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
+       tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
+       if (tmpns) {
++              if (!tmpname) {
++                      info = "empty profile name";
++                      goto fail;
++              }
+               *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
+               if (!*ns_name) {
+                       info = "out of memory";
+-- 
+2.43.0
+
diff --git a/queue-6.6/apparmor-fix-possible-memory-leak-in-unpack_trans_ta.patch b/queue-6.6/apparmor-fix-possible-memory-leak-in-unpack_trans_ta.patch
new file mode 100644 (file)
index 0000000..a8371b4
--- /dev/null
@@ -0,0 +1,92 @@
+From e2a65fa1cb1f285b9461fa05ba419ed4970cdc0d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 21:19:44 +0300
+Subject: apparmor: fix possible memory leak in unpack_trans_table
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit 1342ad786073e96fa813ad943c19f586157ae297 ]
+
+If we fail to unpack the transition table then the table elements which
+have been already allocated are not freed on error path.
+
+unreferenced object 0xffff88802539e000 (size 128):
+  comm "apparmor_parser", pid 903, jiffies 4294914938 (age 35.085s)
+  hex dump (first 32 bytes):
+    20 73 6f 6d 65 20 6e 61 73 74 79 20 73 74 72 69   some nasty stri
+    6e 67 20 73 6f 6d 65 20 6e 61 73 74 79 20 73 74  ng some nasty st
+  backtrace:
+    [<ffffffff81ddb312>] __kmem_cache_alloc_node+0x1e2/0x2d0
+    [<ffffffff81c47194>] __kmalloc_node_track_caller+0x54/0x170
+    [<ffffffff81c225b9>] kmemdup+0x29/0x60
+    [<ffffffff83e1ee65>] aa_unpack_strdup+0xe5/0x1b0
+    [<ffffffff83e20808>] unpack_pdb+0xeb8/0x2700
+    [<ffffffff83e23567>] unpack_profile+0x1507/0x4a30
+    [<ffffffff83e27bfa>] aa_unpack+0x36a/0x1560
+    [<ffffffff83e194c3>] aa_replace_profiles+0x213/0x33c0
+    [<ffffffff83de9461>] policy_update+0x261/0x370
+    [<ffffffff83de978e>] profile_replace+0x20e/0x2a0
+    [<ffffffff81eac8bf>] vfs_write+0x2af/0xe00
+    [<ffffffff81eaddd6>] ksys_write+0x126/0x250
+    [<ffffffff88f34fb6>] do_syscall_64+0x46/0xf0
+    [<ffffffff890000ea>] entry_SYSCALL_64_after_hwframe+0x6e/0x76
+
+Call aa_free_str_table() on error path as was done before the blamed
+commit. It implements all necessary checks, frees str_table if it is
+available and nullifies the pointers.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: a0792e2ceddc ("apparmor: make transition table unpack generic so it can be reused")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lib.c           | 1 +
+ security/apparmor/policy_unpack.c | 7 +++----
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
+index c87bccafff44..7182a8b821fb 100644
+--- a/security/apparmor/lib.c
++++ b/security/apparmor/lib.c
+@@ -41,6 +41,7 @@ void aa_free_str_table(struct aa_str_table *t)
+                       kfree_sensitive(t->table[i]);
+               kfree_sensitive(t->table);
+               t->table = NULL;
++              t->size = 0;
+       }
+ }
+diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
+index dbc83455d900..a904bca24026 100644
+--- a/security/apparmor/policy_unpack.c
++++ b/security/apparmor/policy_unpack.c
+@@ -478,6 +478,8 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs)
+               if (!table)
+                       goto fail;
++              strs->table = table;
++              strs->size = size;
+               for (i = 0; i < size; i++) {
+                       char *str;
+                       int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL);
+@@ -520,14 +522,11 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs)
+                       goto fail;
+               if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
+                       goto fail;
+-
+-              strs->table = table;
+-              strs->size = size;
+       }
+       return true;
+ fail:
+-      kfree_sensitive(table);
++      aa_free_str_table(strs);
+       e->pos = saved_pos;
+       return false;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/apparmor-fix-ref-count-leak-in-task_kill.patch b/queue-6.6/apparmor-fix-ref-count-leak-in-task_kill.patch
new file mode 100644 (file)
index 0000000..ff863ed
--- /dev/null
@@ -0,0 +1,35 @@
+From 290739cc5b3fd726519ae46457a5b4ec4abd65ba Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Dec 2023 06:54:41 -0800
+Subject: apparmor: Fix ref count leak in task_kill
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ Upstream commit 2cb54a19ac7153b9a26a72098c495187f64c2276 ]
+
+apparmor_task_kill was not putting the task_cred reference tc, or the
+cred_label reference tc when dealing with a passed in cred, fix this
+by using a single fn exit.
+
+Fixes: 90c436a64a6e ("apparmor: pass cred through to audit info.")
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ security/apparmor/lsm.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index 6fdab1b5ede5..366cdfd6a7ba 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -839,7 +839,6 @@ static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo
+               cl = aa_get_newest_cred_label(cred);
+               error = aa_may_signal(cred, cl, tc, tl, sig);
+               aa_put_label(cl);
+-              return error;
+       } else {
+               cl = __begin_current_label_crit_section();
+               error = aa_may_signal(current_cred(), cl, tc, tl, sig);
+-- 
+2.43.0
+
diff --git a/queue-6.6/arm-9330-1-davinci-also-select-pinctrl.patch b/queue-6.6/arm-9330-1-davinci-also-select-pinctrl.patch
new file mode 100644 (file)
index 0000000..8d53b71
--- /dev/null
@@ -0,0 +1,48 @@
+From 9e5a251c2c1e19102c15579018f95a2365ab4314 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 7 Nov 2023 01:36:03 +0100
+Subject: ARM: 9330/1: davinci: also select PINCTRL
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit f54e8634d1366926c807e2af6125b33cff555fa7 ]
+
+kconfig warns when PINCTRL_SINGLE is selected but PINCTRL is not
+set, so also set PINCTRL for ARCH_DAVINCI. This prevents a
+kconfig/build warning:
+
+   WARNING: unmet direct dependencies detected for PINCTRL_SINGLE
+     Depends on [n]: PINCTRL [=n] && OF [=y] && HAS_IOMEM [=y]
+     Selected by [y]:
+     - ARCH_DAVINCI [=y] && ARCH_MULTI_V5 [=y]
+
+Closes: lore.kernel.org/r/202311070548.0f6XfBrh-lkp@intel.com
+
+Fixes: f962396ce292 ("ARM: davinci: support multiplatform build for ARM v5")
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Reported-by: kernel test robot <lkp@intel.com>
+Cc: Bartosz Golaszewski <brgl@bgdev.pl>
+Cc: Arnd Bergmann <arnd@arndb.de>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: patches@armlinux.org.uk
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/mach-davinci/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
+index 59de137c6f53..2a8a9fe46586 100644
+--- a/arch/arm/mach-davinci/Kconfig
++++ b/arch/arm/mach-davinci/Kconfig
+@@ -11,6 +11,7 @@ menuconfig ARCH_DAVINCI
+       select PM_GENERIC_DOMAINS_OF if PM && OF
+       select REGMAP_MMIO
+       select RESET_CONTROLLER
++      select PINCTRL
+       select PINCTRL_SINGLE
+ if ARCH_DAVINCI
+-- 
+2.43.0
+
diff --git a/queue-6.6/arm64-ptrace-don-t-flush-za-zt-storage-when-writing-.patch b/queue-6.6/arm64-ptrace-don-t-flush-za-zt-storage-when-writing-.patch
new file mode 100644 (file)
index 0000000..eb1b614
--- /dev/null
@@ -0,0 +1,55 @@
+From 6f0ade78b3058199ac4a2d86210a11f1562b3ad8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 18:42:38 +0000
+Subject: arm64/ptrace: Don't flush ZA/ZT storage when writing ZA via ptrace
+
+From: Mark Brown <broonie@kernel.org>
+
+[ Upstream commit b7c510d049049409e8945b932f4b0b357fa17415 ]
+
+When writing ZA we currently unconditionally flush the buffer used to store
+it as part of ensuring that it is allocated. Since this buffer is shared
+with ZT0 this means that a write to ZA when PSTATE.ZA is already set will
+corrupt the value of ZT0 on a SME2 system. Fix this by only flushing the
+backing storage if PSTATE.ZA was not previously set.
+
+This will mean that short or failed writes may leave stale data in the
+buffer, this seems as correct as our current behaviour and unlikely to be
+something that userspace will rely on.
+
+Fixes: f90b529bcbe5 ("arm64/sme: Implement ZT0 ptrace support")
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Link: https://lore.kernel.org/r/20240115-arm64-fix-ptrace-za-zt-v1-1-48617517028a@kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/ptrace.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
+index 20d7ef82de90..b3f64144b5cd 100644
+--- a/arch/arm64/kernel/ptrace.c
++++ b/arch/arm64/kernel/ptrace.c
+@@ -1107,12 +1107,13 @@ static int za_set(struct task_struct *target,
+               }
+       }
+-      /* Allocate/reinit ZA storage */
+-      sme_alloc(target, true);
+-      if (!target->thread.sme_state) {
+-              ret = -ENOMEM;
+-              goto out;
+-      }
++      /*
++       * Only flush the storage if PSTATE.ZA was not already set,
++       * otherwise preserve any existing data.
++       */
++      sme_alloc(target, !thread_za_enabled(&target->thread));
++      if (!target->thread.sme_state)
++              return -ENOMEM;
+       /* If there is no data then disable ZA */
+       if (!count) {
+-- 
+2.43.0
+
diff --git a/queue-6.6/arm64-scs-work-around-full-lto-issue-with-dynamic-sc.patch b/queue-6.6/arm64-scs-work-around-full-lto-issue-with-dynamic-sc.patch
new file mode 100644 (file)
index 0000000..dea33fd
--- /dev/null
@@ -0,0 +1,51 @@
+From 427661778c522c06d7b0ddc5330f37518a9eb704 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 14:26:20 +0100
+Subject: arm64: scs: Work around full LTO issue with dynamic SCS
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 8c5a19cb17a71e52303150335b459c7d2d28a155 ]
+
+Full LTO takes the '-mbranch-protection=none' passed to the compiler
+when generating the dynamic shadow call stack patching code as a hint to
+stop emitting PAC instructions altogether. (Thin LTO appears unaffected
+by this)
+
+Work around this by stripping unwind tables from the object in question,
+which should be sufficient to prevent the patching code from attempting
+to patch itself.
+
+Fixes: 3b619e22c460 ("arm64: implement dynamic shadow call stack for Clang")
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Reviewed-by: Sami Tolvanen <samitolvanen@google.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20240110132619.258809-2-ardb+git@google.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/kernel/Makefile | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
+index d95b3d6b471a..e5d03a7039b4 100644
+--- a/arch/arm64/kernel/Makefile
++++ b/arch/arm64/kernel/Makefile
+@@ -73,7 +73,13 @@ obj-$(CONFIG_ARM64_MTE)                     += mte.o
+ obj-y                                 += vdso-wrap.o
+ obj-$(CONFIG_COMPAT_VDSO)             += vdso32-wrap.o
+ obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS)       += patch-scs.o
+-CFLAGS_patch-scs.o                    += -mbranch-protection=none
++
++# We need to prevent the SCS patching code from patching itself. Using
++# -mbranch-protection=none here to avoid the patchable PAC opcodes from being
++# generated triggers an issue with full LTO on Clang, which stops emitting PAC
++# instructions altogether. So instead, omit the unwind tables used by the
++# patching code, so it will not be able to locate its own PAC instructions.
++CFLAGS_patch-scs.o                    += -fno-asynchronous-unwind-tables -fno-unwind-tables
+ # Force dependency (vdso*-wrap.S includes vdso.so through incbin)
+ $(obj)/vdso-wrap.o: $(obj)/vdso/vdso.so
+-- 
+2.43.0
+
diff --git a/queue-6.6/asoc-mediatek-sof-common-add-null-check-for-normal_l.patch b/queue-6.6/asoc-mediatek-sof-common-add-null-check-for-normal_l.patch
new file mode 100644 (file)
index 0000000..8b18a94
--- /dev/null
@@ -0,0 +1,45 @@
+From 06dec544824b13233e806763fbbe18d9d1b4a469 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 11:52:26 +0100
+Subject: ASoC: mediatek: sof-common: Add NULL check for normal_link string
+
+From: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+[ Upstream commit e3b3ec967a7d93b9010a5af9a2394c8b5c8f31ed ]
+
+It's not granted that all entries of struct sof_conn_stream declare
+a `normal_link` (a non-SOF, direct link) string, and this is the case
+for SoCs that support only SOF paths (hence do not support both direct
+and SOF usecases).
+
+For example, in the case of MT8188 there is no normal_link string in
+any of the sof_conn_stream entries and there will be more drivers
+doing that in the future.
+
+To avoid possible NULL pointer KPs, add a NULL check for `normal_link`.
+
+Fixes: 0caf1120c583 ("ASoC: mediatek: mt8195: extract SOF common code")
+Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Link: https://msgid.link/r/20240111105226.117603-1-angelogioacchino.delregno@collabora.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/mediatek/common/mtk-dsp-sof-common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/sound/soc/mediatek/common/mtk-dsp-sof-common.c b/sound/soc/mediatek/common/mtk-dsp-sof-common.c
+index 6fef16306f74..21a9403b7e92 100644
+--- a/sound/soc/mediatek/common/mtk-dsp-sof-common.c
++++ b/sound/soc/mediatek/common/mtk-dsp-sof-common.c
+@@ -24,7 +24,7 @@ int mtk_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
+               struct snd_soc_dai_link *sof_dai_link = NULL;
+               const struct sof_conn_stream *conn = &sof_priv->conn_streams[i];
+-              if (strcmp(rtd->dai_link->name, conn->normal_link))
++              if (conn->normal_link && strcmp(rtd->dai_link->name, conn->normal_link))
+                       continue;
+               for_each_card_rtds(card, runtime) {
+-- 
+2.43.0
+
diff --git a/queue-6.6/asoc-sof-ipc4-loader-remove-the-cpc-check-warnings.patch b/queue-6.6/asoc-sof-ipc4-loader-remove-the-cpc-check-warnings.patch
new file mode 100644 (file)
index 0000000..0d30cbf
--- /dev/null
@@ -0,0 +1,59 @@
+From 45f91329ed6becd3c15b9ead87bf7fccd6da119a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 11:22:09 +0200
+Subject: ASoC: SOF: ipc4-loader: remove the CPC check warnings
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+
+[ Upstream commit ab09fb9c629ed3aaea6a82467f08595dbc549726 ]
+
+Warnings related to missing data in firmware manifest have
+proven to be too verbose. This relates to description of
+DSP module cost expressed in cycles per chunk (CPC). If
+a matching value is not found in the manifest, kernel will
+pass a zero value and DSP firmware will use a conservative
+value in its place.
+
+Downgrade the warnings to dev_dbg().
+
+Fixes: d8a2c9879349 ("ASoC: SOF: ipc4-loader/topology: Query the CPC value from manifest")
+Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
+Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com>
+Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
+Link: https://msgid.link/r/20240115092209.7184-3-peter.ujfalusi@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/sof/ipc4-loader.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/sound/soc/sof/ipc4-loader.c b/sound/soc/sof/ipc4-loader.c
+index eaa04762eb11..4d37e89b592a 100644
+--- a/sound/soc/sof/ipc4-loader.c
++++ b/sound/soc/sof/ipc4-loader.c
+@@ -479,13 +479,10 @@ void sof_ipc4_update_cpc_from_manifest(struct snd_sof_dev *sdev,
+               msg = "No CPC match in the firmware file's manifest";
+ no_cpc:
+-      dev_warn(sdev->dev, "%s (UUID: %pUL): %s (ibs/obs: %u/%u)\n",
+-               fw_module->man4_module_entry.name,
+-               &fw_module->man4_module_entry.uuid, msg, basecfg->ibs,
+-               basecfg->obs);
+-      dev_warn_once(sdev->dev, "Please try to update the firmware.\n");
+-      dev_warn_once(sdev->dev, "If the issue persists, file a bug at\n");
+-      dev_warn_once(sdev->dev, "https://github.com/thesofproject/sof/issues/\n");
++      dev_dbg(sdev->dev, "%s (UUID: %pUL): %s (ibs/obs: %u/%u)\n",
++              fw_module->man4_module_entry.name,
++              &fw_module->man4_module_entry.uuid, msg, basecfg->ibs,
++              basecfg->obs);
+ }
+ const struct sof_ipc_fw_loader_ops ipc4_loader_ops = {
+-- 
+2.43.0
+
diff --git a/queue-6.6/base-node.c-initialize-the-accessor-list-before-regi.patch b/queue-6.6/base-node.c-initialize-the-accessor-list-before-regi.patch
new file mode 100644 (file)
index 0000000..36d56ce
--- /dev/null
@@ -0,0 +1,64 @@
+From afa19df0f792b63502994ec88c2d7629def42556 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Oct 2023 00:42:39 -0400
+Subject: base/node.c: initialize the accessor list before registering
+
+From: Gregory Price <gourry.memverge@gmail.com>
+
+[ Upstream commit 48b5928e18dc27e05cab3dc4c78cd8a15baaf1e5 ]
+
+The current code registers the node as available in the node array
+before initializing the accessor list.  This makes it so that
+anything which might access the accessor list as a result of
+allocations will cause an undefined memory access.
+
+In one example, an extension to access hmat data during interleave
+caused this undefined access as a result of a bulk allocation
+that occurs during node initialization but before the accessor
+list is initialized.
+
+Initialize the accessor list before making the node generally
+available to the global system.
+
+Fixes: 08d9dbe72b1f ("node: Link memory nodes to their compute nodes")
+Signed-off-by: Gregory Price <gregory.price@memverge.com>
+Link: https://lore.kernel.org/r/20231030044239.971756-1-gregory.price@memverge.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/node.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/base/node.c b/drivers/base/node.c
+index 493d533f8375..4d588f4658c8 100644
+--- a/drivers/base/node.c
++++ b/drivers/base/node.c
+@@ -868,11 +868,15 @@ int __register_one_node(int nid)
+ {
+       int error;
+       int cpu;
++      struct node *node;
+-      node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL);
+-      if (!node_devices[nid])
++      node = kzalloc(sizeof(struct node), GFP_KERNEL);
++      if (!node)
+               return -ENOMEM;
++      INIT_LIST_HEAD(&node->access_list);
++      node_devices[nid] = node;
++
+       error = register_node(node_devices[nid], nid);
+       /* link cpu under this node */
+@@ -881,7 +885,6 @@ int __register_one_node(int nid)
+                       register_cpu_under_node(cpu, nid);
+       }
+-      INIT_LIST_HEAD(&node_devices[nid]->access_list);
+       node_init_caches(nid);
+       return error;
+-- 
+2.43.0
+
diff --git a/queue-6.6/block-ensure-we-hold-a-queue-reference-when-using-qu.patch b/queue-6.6/block-ensure-we-hold-a-queue-reference-when-using-qu.patch
new file mode 100644 (file)
index 0000000..0a168c5
--- /dev/null
@@ -0,0 +1,71 @@
+From 759328c0a8bf2120a9d1e7eae9e89a8529d81043 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 09:12:20 -0700
+Subject: block: ensure we hold a queue reference when using queue limits
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ Upstream commit 7b4f36cd22a65b750b4cb6ac14804fb7d6e6c67d ]
+
+q_usage_counter is the only thing preventing us from the limits changing
+under us in __bio_split_to_limits, but blk_mq_submit_bio doesn't hold
+it while calling into it.
+
+Move the splitting inside the region where we know we've got a queue
+reference. Ideally this could still remain a shared section of code, but
+let's keep the fix simple and defer any refactoring here to later.
+
+Reported-by: Christoph Hellwig <hch@lst.de>
+Fixes: 900e08075202 ("block: move queue enter logic into blk_mq_submit_bio()")
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ block/blk-mq.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index 20ecd0ab616f..6041e17492ec 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -2968,12 +2968,6 @@ void blk_mq_submit_bio(struct bio *bio)
+       blk_status_t ret;
+       bio = blk_queue_bounce(bio, q);
+-      if (bio_may_exceed_limits(bio, &q->limits)) {
+-              bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
+-              if (!bio)
+-                      return;
+-      }
+-
+       bio_set_ioprio(bio);
+       if (plug) {
+@@ -2982,6 +2976,11 @@ void blk_mq_submit_bio(struct bio *bio)
+                       rq = NULL;
+       }
+       if (rq) {
++              if (unlikely(bio_may_exceed_limits(bio, &q->limits))) {
++                      bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
++                      if (!bio)
++                              return;
++              }
+               if (!bio_integrity_prep(bio))
+                       return;
+               if (blk_mq_attempt_bio_merge(q, bio, nr_segs))
+@@ -2992,6 +2991,11 @@ void blk_mq_submit_bio(struct bio *bio)
+       } else {
+               if (unlikely(bio_queue_enter(bio)))
+                       return;
++              if (unlikely(bio_may_exceed_limits(bio, &q->limits))) {
++                      bio = __bio_split_to_limits(bio, &q->limits, &nr_segs);
++                      if (!bio)
++                              goto fail;
++              }
+               if (!bio_integrity_prep(bio))
+                       goto fail;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/bpf-avoid-iter-offset-making-backward-progress-in-bp.patch b/queue-6.6/bpf-avoid-iter-offset-making-backward-progress-in-bp.patch
new file mode 100644 (file)
index 0000000..56c46c5
--- /dev/null
@@ -0,0 +1,113 @@
+From b1ee3348863a4397ba2dad97e2a42ef7ce38ea39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 11:05:29 -0800
+Subject: bpf: Avoid iter->offset making backward progress in bpf_iter_udp
+
+From: Martin KaFai Lau <martin.lau@kernel.org>
+
+[ Upstream commit 2242fd537fab52d5f4d2fbb1845f047c01fad0cf ]
+
+There is a bug in the bpf_iter_udp_batch() function that stops
+the userspace from making forward progress.
+
+The case that triggers the bug is the userspace passed in
+a very small read buffer. When the bpf prog does bpf_seq_printf,
+the userspace read buffer is not enough to capture the whole bucket.
+
+When the read buffer is not large enough, the kernel will remember
+the offset of the bucket in iter->offset such that the next userspace
+read() can continue from where it left off.
+
+The kernel will skip the number (== "iter->offset") of sockets in
+the next read(). However, the code directly decrements the
+"--iter->offset". This is incorrect because the next read() may
+not consume the whole bucket either and then the next-next read()
+will start from offset 0. The net effect is the userspace will
+keep reading from the beginning of a bucket and the process will
+never finish. "iter->offset" must always go forward until the
+whole bucket is consumed.
+
+This patch fixes it by using a local variable "resume_offset"
+and "resume_bucket". "iter->offset" is always reset to 0 before
+it may be used. "iter->offset" will be advanced to the
+"resume_offset" when it continues from the "resume_bucket" (i.e.
+"state->bucket == resume_bucket"). This brings it closer to
+the bpf_iter_tcp's offset handling which does not suffer
+the same bug.
+
+Cc: Aditi Ghag <aditi.ghag@isovalent.com>
+Fixes: c96dac8d369f ("bpf: udp: Implement batching for sockets iterator")
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Reviewed-by: Aditi Ghag <aditi.ghag@isovalent.com>
+Link: https://lore.kernel.org/r/20240112190530.3751661-3-martin.lau@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 21 ++++++++++-----------
+ 1 file changed, 10 insertions(+), 11 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index a4857c85a020..9cb22a6ae1dc 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -3116,16 +3116,18 @@ static struct sock *bpf_iter_udp_batch(struct seq_file *seq)
+       struct bpf_udp_iter_state *iter = seq->private;
+       struct udp_iter_state *state = &iter->state;
+       struct net *net = seq_file_net(seq);
++      int resume_bucket, resume_offset;
+       struct udp_table *udptable;
+       unsigned int batch_sks = 0;
+       bool resized = false;
+       struct sock *sk;
++      resume_bucket = state->bucket;
++      resume_offset = iter->offset;
++
+       /* The current batch is done, so advance the bucket. */
+-      if (iter->st_bucket_done) {
++      if (iter->st_bucket_done)
+               state->bucket++;
+-              iter->offset = 0;
+-      }
+       udptable = udp_get_table_seq(seq, net);
+@@ -3145,19 +3147,19 @@ static struct sock *bpf_iter_udp_batch(struct seq_file *seq)
+       for (; state->bucket <= udptable->mask; state->bucket++) {
+               struct udp_hslot *hslot2 = &udptable->hash2[state->bucket];
+-              if (hlist_empty(&hslot2->head)) {
+-                      iter->offset = 0;
++              if (hlist_empty(&hslot2->head))
+                       continue;
+-              }
++              iter->offset = 0;
+               spin_lock_bh(&hslot2->lock);
+               udp_portaddr_for_each_entry(sk, &hslot2->head) {
+                       if (seq_sk_match(seq, sk)) {
+                               /* Resume from the last iterated socket at the
+                                * offset in the bucket before iterator was stopped.
+                                */
+-                              if (iter->offset) {
+-                                      --iter->offset;
++                              if (state->bucket == resume_bucket &&
++                                  iter->offset < resume_offset) {
++                                      ++iter->offset;
+                                       continue;
+                               }
+                               if (iter->end_sk < iter->max_sk) {
+@@ -3171,9 +3173,6 @@ static struct sock *bpf_iter_udp_batch(struct seq_file *seq)
+               if (iter->end_sk)
+                       break;
+-
+-              /* Reset the current bucket's offset before moving to the next bucket. */
+-              iter->offset = 0;
+       }
+       /* All done: no batch made. */
+-- 
+2.43.0
+
diff --git a/queue-6.6/bpf-iter_udp-retry-with-a-larger-batch-size-without-.patch b/queue-6.6/bpf-iter_udp-retry-with-a-larger-batch-size-without-.patch
new file mode 100644 (file)
index 0000000..96c00ec
--- /dev/null
@@ -0,0 +1,49 @@
+From 4b940ddabc120aaeb3ad43b3aec97ea9c5c9c68e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 11:05:28 -0800
+Subject: bpf: iter_udp: Retry with a larger batch size without going back to
+ the previous bucket
+
+From: Martin KaFai Lau <martin.lau@kernel.org>
+
+[ Upstream commit 19ca0823f6eaad01d18f664a00550abe912c034c ]
+
+The current logic is to use a default size 16 to batch the whole bucket.
+If it is too small, it will retry with a larger batch size.
+
+The current code accidentally does a state->bucket-- before retrying.
+This goes back to retry with the previous bucket which has already
+been done. This patch fixed it.
+
+It is hard to create a selftest. I added a WARN_ON(state->bucket < 0),
+forced a particular port to be hashed to the first bucket,
+created >16 sockets, and observed the for-loop went back
+to the "-1" bucket.
+
+Cc: Aditi Ghag <aditi.ghag@isovalent.com>
+Fixes: c96dac8d369f ("bpf: udp: Implement batching for sockets iterator")
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
+Reviewed-by: Aditi Ghag <aditi.ghag@isovalent.com>
+Link: https://lore.kernel.org/r/20240112190530.3751661-2-martin.lau@linux.dev
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index bd12a7658213..a4857c85a020 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -3192,7 +3192,6 @@ static struct sock *bpf_iter_udp_batch(struct seq_file *seq)
+               /* After allocating a larger batch, retry one more time to grab
+                * the whole bucket.
+                */
+-              state->bucket--;
+               goto again;
+       }
+ done:
+-- 
+2.43.0
+
diff --git a/queue-6.6/bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch b/queue-6.6/bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch
new file mode 100644 (file)
index 0000000..9c69905
--- /dev/null
@@ -0,0 +1,88 @@
+From 85b724fb05b0f9f7d65a649b0ddf348f91bd1d42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 09:20:27 +0100
+Subject: bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS
+
+From: Hao Sun <sunhao.th@gmail.com>
+
+[ Upstream commit 22c7fa171a02d310e3a3f6ed46a698ca8a0060ed ]
+
+For PTR_TO_FLOW_KEYS, check_flow_keys_access() only uses fixed off
+for validation. However, variable offset ptr alu is not prohibited
+for this ptr kind. So the variable offset is not checked.
+
+The following prog is accepted:
+
+  func#0 @0
+  0: R1=ctx() R10=fp0
+  0: (bf) r6 = r1                       ; R1=ctx() R6_w=ctx()
+  1: (79) r7 = *(u64 *)(r6 +144)        ; R6_w=ctx() R7_w=flow_keys()
+  2: (b7) r8 = 1024                     ; R8_w=1024
+  3: (37) r8 /= 1                       ; R8_w=scalar()
+  4: (57) r8 &= 1024                    ; R8_w=scalar(smin=smin32=0,
+  smax=umax=smax32=umax32=1024,var_off=(0x0; 0x400))
+  5: (0f) r7 += r8
+  mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
+  mark_precise: frame0: regs=r8 stack= before 4: (57) r8 &= 1024
+  mark_precise: frame0: regs=r8 stack= before 3: (37) r8 /= 1
+  mark_precise: frame0: regs=r8 stack= before 2: (b7) r8 = 1024
+  6: R7_w=flow_keys(smin=smin32=0,smax=umax=smax32=umax32=1024,var_off
+  =(0x0; 0x400)) R8_w=scalar(smin=smin32=0,smax=umax=smax32=umax32=1024,
+  var_off=(0x0; 0x400))
+  6: (79) r0 = *(u64 *)(r7 +0)          ; R0_w=scalar()
+  7: (95) exit
+
+This prog loads flow_keys to r7, and adds the variable offset r8
+to r7, and finally causes out-of-bounds access:
+
+  BUG: unable to handle page fault for address: ffffc90014c80038
+  [...]
+  Call Trace:
+   <TASK>
+   bpf_dispatcher_nop_func include/linux/bpf.h:1231 [inline]
+   __bpf_prog_run include/linux/filter.h:651 [inline]
+   bpf_prog_run include/linux/filter.h:658 [inline]
+   bpf_prog_run_pin_on_cpu include/linux/filter.h:675 [inline]
+   bpf_flow_dissect+0x15f/0x350 net/core/flow_dissector.c:991
+   bpf_prog_test_run_flow_dissector+0x39d/0x620 net/bpf/test_run.c:1359
+   bpf_prog_test_run kernel/bpf/syscall.c:4107 [inline]
+   __sys_bpf+0xf8f/0x4560 kernel/bpf/syscall.c:5475
+   __do_sys_bpf kernel/bpf/syscall.c:5561 [inline]
+   __se_sys_bpf kernel/bpf/syscall.c:5559 [inline]
+   __x64_sys_bpf+0x73/0xb0 kernel/bpf/syscall.c:5559
+   do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+   do_syscall_64+0x3f/0x110 arch/x86/entry/common.c:83
+   entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Fix this by rejecting ptr alu with variable offset on flow_keys.
+Applying the patch rejects the program with "R7 pointer arithmetic
+on flow_keys prohibited".
+
+Fixes: d58e468b1112 ("flow_dissector: implements flow dissector BPF hook")
+Signed-off-by: Hao Sun <sunhao.th@gmail.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Yonghong Song <yonghong.song@linux.dev>
+Link: https://lore.kernel.org/bpf/20240115082028.9992-1-sunhao.th@gmail.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/bpf/verifier.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index ed24ad2e5bd2..97fd1766818b 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -12087,6 +12087,10 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+       }
+       switch (base_type(ptr_reg->type)) {
++      case PTR_TO_FLOW_KEYS:
++              if (known)
++                      break;
++              fallthrough;
+       case CONST_PTR_TO_MAP:
+               /* smin_val represents the known value */
+               if (known && smin_val == 0 && opcode == BPF_ADD)
+-- 
+2.43.0
+
diff --git a/queue-6.6/bus-mhi-ep-do-not-allocate-event-ring-element-on-sta.patch b/queue-6.6/bus-mhi-ep-do-not-allocate-event-ring-element-on-sta.patch
new file mode 100644 (file)
index 0000000..06b820c
--- /dev/null
@@ -0,0 +1,126 @@
+From a03c5e784fba33a3308a230357d65e06e200faa3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Sep 2023 13:05:02 +0530
+Subject: bus: mhi: ep: Do not allocate event ring element on stack
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 987fdb5a43a66764808371b54e6047834170d565 ]
+
+It is possible that the host controller driver would use DMA framework to
+write the event ring element. So avoid allocating event ring element on the
+stack as DMA cannot work on vmalloc memory.
+
+Cc: stable@vger.kernel.org
+Fixes: 961aeb689224 ("bus: mhi: ep: Add support for sending events to the host")
+Link: https://lore.kernel.org/r/20230901073502.69385-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Stable-dep-of: 327ec5f70609 ("PCI: epf-mhi: Fix the DMA data direction of dma_unmap_single()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/ep/main.c | 68 ++++++++++++++++++++++++++++-----------
+ 1 file changed, 50 insertions(+), 18 deletions(-)
+
+diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
+index 600881808982..e2513f5f47a6 100644
+--- a/drivers/bus/mhi/ep/main.c
++++ b/drivers/bus/mhi/ep/main.c
+@@ -71,45 +71,77 @@ static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx,
+ static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring,
+                                       struct mhi_ring_element *tre, u32 len, enum mhi_ev_ccs code)
+ {
+-      struct mhi_ring_element event = {};
++      struct mhi_ring_element *event;
++      int ret;
++
++      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      if (!event)
++              return -ENOMEM;
+-      event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre));
+-      event.dword[0] = MHI_TRE_EV_DWORD0(code, len);
+-      event.dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT);
++      event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre));
++      event->dword[0] = MHI_TRE_EV_DWORD0(code, len);
++      event->dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT);
+-      return mhi_ep_send_event(mhi_cntrl, ring->er_index, &event, MHI_TRE_DATA_GET_BEI(tre));
++      ret = mhi_ep_send_event(mhi_cntrl, ring->er_index, event, MHI_TRE_DATA_GET_BEI(tre));
++      kfree(event);
++
++      return ret;
+ }
+ int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state)
+ {
+-      struct mhi_ring_element event = {};
++      struct mhi_ring_element *event;
++      int ret;
++
++      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      if (!event)
++              return -ENOMEM;
+-      event.dword[0] = MHI_SC_EV_DWORD0(state);
+-      event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT);
++      event->dword[0] = MHI_SC_EV_DWORD0(state);
++      event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT);
+-      return mhi_ep_send_event(mhi_cntrl, 0, &event, 0);
++      ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
++      kfree(event);
++
++      return ret;
+ }
+ int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env)
+ {
+-      struct mhi_ring_element event = {};
++      struct mhi_ring_element *event;
++      int ret;
++
++      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      if (!event)
++              return -ENOMEM;
+-      event.dword[0] = MHI_EE_EV_DWORD0(exec_env);
+-      event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT);
++      event->dword[0] = MHI_EE_EV_DWORD0(exec_env);
++      event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT);
+-      return mhi_ep_send_event(mhi_cntrl, 0, &event, 0);
++      ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
++      kfree(event);
++
++      return ret;
+ }
+ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code)
+ {
+       struct mhi_ep_ring *ring = &mhi_cntrl->mhi_cmd->ring;
+-      struct mhi_ring_element event = {};
++      struct mhi_ring_element *event;
++      int ret;
++
++      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      if (!event)
++              return -ENOMEM;
+-      event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element));
+-      event.dword[0] = MHI_CC_EV_DWORD0(code);
+-      event.dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT);
++      event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element));
++      event->dword[0] = MHI_CC_EV_DWORD0(code);
++      event->dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT);
+-      return mhi_ep_send_event(mhi_cntrl, 0, &event, 0);
++      ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
++      kfree(event);
++
++      return ret;
+ }
+ static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_element *el)
+-- 
+2.43.0
+
diff --git a/queue-6.6/bus-mhi-ep-pass-mhi_ep_buf_info-struct-to-read-write.patch b/queue-6.6/bus-mhi-ep-pass-mhi_ep_buf_info-struct-to-read-write.patch
new file mode 100644 (file)
index 0000000..77628a6
--- /dev/null
@@ -0,0 +1,406 @@
+From f4ebd803dfbf104663d094d56f20f759f7a159ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 17 Aug 2023 23:24:52 +0530
+Subject: bus: mhi: ep: Pass mhi_ep_buf_info struct to read/write APIs
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit b08ded2ef2e98768d5ee5f71da8fe768b1f7774b ]
+
+In the preparation of DMA async support, let's pass the parameters to
+read_from_host() and write_to_host() APIs using mhi_ep_buf_info structure.
+
+No functional change.
+
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Stable-dep-of: 327ec5f70609 ("PCI: epf-mhi: Fix the DMA data direction of dma_unmap_single()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/ep/main.c                    | 23 +++----
+ drivers/bus/mhi/ep/ring.c                    | 41 ++++++------
+ drivers/pci/endpoint/functions/pci-epf-mhi.c | 66 +++++++++++---------
+ include/linux/mhi_ep.h                       | 16 ++++-
+ 4 files changed, 84 insertions(+), 62 deletions(-)
+
+diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
+index 517279600645..582d5c166a75 100644
+--- a/drivers/bus/mhi/ep/main.c
++++ b/drivers/bus/mhi/ep/main.c
+@@ -324,10 +324,9 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl,
+       struct mhi_ep_chan *mhi_chan = &mhi_cntrl->mhi_chan[ring->ch_id];
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
+       size_t tr_len, read_offset, write_offset;
++      struct mhi_ep_buf_info buf_info = {};
+       struct mhi_ring_element *el;
+       bool tr_done = false;
+-      void *write_addr;
+-      u64 read_addr;
+       u32 buf_left;
+       int ret;
+@@ -356,11 +355,13 @@ static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl,
+               read_offset = mhi_chan->tre_size - mhi_chan->tre_bytes_left;
+               write_offset = len - buf_left;
+-              read_addr = mhi_chan->tre_loc + read_offset;
+-              write_addr = result->buf_addr + write_offset;
++
++              buf_info.host_addr = mhi_chan->tre_loc + read_offset;
++              buf_info.dev_addr = result->buf_addr + write_offset;
++              buf_info.size = tr_len;
+               dev_dbg(dev, "Reading %zd bytes from channel (%u)\n", tr_len, ring->ch_id);
+-              ret = mhi_cntrl->read_from_host(mhi_cntrl, read_addr, write_addr, tr_len);
++              ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info);
+               if (ret < 0) {
+                       dev_err(&mhi_chan->mhi_dev->dev, "Error reading from channel\n");
+                       return ret;
+@@ -483,12 +484,11 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
+       struct mhi_ep_cntrl *mhi_cntrl = mhi_dev->mhi_cntrl;
+       struct mhi_ep_chan *mhi_chan = mhi_dev->dl_chan;
+       struct device *dev = &mhi_chan->mhi_dev->dev;
++      struct mhi_ep_buf_info buf_info = {};
+       struct mhi_ring_element *el;
+       u32 buf_left, read_offset;
+       struct mhi_ep_ring *ring;
+       enum mhi_ev_ccs code;
+-      void *read_addr;
+-      u64 write_addr;
+       size_t tr_len;
+       u32 tre_len;
+       int ret;
+@@ -517,11 +517,13 @@ int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
+               tr_len = min(buf_left, tre_len);
+               read_offset = skb->len - buf_left;
+-              read_addr = skb->data + read_offset;
+-              write_addr = MHI_TRE_DATA_GET_PTR(el);
++
++              buf_info.dev_addr = skb->data + read_offset;
++              buf_info.host_addr = MHI_TRE_DATA_GET_PTR(el);
++              buf_info.size = tr_len;
+               dev_dbg(dev, "Writing %zd bytes to channel (%u)\n", tr_len, ring->ch_id);
+-              ret = mhi_cntrl->write_to_host(mhi_cntrl, read_addr, write_addr, tr_len);
++              ret = mhi_cntrl->write_to_host(mhi_cntrl, &buf_info);
+               if (ret < 0) {
+                       dev_err(dev, "Error writing to the channel\n");
+                       goto err_exit;
+@@ -1429,7 +1431,6 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
+               ret = -ENOMEM;
+               goto err_destroy_tre_buf_cache;
+       }
+-
+       INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker);
+       INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker);
+       INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker);
+diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c
+index 115518ec76a4..c673d7200b3e 100644
+--- a/drivers/bus/mhi/ep/ring.c
++++ b/drivers/bus/mhi/ep/ring.c
+@@ -30,7 +30,8 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
+ {
+       struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl;
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
+-      size_t start, copy_size;
++      struct mhi_ep_buf_info buf_info = {};
++      size_t start;
+       int ret;
+       /* Don't proceed in the case of event ring. This happens during mhi_ep_ring_start(). */
+@@ -43,30 +44,34 @@ static int __mhi_ep_cache_ring(struct mhi_ep_ring *ring, size_t end)
+       start = ring->wr_offset;
+       if (start < end) {
+-              copy_size = (end - start) * sizeof(struct mhi_ring_element);
+-              ret = mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase +
+-                                              (start * sizeof(struct mhi_ring_element)),
+-                                              &ring->ring_cache[start], copy_size);
++              buf_info.size = (end - start) * sizeof(struct mhi_ring_element);
++              buf_info.host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element));
++              buf_info.dev_addr = &ring->ring_cache[start];
++
++              ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info);
+               if (ret < 0)
+                       return ret;
+       } else {
+-              copy_size = (ring->ring_size - start) * sizeof(struct mhi_ring_element);
+-              ret = mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase +
+-                                              (start * sizeof(struct mhi_ring_element)),
+-                                              &ring->ring_cache[start], copy_size);
++              buf_info.size = (ring->ring_size - start) * sizeof(struct mhi_ring_element);
++              buf_info.host_addr = ring->rbase + (start * sizeof(struct mhi_ring_element));
++              buf_info.dev_addr = &ring->ring_cache[start];
++
++              ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info);
+               if (ret < 0)
+                       return ret;
+               if (end) {
+-                      ret = mhi_cntrl->read_from_host(mhi_cntrl, ring->rbase,
+-                                                      &ring->ring_cache[0],
+-                                                      end * sizeof(struct mhi_ring_element));
++                      buf_info.host_addr = ring->rbase;
++                      buf_info.dev_addr = &ring->ring_cache[0];
++                      buf_info.size = end * sizeof(struct mhi_ring_element);
++
++                      ret = mhi_cntrl->read_from_host(mhi_cntrl, &buf_info);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+-      dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, copy_size);
++      dev_dbg(dev, "Cached ring: start %zu end %zu size %zu\n", start, end, buf_info.size);
+       return 0;
+ }
+@@ -102,6 +107,7 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e
+ {
+       struct mhi_ep_cntrl *mhi_cntrl = ring->mhi_cntrl;
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
++      struct mhi_ep_buf_info buf_info = {};
+       size_t old_offset = 0;
+       u32 num_free_elem;
+       __le64 rp;
+@@ -133,12 +139,11 @@ int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *e
+       rp = cpu_to_le64(ring->rd_offset * sizeof(*el) + ring->rbase);
+       memcpy_toio((void __iomem *) &ring->ring_ctx->generic.rp, &rp, sizeof(u64));
+-      ret = mhi_cntrl->write_to_host(mhi_cntrl, el, ring->rbase + (old_offset * sizeof(*el)),
+-                                     sizeof(*el));
+-      if (ret < 0)
+-              return ret;
++      buf_info.host_addr = ring->rbase + (old_offset * sizeof(*el));
++      buf_info.dev_addr = el;
++      buf_info.size = sizeof(*el);
+-      return 0;
++      return mhi_cntrl->write_to_host(mhi_cntrl, &buf_info);
+ }
+ void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id)
+diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c
+index b7b9d3e21f97..ec5f4a38178b 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-mhi.c
++++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c
+@@ -209,28 +209,28 @@ static void pci_epf_mhi_raise_irq(struct mhi_ep_cntrl *mhi_cntrl, u32 vector)
+                         vector + 1);
+ }
+-static int pci_epf_mhi_iatu_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from,
+-                               void *to, size_t size)
++static int pci_epf_mhi_iatu_read(struct mhi_ep_cntrl *mhi_cntrl,
++                               struct mhi_ep_buf_info *buf_info)
+ {
+       struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl);
+-      size_t offset = get_align_offset(epf_mhi, from);
++      size_t offset = get_align_offset(epf_mhi, buf_info->host_addr);
+       void __iomem *tre_buf;
+       phys_addr_t tre_phys;
+       int ret;
+       mutex_lock(&epf_mhi->lock);
+-      ret = __pci_epf_mhi_alloc_map(mhi_cntrl, from, &tre_phys, &tre_buf,
+-                                    offset, size);
++      ret = __pci_epf_mhi_alloc_map(mhi_cntrl, buf_info->host_addr, &tre_phys,
++                                    &tre_buf, offset, buf_info->size);
+       if (ret) {
+               mutex_unlock(&epf_mhi->lock);
+               return ret;
+       }
+-      memcpy_fromio(to, tre_buf, size);
++      memcpy_fromio(buf_info->dev_addr, tre_buf, buf_info->size);
+-      __pci_epf_mhi_unmap_free(mhi_cntrl, from, tre_phys, tre_buf, offset,
+-                               size);
++      __pci_epf_mhi_unmap_free(mhi_cntrl, buf_info->host_addr, tre_phys,
++                               tre_buf, offset, buf_info->size);
+       mutex_unlock(&epf_mhi->lock);
+@@ -238,27 +238,27 @@ static int pci_epf_mhi_iatu_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from,
+ }
+ static int pci_epf_mhi_iatu_write(struct mhi_ep_cntrl *mhi_cntrl,
+-                                void *from, u64 to, size_t size)
++                                struct mhi_ep_buf_info *buf_info)
+ {
+       struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl);
+-      size_t offset = get_align_offset(epf_mhi, to);
++      size_t offset = get_align_offset(epf_mhi, buf_info->host_addr);
+       void __iomem *tre_buf;
+       phys_addr_t tre_phys;
+       int ret;
+       mutex_lock(&epf_mhi->lock);
+-      ret = __pci_epf_mhi_alloc_map(mhi_cntrl, to, &tre_phys, &tre_buf,
+-                                    offset, size);
++      ret = __pci_epf_mhi_alloc_map(mhi_cntrl, buf_info->host_addr, &tre_phys,
++                                    &tre_buf, offset, buf_info->size);
+       if (ret) {
+               mutex_unlock(&epf_mhi->lock);
+               return ret;
+       }
+-      memcpy_toio(tre_buf, from, size);
++      memcpy_toio(tre_buf, buf_info->dev_addr, buf_info->size);
+-      __pci_epf_mhi_unmap_free(mhi_cntrl, to, tre_phys, tre_buf, offset,
+-                               size);
++      __pci_epf_mhi_unmap_free(mhi_cntrl, buf_info->host_addr, tre_phys,
++                               tre_buf, offset, buf_info->size);
+       mutex_unlock(&epf_mhi->lock);
+@@ -270,8 +270,8 @@ static void pci_epf_mhi_dma_callback(void *param)
+       complete(param);
+ }
+-static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from,
+-                               void *to, size_t size)
++static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl,
++                               struct mhi_ep_buf_info *buf_info)
+ {
+       struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl);
+       struct device *dma_dev = epf_mhi->epf->epc->dev.parent;
+@@ -284,13 +284,13 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from,
+       dma_addr_t dst_addr;
+       int ret;
+-      if (size < SZ_4K)
+-              return pci_epf_mhi_iatu_read(mhi_cntrl, from, to, size);
++      if (buf_info->size < SZ_4K)
++              return pci_epf_mhi_iatu_read(mhi_cntrl, buf_info);
+       mutex_lock(&epf_mhi->lock);
+       config.direction = DMA_DEV_TO_MEM;
+-      config.src_addr = from;
++      config.src_addr = buf_info->host_addr;
+       ret = dmaengine_slave_config(chan, &config);
+       if (ret) {
+@@ -298,14 +298,16 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from,
+               goto err_unlock;
+       }
+-      dst_addr = dma_map_single(dma_dev, to, size, DMA_FROM_DEVICE);
++      dst_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size,
++                                DMA_FROM_DEVICE);
+       ret = dma_mapping_error(dma_dev, dst_addr);
+       if (ret) {
+               dev_err(dev, "Failed to map remote memory\n");
+               goto err_unlock;
+       }
+-      desc = dmaengine_prep_slave_single(chan, dst_addr, size, DMA_DEV_TO_MEM,
++      desc = dmaengine_prep_slave_single(chan, dst_addr, buf_info->size,
++                                         DMA_DEV_TO_MEM,
+                                          DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+       if (!desc) {
+               dev_err(dev, "Failed to prepare DMA\n");
+@@ -332,15 +334,15 @@ static int pci_epf_mhi_edma_read(struct mhi_ep_cntrl *mhi_cntrl, u64 from,
+       }
+ err_unmap:
+-      dma_unmap_single(dma_dev, dst_addr, size, DMA_FROM_DEVICE);
++      dma_unmap_single(dma_dev, dst_addr, buf_info->size, DMA_FROM_DEVICE);
+ err_unlock:
+       mutex_unlock(&epf_mhi->lock);
+       return ret;
+ }
+-static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from,
+-                                u64 to, size_t size)
++static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl,
++                                struct mhi_ep_buf_info *buf_info)
+ {
+       struct pci_epf_mhi *epf_mhi = to_epf_mhi(mhi_cntrl);
+       struct device *dma_dev = epf_mhi->epf->epc->dev.parent;
+@@ -353,13 +355,13 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from,
+       dma_addr_t src_addr;
+       int ret;
+-      if (size < SZ_4K)
+-              return pci_epf_mhi_iatu_write(mhi_cntrl, from, to, size);
++      if (buf_info->size < SZ_4K)
++              return pci_epf_mhi_iatu_write(mhi_cntrl, buf_info);
+       mutex_lock(&epf_mhi->lock);
+       config.direction = DMA_MEM_TO_DEV;
+-      config.dst_addr = to;
++      config.dst_addr = buf_info->host_addr;
+       ret = dmaengine_slave_config(chan, &config);
+       if (ret) {
+@@ -367,14 +369,16 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from,
+               goto err_unlock;
+       }
+-      src_addr = dma_map_single(dma_dev, from, size, DMA_TO_DEVICE);
++      src_addr = dma_map_single(dma_dev, buf_info->dev_addr, buf_info->size,
++                                DMA_TO_DEVICE);
+       ret = dma_mapping_error(dma_dev, src_addr);
+       if (ret) {
+               dev_err(dev, "Failed to map remote memory\n");
+               goto err_unlock;
+       }
+-      desc = dmaengine_prep_slave_single(chan, src_addr, size, DMA_MEM_TO_DEV,
++      desc = dmaengine_prep_slave_single(chan, src_addr, buf_info->size,
++                                         DMA_MEM_TO_DEV,
+                                          DMA_CTRL_ACK | DMA_PREP_INTERRUPT);
+       if (!desc) {
+               dev_err(dev, "Failed to prepare DMA\n");
+@@ -401,7 +405,7 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl, void *from,
+       }
+ err_unmap:
+-      dma_unmap_single(dma_dev, src_addr, size, DMA_FROM_DEVICE);
++      dma_unmap_single(dma_dev, src_addr, buf_info->size, DMA_FROM_DEVICE);
+ err_unlock:
+       mutex_unlock(&epf_mhi->lock);
+diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
+index ce85d42b685d..96f3a133540d 100644
+--- a/include/linux/mhi_ep.h
++++ b/include/linux/mhi_ep.h
+@@ -49,6 +49,18 @@ struct mhi_ep_db_info {
+       u32 status;
+ };
++/**
++ * struct mhi_ep_buf_info - MHI Endpoint transfer buffer info
++ * @dev_addr: Address of the buffer in endpoint
++ * @host_addr: Address of the bufffer in host
++ * @size: Size of the buffer
++ */
++struct mhi_ep_buf_info {
++      void *dev_addr;
++      u64 host_addr;
++      size_t size;
++};
++
+ /**
+  * struct mhi_ep_cntrl - MHI Endpoint controller structure
+  * @cntrl_dev: Pointer to the struct device of physical bus acting as the MHI
+@@ -137,8 +149,8 @@ struct mhi_ep_cntrl {
+                        void __iomem **virt, size_t size);
+       void (*unmap_free)(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_addr_t phys,
+                          void __iomem *virt, size_t size);
+-      int (*read_from_host)(struct mhi_ep_cntrl *mhi_cntrl, u64 from, void *to, size_t size);
+-      int (*write_to_host)(struct mhi_ep_cntrl *mhi_cntrl, void *from, u64 to, size_t size);
++      int (*read_from_host)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info);
++      int (*write_to_host)(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_buf_info *buf_info);
+       enum mhi_state mhi_state;
+-- 
+2.43.0
+
diff --git a/queue-6.6/bus-mhi-ep-use-slab-allocator-where-applicable.patch b/queue-6.6/bus-mhi-ep-use-slab-allocator-where-applicable.patch
new file mode 100644 (file)
index 0000000..6ee9e7b
--- /dev/null
@@ -0,0 +1,246 @@
+From af6be2b05a91bdb862ba11d5aa99b44e192664fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 18 Oct 2023 17:58:12 +0530
+Subject: bus: mhi: ep: Use slab allocator where applicable
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 62210a26cd4f8ad52683a71c0226dfe85de1144d ]
+
+Use slab allocator for allocating the memory for objects used frequently
+and are of fixed size. This reduces the overheard associated with
+kmalloc().
+
+Suggested-by: Alex Elder <elder@linaro.org>
+Link: https://lore.kernel.org/r/20231018122812.47261-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Stable-dep-of: 327ec5f70609 ("PCI: epf-mhi: Fix the DMA data direction of dma_unmap_single()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/bus/mhi/ep/main.c | 66 +++++++++++++++++++++++++++++----------
+ include/linux/mhi_ep.h    |  3 ++
+ 2 files changed, 52 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c
+index e2513f5f47a6..517279600645 100644
+--- a/drivers/bus/mhi/ep/main.c
++++ b/drivers/bus/mhi/ep/main.c
+@@ -74,7 +74,7 @@ static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct m
+       struct mhi_ring_element *event;
+       int ret;
+-      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+       if (!event)
+               return -ENOMEM;
+@@ -83,7 +83,7 @@ static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct m
+       event->dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT);
+       ret = mhi_ep_send_event(mhi_cntrl, ring->er_index, event, MHI_TRE_DATA_GET_BEI(tre));
+-      kfree(event);
++      kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event);
+       return ret;
+ }
+@@ -93,7 +93,7 @@ int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_stat
+       struct mhi_ring_element *event;
+       int ret;
+-      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+       if (!event)
+               return -ENOMEM;
+@@ -101,7 +101,7 @@ int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_stat
+       event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT);
+       ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
+-      kfree(event);
++      kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event);
+       return ret;
+ }
+@@ -111,7 +111,7 @@ int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_e
+       struct mhi_ring_element *event;
+       int ret;
+-      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+       if (!event)
+               return -ENOMEM;
+@@ -119,7 +119,7 @@ int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_e
+       event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT);
+       ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
+-      kfree(event);
++      kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event);
+       return ret;
+ }
+@@ -130,7 +130,7 @@ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_e
+       struct mhi_ring_element *event;
+       int ret;
+-      event = kzalloc(sizeof(struct mhi_ring_element), GFP_KERNEL);
++      event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA);
+       if (!event)
+               return -ENOMEM;
+@@ -139,7 +139,7 @@ static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_e
+       event->dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT);
+       ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0);
+-      kfree(event);
++      kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event);
+       return ret;
+ }
+@@ -451,7 +451,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem
+               mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result);
+       } else {
+               /* UL channel */
+-              result.buf_addr = kzalloc(len, GFP_KERNEL);
++              result.buf_addr = kmem_cache_zalloc(mhi_cntrl->tre_buf_cache, GFP_KERNEL | GFP_DMA);
+               if (!result.buf_addr)
+                       return -ENOMEM;
+@@ -459,7 +459,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem
+                       ret = mhi_ep_read_channel(mhi_cntrl, ring, &result, len);
+                       if (ret < 0) {
+                               dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n");
+-                              kfree(result.buf_addr);
++                              kmem_cache_free(mhi_cntrl->tre_buf_cache, result.buf_addr);
+                               return ret;
+                       }
+@@ -471,7 +471,7 @@ static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring, struct mhi_ring_elem
+                       /* Read until the ring becomes empty */
+               } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE));
+-              kfree(result.buf_addr);
++              kmem_cache_free(mhi_cntrl->tre_buf_cache, result.buf_addr);
+       }
+       return 0;
+@@ -780,14 +780,14 @@ static void mhi_ep_ch_ring_worker(struct work_struct *work)
+               if (ret) {
+                       dev_err(dev, "Error updating write offset for ring\n");
+                       mutex_unlock(&chan->lock);
+-                      kfree(itr);
++                      kmem_cache_free(mhi_cntrl->ring_item_cache, itr);
+                       continue;
+               }
+               /* Sanity check to make sure there are elements in the ring */
+               if (ring->rd_offset == ring->wr_offset) {
+                       mutex_unlock(&chan->lock);
+-                      kfree(itr);
++                      kmem_cache_free(mhi_cntrl->ring_item_cache, itr);
+                       continue;
+               }
+@@ -799,12 +799,12 @@ static void mhi_ep_ch_ring_worker(struct work_struct *work)
+                       dev_err(dev, "Error processing ring for channel (%u): %d\n",
+                               ring->ch_id, ret);
+                       mutex_unlock(&chan->lock);
+-                      kfree(itr);
++                      kmem_cache_free(mhi_cntrl->ring_item_cache, itr);
+                       continue;
+               }
+               mutex_unlock(&chan->lock);
+-              kfree(itr);
++              kmem_cache_free(mhi_cntrl->ring_item_cache, itr);
+       }
+ }
+@@ -860,7 +860,7 @@ static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, unsigned lon
+               u32 ch_id = ch_idx + i;
+               ring = &mhi_cntrl->mhi_chan[ch_id].ring;
+-              item = kzalloc(sizeof(*item), GFP_ATOMIC);
++              item = kmem_cache_zalloc(mhi_cntrl->ring_item_cache, GFP_ATOMIC);
+               if (!item)
+                       return;
+@@ -1407,6 +1407,29 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
+               goto err_free_ch;
+       }
++      mhi_cntrl->ev_ring_el_cache = kmem_cache_create("mhi_ep_event_ring_el",
++                                                      sizeof(struct mhi_ring_element), 0,
++                                                      SLAB_CACHE_DMA, NULL);
++      if (!mhi_cntrl->ev_ring_el_cache) {
++              ret = -ENOMEM;
++              goto err_free_cmd;
++      }
++
++      mhi_cntrl->tre_buf_cache = kmem_cache_create("mhi_ep_tre_buf", MHI_EP_DEFAULT_MTU, 0,
++                                                    SLAB_CACHE_DMA, NULL);
++      if (!mhi_cntrl->tre_buf_cache) {
++              ret = -ENOMEM;
++              goto err_destroy_ev_ring_el_cache;
++      }
++
++      mhi_cntrl->ring_item_cache = kmem_cache_create("mhi_ep_ring_item",
++                                                      sizeof(struct mhi_ep_ring_item), 0,
++                                                      0, NULL);
++      if (!mhi_cntrl->ev_ring_el_cache) {
++              ret = -ENOMEM;
++              goto err_destroy_tre_buf_cache;
++      }
++
+       INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker);
+       INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker);
+       INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker);
+@@ -1415,7 +1438,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
+       mhi_cntrl->wq = alloc_workqueue("mhi_ep_wq", 0, 0);
+       if (!mhi_cntrl->wq) {
+               ret = -ENOMEM;
+-              goto err_free_cmd;
++              goto err_destroy_ring_item_cache;
+       }
+       INIT_LIST_HEAD(&mhi_cntrl->st_transition_list);
+@@ -1474,6 +1497,12 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
+       ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index);
+ err_destroy_wq:
+       destroy_workqueue(mhi_cntrl->wq);
++err_destroy_ring_item_cache:
++      kmem_cache_destroy(mhi_cntrl->ring_item_cache);
++err_destroy_ev_ring_el_cache:
++      kmem_cache_destroy(mhi_cntrl->ev_ring_el_cache);
++err_destroy_tre_buf_cache:
++      kmem_cache_destroy(mhi_cntrl->tre_buf_cache);
+ err_free_cmd:
+       kfree(mhi_cntrl->mhi_cmd);
+ err_free_ch:
+@@ -1495,6 +1524,9 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl)
+       free_irq(mhi_cntrl->irq, mhi_cntrl);
++      kmem_cache_destroy(mhi_cntrl->tre_buf_cache);
++      kmem_cache_destroy(mhi_cntrl->ev_ring_el_cache);
++      kmem_cache_destroy(mhi_cntrl->ring_item_cache);
+       kfree(mhi_cntrl->mhi_cmd);
+       kfree(mhi_cntrl->mhi_chan);
+diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h
+index f198a8ac7ee7..ce85d42b685d 100644
+--- a/include/linux/mhi_ep.h
++++ b/include/linux/mhi_ep.h
+@@ -128,6 +128,9 @@ struct mhi_ep_cntrl {
+       struct work_struct reset_work;
+       struct work_struct cmd_ring_work;
+       struct work_struct ch_ring_work;
++      struct kmem_cache *ring_item_cache;
++      struct kmem_cache *ev_ring_el_cache;
++      struct kmem_cache *tre_buf_cache;
+       void (*raise_irq)(struct mhi_ep_cntrl *mhi_cntrl, u32 vector);
+       int (*alloc_map)(struct mhi_ep_cntrl *mhi_cntrl, u64 pci_addr, phys_addr_t *phys_ptr,
+-- 
+2.43.0
+
diff --git a/queue-6.6/cxl-port-fix-missing-target-list-lock.patch b/queue-6.6/cxl-port-fix-missing-target-list-lock.patch
new file mode 100644 (file)
index 0000000..172119c
--- /dev/null
@@ -0,0 +1,119 @@
+From 0fe5b3801a54f77adcb1ef9b8f59d4098b508c7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 21 Dec 2023 21:05:01 -0800
+Subject: cxl/port: Fix missing target list lock
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ Upstream commit 5459e186a5c9f412334321cff58d70dcb0e48a04 ]
+
+cxl_port_setup_targets() modifies the ->targets[] array of a switch
+decoder. target_list_show() expects to be able to emit a coherent
+snapshot of that array by "holding" ->target_lock for read. The
+target_lock is held for write during initialization of the ->targets[]
+array, but it is not held for write during cxl_port_setup_targets().
+
+The ->target_lock() predates the introduction of @cxl_region_rwsem. That
+semaphore protects changes to host-physical-address (HPA) decode which
+is precisely what writes to a switch decoder's target list affects.
+
+Replace ->target_lock with @cxl_region_rwsem.
+
+Now the side-effect of snapshotting a unstable view of a decoder's
+target list is likely benign so the Fixes: tag is presumptive.
+
+Fixes: 27b3f8d13830 ("cxl/region: Program target lists")
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/port.c | 22 +++++++---------------
+ drivers/cxl/cxl.h       |  2 --
+ 2 files changed, 7 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
+index 4081052bb385..c67cc8c9d5cc 100644
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -172,14 +172,10 @@ static ssize_t target_list_show(struct device *dev,
+ {
+       struct cxl_switch_decoder *cxlsd = to_cxl_switch_decoder(dev);
+       ssize_t offset;
+-      unsigned int seq;
+       int rc;
+-      do {
+-              seq = read_seqbegin(&cxlsd->target_lock);
+-              rc = emit_target_list(cxlsd, buf);
+-      } while (read_seqretry(&cxlsd->target_lock, seq));
+-
++      guard(rwsem_read)(&cxl_region_rwsem);
++      rc = emit_target_list(cxlsd, buf);
+       if (rc < 0)
+               return rc;
+       offset = rc;
+@@ -1579,7 +1575,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, CXL);
+ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd,
+                                   struct cxl_port *port, int *target_map)
+ {
+-      int i, rc = 0;
++      int i;
+       if (!target_map)
+               return 0;
+@@ -1589,19 +1585,16 @@ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd,
+       if (xa_empty(&port->dports))
+               return -EINVAL;
+-      write_seqlock(&cxlsd->target_lock);
++      guard(rwsem_write)(&cxl_region_rwsem);
+       for (i = 0; i < cxlsd->cxld.interleave_ways; i++) {
+               struct cxl_dport *dport = find_dport(port, target_map[i]);
+-              if (!dport) {
+-                      rc = -ENXIO;
+-                      break;
+-              }
++              if (!dport)
++                      return -ENXIO;
+               cxlsd->target[i] = dport;
+       }
+-      write_sequnlock(&cxlsd->target_lock);
+-      return rc;
++      return 0;
+ }
+ struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos)
+@@ -1671,7 +1664,6 @@ static int cxl_switch_decoder_init(struct cxl_port *port,
+               return -EINVAL;
+       cxlsd->nr_targets = nr_targets;
+-      seqlock_init(&cxlsd->target_lock);
+       return cxl_decoder_init(port, &cxlsd->cxld);
+ }
+diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
+index 6c6afda0e4c6..de2c250c894b 100644
+--- a/drivers/cxl/cxl.h
++++ b/drivers/cxl/cxl.h
+@@ -404,7 +404,6 @@ struct cxl_endpoint_decoder {
+ /**
+  * struct cxl_switch_decoder - Switch specific CXL HDM Decoder
+  * @cxld: base cxl_decoder object
+- * @target_lock: coordinate coherent reads of the target list
+  * @nr_targets: number of elements in @target
+  * @target: active ordered target list in current decoder configuration
+  *
+@@ -416,7 +415,6 @@ struct cxl_endpoint_decoder {
+  */
+ struct cxl_switch_decoder {
+       struct cxl_decoder cxld;
+-      seqlock_t target_lock;
+       int nr_targets;
+       struct cxl_dport *target[];
+ };
+-- 
+2.43.0
+
diff --git a/queue-6.6/cxl-region-fix-x9-interleave-typo.patch b/queue-6.6/cxl-region-fix-x9-interleave-typo.patch
new file mode 100644 (file)
index 0000000..e579866
--- /dev/null
@@ -0,0 +1,38 @@
+From fd531419dea7e79c7e00b7a84d04d6c6d71b6d16 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Nov 2023 20:18:34 +0000
+Subject: cxl/region: fix x9 interleave typo
+
+From: Jim Harris <jim.harris@samsung.com>
+
+[ Upstream commit c7ad3dc3649730af483ee1e78be5d0362da25bfe ]
+
+CXL supports x3, x6 and x12 - not x9.
+
+Fixes: 80d10a6cee050 ("cxl/region: Add interleave geometry attributes")
+Signed-off-by: Jim Harris <jim.harris@samsung.com>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Fan Ni <fan.ni@samsung.com>
+Link: https://lore.kernel.org/r/169904271254.204936.8580772404462743630.stgit@ubuntu
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/cxl/core/region.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c
+index e7206367ec66..472bd510b5e2 100644
+--- a/drivers/cxl/core/region.c
++++ b/drivers/cxl/core/region.c
+@@ -397,7 +397,7 @@ static ssize_t interleave_ways_store(struct device *dev,
+               return rc;
+       /*
+-       * Even for x3, x9, and x12 interleaves the region interleave must be a
++       * Even for x3, x6, and x12 interleaves the region interleave must be a
+        * power of 2 multiple of the host bridge interleave.
+        */
+       if (!is_power_of_2(val / cxld->interleave_ways) ||
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-amdgpu-fall-back-to-input-power-for-avg-power-vi.patch b/queue-6.6/drm-amdgpu-fall-back-to-input-power-for-avg-power-vi.patch
new file mode 100644 (file)
index 0000000..7f419ca
--- /dev/null
@@ -0,0 +1,41 @@
+From f0948588a338d981b06ab52779e062cbcbf2ddc3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 2 Oct 2023 14:43:06 -0400
+Subject: drm/amdgpu: fall back to INPUT power for AVG power via INFO IOCTL
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit d02069850fc102b07ae923535d5e212f2c8a34e9 ]
+
+For backwards compatibility with userspace.
+
+Fixes: 47f1724db4fe ("drm/amd: Introduce `AMDGPU_PP_SENSOR_GPU_INPUT_POWER`")
+Link: https://gitlab.freedesktop.org/drm/amd/-/issues/2897
+Reviewed-by: Yang Wang <kevinyang.wang@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index d30dc0b718c7..58dab4f73a9a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -1026,7 +1026,12 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
+                       if (amdgpu_dpm_read_sensor(adev,
+                                                  AMDGPU_PP_SENSOR_GPU_AVG_POWER,
+                                                  (void *)&ui32, &ui32_size)) {
+-                              return -EINVAL;
++                              /* fall back to input power for backwards compat */
++                              if (amdgpu_dpm_read_sensor(adev,
++                                                         AMDGPU_PP_SENSOR_GPU_INPUT_POWER,
++                                                         (void *)&ui32, &ui32_size)) {
++                                      return -EINVAL;
++                              }
+                       }
+                       ui32 >>= 8;
+                       break;
+-- 
+2.43.0
+
diff --git a/queue-6.6/drm-amdkfd-fixes-for-hmm-mem-allocation.patch b/queue-6.6/drm-amdkfd-fixes-for-hmm-mem-allocation.patch
new file mode 100644 (file)
index 0000000..95654cd
--- /dev/null
@@ -0,0 +1,50 @@
+From 65c8c6f3f8c4b9b5109aa1f2981eb56ed82e4fde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Jan 2024 15:07:00 +0200
+Subject: drm/amdkfd: fixes for HMM mem allocation
+
+From: Dafna Hirschfeld <dhirschfeld@habana.ai>
+
+[ Upstream commit 02eed83abc1395a1207591aafad9bcfc5cb1abcb ]
+
+Fix err return value and reset pgmap->type after checking it.
+
+Fixes: c83dee9b6394 ("drm/amdkfd: add SPM support for SVM")
+Reviewed-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Dafna Hirschfeld <dhirschfeld@habana.ai>
+Signed-off-by: Felix Kuehling <felix.kuehling@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_migrate.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+index 7d82c7da223a..659313648b20 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c
+@@ -1021,7 +1021,7 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
+       } else {
+               res = devm_request_free_mem_region(adev->dev, &iomem_resource, size);
+               if (IS_ERR(res))
+-                      return -ENOMEM;
++                      return PTR_ERR(res);
+               pgmap->range.start = res->start;
+               pgmap->range.end = res->end;
+               pgmap->type = MEMORY_DEVICE_PRIVATE;
+@@ -1037,10 +1037,10 @@ int kgd2kfd_init_zone_device(struct amdgpu_device *adev)
+       r = devm_memremap_pages(adev->dev, pgmap);
+       if (IS_ERR(r)) {
+               pr_err("failed to register HMM device memory\n");
+-              /* Disable SVM support capability */
+-              pgmap->type = 0;
+               if (pgmap->type == MEMORY_DEVICE_PRIVATE)
+                       devm_release_mem_region(adev->dev, res->start, resource_size(res));
++              /* Disable SVM support capability */
++              pgmap->type = 0;
+               return PTR_ERR(r);
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/dt-bindings-gpio-xilinx-fix-node-address-in-gpio.patch b/queue-6.6/dt-bindings-gpio-xilinx-fix-node-address-in-gpio.patch
new file mode 100644 (file)
index 0000000..8d5cbb1
--- /dev/null
@@ -0,0 +1,36 @@
+From c0353669a03cb76f542df3b9c9f18d4d3fc1781d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 12:32:58 +0100
+Subject: dt-bindings: gpio: xilinx: Fix node address in gpio
+
+From: Michal Simek <michal.simek@amd.com>
+
+[ Upstream commit 314c020c4ed3de72b15603eb6892250bc4b51702 ]
+
+Node address doesn't match reg property which is not correct.
+
+Fixes: ba96b2e7974b ("dt-bindings: gpio: gpio-xilinx: Convert Xilinx axi gpio binding to YAML")
+Signed-off-by: Michal Simek <michal.simek@amd.com>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml
+index c1060e5fcef3..d3d8a2e143ed 100644
+--- a/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml
++++ b/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml
+@@ -126,7 +126,7 @@ examples:
+   - |
+     #include <dt-bindings/interrupt-controller/arm-gic.h>
+-        gpio@e000a000 {
++        gpio@a0020000 {
+             compatible = "xlnx,xps-gpio-1.00.a";
+             reg = <0xa0020000 0x10000>;
+             #gpio-cells = <2>;
+-- 
+2.43.0
+
diff --git a/queue-6.6/erofs-fix-inconsistent-per-file-compression-format.patch b/queue-6.6/erofs-fix-inconsistent-per-file-compression-format.patch
new file mode 100644 (file)
index 0000000..994c5d0
--- /dev/null
@@ -0,0 +1,94 @@
+From 32f68ad815efa0cbcaa26e43fceefb0e973b180e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 23:06:02 +0800
+Subject: erofs: fix inconsistent per-file compression format
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit 118a8cf504d7dfa519562d000f423ee3ca75d2c4 ]
+
+EROFS can select compression algorithms on a per-file basis, and each
+per-file compression algorithm needs to be marked in the on-disk
+superblock for initialization.
+
+However, syzkaller can generate inconsistent crafted images that use
+an unsupported algorithmtype for specific inodes, e.g. use MicroLZMA
+algorithmtype even it's not set in `sbi->available_compr_algs`.  This
+can lead to an unexpected "BUG: kernel NULL pointer dereference" if
+the corresponding decompressor isn't built-in.
+
+Fix this by checking against `sbi->available_compr_algs` for each
+m_algorithmformat request.  Incorrect !erofs_sb_has_compr_cfgs preset
+bitmap is now fixed together since it was harmless previously.
+
+Reported-by: <bugreport@ubisectech.com>
+Fixes: 8f89926290c4 ("erofs: get compression algorithms directly on mapping")
+Fixes: 622ceaddb764 ("erofs: lzma compression support")
+Reviewed-by: Yue Hu <huyue2@coolpad.com>
+Link: https://lore.kernel.org/r/20240113150602.1471050-1-hsiangkao@linux.alibaba.com
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/decompressor.c |  2 +-
+ fs/erofs/zmap.c         | 23 +++++++++++++----------
+ 2 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
+index e75edc8f1753..8d1f86487d6e 100644
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -399,7 +399,7 @@ int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb)
+       int size, ret = 0;
+       if (!erofs_sb_has_compr_cfgs(sbi)) {
+-              sbi->available_compr_algs = Z_EROFS_COMPRESSION_LZ4;
++              sbi->available_compr_algs = 1 << Z_EROFS_COMPRESSION_LZ4;
+               return z_erofs_load_lz4_config(sb, dsb, NULL, 0);
+       }
+diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c
+index 7b55111fd533..7a1a24ae4a2d 100644
+--- a/fs/erofs/zmap.c
++++ b/fs/erofs/zmap.c
+@@ -458,7 +458,7 @@ static int z_erofs_do_map_blocks(struct inode *inode,
+               .map = map,
+       };
+       int err = 0;
+-      unsigned int lclusterbits, endoff;
++      unsigned int lclusterbits, endoff, afmt;
+       unsigned long initial_lcn;
+       unsigned long long ofs, end;
+@@ -547,17 +547,20 @@ static int z_erofs_do_map_blocks(struct inode *inode,
+                       err = -EFSCORRUPTED;
+                       goto unmap_out;
+               }
+-              if (vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER)
+-                      map->m_algorithmformat =
+-                              Z_EROFS_COMPRESSION_INTERLACED;
+-              else
+-                      map->m_algorithmformat =
+-                              Z_EROFS_COMPRESSION_SHIFTED;
+-      } else if (m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) {
+-              map->m_algorithmformat = vi->z_algorithmtype[1];
++              afmt = vi->z_advise & Z_EROFS_ADVISE_INTERLACED_PCLUSTER ?
++                      Z_EROFS_COMPRESSION_INTERLACED :
++                      Z_EROFS_COMPRESSION_SHIFTED;
+       } else {
+-              map->m_algorithmformat = vi->z_algorithmtype[0];
++              afmt = m.headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2 ?
++                      vi->z_algorithmtype[1] : vi->z_algorithmtype[0];
++              if (!(EROFS_I_SB(inode)->available_compr_algs & (1 << afmt))) {
++                      erofs_err(inode->i_sb, "inconsistent algorithmtype %u for nid %llu",
++                                afmt, vi->nid);
++                      err = -EFSCORRUPTED;
++                      goto unmap_out;
++              }
+       }
++      map->m_algorithmformat = afmt;
+       if ((flags & EROFS_GET_BLOCKS_FIEMAP) ||
+           ((flags & EROFS_GET_BLOCKS_READMORE) &&
+-- 
+2.43.0
+
diff --git a/queue-6.6/erofs-simplify-compression-configuration-parser.patch b/queue-6.6/erofs-simplify-compression-configuration-parser.patch
new file mode 100644 (file)
index 0000000..83a88e4
--- /dev/null
@@ -0,0 +1,356 @@
+From cf581ab133b367e8654922d7150e5be30c0f1cf4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Oct 2023 21:09:57 +0800
+Subject: erofs: simplify compression configuration parser
+
+From: Gao Xiang <hsiangkao@linux.alibaba.com>
+
+[ Upstream commit efb4fb02cef3ab410b603c8f0e1c67f61d55f542 ]
+
+Move erofs_load_compr_cfgs() into decompressor.c as well as introduce
+a callback instead of a hard-coded switch for each algorithm for
+simplicity.
+
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Link: https://lore.kernel.org/r/20231022130957.11398-1-xiang@kernel.org
+Stable-dep-of: 118a8cf504d7 ("erofs: fix inconsistent per-file compression format")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/erofs/compress.h             |  6 +++
+ fs/erofs/decompressor.c         | 62 ++++++++++++++++++++++++++--
+ fs/erofs/decompressor_deflate.c |  5 ++-
+ fs/erofs/decompressor_lzma.c    |  4 +-
+ fs/erofs/internal.h             | 38 +----------------
+ fs/erofs/super.c                | 72 ++++-----------------------------
+ 6 files changed, 79 insertions(+), 108 deletions(-)
+
+diff --git a/fs/erofs/compress.h b/fs/erofs/compress.h
+index 349c3316ae6b..279933e007d2 100644
+--- a/fs/erofs/compress.h
++++ b/fs/erofs/compress.h
+@@ -21,6 +21,8 @@ struct z_erofs_decompress_req {
+ };
+ struct z_erofs_decompressor {
++      int (*config)(struct super_block *sb, struct erofs_super_block *dsb,
++                    void *data, int size);
+       int (*decompress)(struct z_erofs_decompress_req *rq,
+                         struct page **pagepool);
+       char *name;
+@@ -92,6 +94,10 @@ int z_erofs_fixup_insize(struct z_erofs_decompress_req *rq, const char *padbuf,
+ extern const struct z_erofs_decompressor erofs_decompressors[];
+ /* prototypes for specific algorithms */
++int z_erofs_load_lzma_config(struct super_block *sb,
++                      struct erofs_super_block *dsb, void *data, int size);
++int z_erofs_load_deflate_config(struct super_block *sb,
++                      struct erofs_super_block *dsb, void *data, int size);
+ int z_erofs_lzma_decompress(struct z_erofs_decompress_req *rq,
+                           struct page **pagepool);
+ int z_erofs_deflate_decompress(struct z_erofs_decompress_req *rq,
+diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
+index 332ec5f74002..e75edc8f1753 100644
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -24,11 +24,11 @@ struct z_erofs_lz4_decompress_ctx {
+       unsigned int oend;
+ };
+-int z_erofs_load_lz4_config(struct super_block *sb,
+-                          struct erofs_super_block *dsb,
+-                          struct z_erofs_lz4_cfgs *lz4, int size)
++static int z_erofs_load_lz4_config(struct super_block *sb,
++                          struct erofs_super_block *dsb, void *data, int size)
+ {
+       struct erofs_sb_info *sbi = EROFS_SB(sb);
++      struct z_erofs_lz4_cfgs *lz4 = data;
+       u16 distance;
+       if (lz4) {
+@@ -370,19 +370,75 @@ const struct z_erofs_decompressor erofs_decompressors[] = {
+               .name = "interlaced"
+       },
+       [Z_EROFS_COMPRESSION_LZ4] = {
++              .config = z_erofs_load_lz4_config,
+               .decompress = z_erofs_lz4_decompress,
+               .name = "lz4"
+       },
+ #ifdef CONFIG_EROFS_FS_ZIP_LZMA
+       [Z_EROFS_COMPRESSION_LZMA] = {
++              .config = z_erofs_load_lzma_config,
+               .decompress = z_erofs_lzma_decompress,
+               .name = "lzma"
+       },
+ #endif
+ #ifdef CONFIG_EROFS_FS_ZIP_DEFLATE
+       [Z_EROFS_COMPRESSION_DEFLATE] = {
++              .config = z_erofs_load_deflate_config,
+               .decompress = z_erofs_deflate_decompress,
+               .name = "deflate"
+       },
+ #endif
+ };
++
++int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb)
++{
++      struct erofs_sb_info *sbi = EROFS_SB(sb);
++      struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
++      unsigned int algs, alg;
++      erofs_off_t offset;
++      int size, ret = 0;
++
++      if (!erofs_sb_has_compr_cfgs(sbi)) {
++              sbi->available_compr_algs = Z_EROFS_COMPRESSION_LZ4;
++              return z_erofs_load_lz4_config(sb, dsb, NULL, 0);
++      }
++
++      sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
++      if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) {
++              erofs_err(sb, "unidentified algorithms %x, please upgrade kernel",
++                        sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS);
++              return -EOPNOTSUPP;
++      }
++
++      erofs_init_metabuf(&buf, sb);
++      offset = EROFS_SUPER_OFFSET + sbi->sb_size;
++      alg = 0;
++      for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
++              void *data;
++
++              if (!(algs & 1))
++                      continue;
++
++              data = erofs_read_metadata(sb, &buf, &offset, &size);
++              if (IS_ERR(data)) {
++                      ret = PTR_ERR(data);
++                      break;
++              }
++
++              if (alg >= ARRAY_SIZE(erofs_decompressors) ||
++                  !erofs_decompressors[alg].config) {
++                      erofs_err(sb, "algorithm %d isn't enabled on this kernel",
++                                alg);
++                      ret = -EOPNOTSUPP;
++              } else {
++                      ret = erofs_decompressors[alg].config(sb,
++                                      dsb, data, size);
++              }
++
++              kfree(data);
++              if (ret)
++                      break;
++      }
++      erofs_put_metabuf(&buf);
++      return ret;
++}
+diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c
+index 19e5bdeb30b6..0e1946a6bda5 100644
+--- a/fs/erofs/decompressor_deflate.c
++++ b/fs/erofs/decompressor_deflate.c
+@@ -77,9 +77,10 @@ int __init z_erofs_deflate_init(void)
+ }
+ int z_erofs_load_deflate_config(struct super_block *sb,
+-                              struct erofs_super_block *dsb,
+-                              struct z_erofs_deflate_cfgs *dfl, int size)
++                      struct erofs_super_block *dsb, void *data, int size)
+ {
++      struct z_erofs_deflate_cfgs *dfl = data;
++
+       if (!dfl || size < sizeof(struct z_erofs_deflate_cfgs)) {
+               erofs_err(sb, "invalid deflate cfgs, size=%u", size);
+               return -EINVAL;
+diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c
+index dee10d22ada9..ba4ec73f4aae 100644
+--- a/fs/erofs/decompressor_lzma.c
++++ b/fs/erofs/decompressor_lzma.c
+@@ -72,10 +72,10 @@ int __init z_erofs_lzma_init(void)
+ }
+ int z_erofs_load_lzma_config(struct super_block *sb,
+-                           struct erofs_super_block *dsb,
+-                           struct z_erofs_lzma_cfgs *lzma, int size)
++                      struct erofs_super_block *dsb, void *data, int size)
+ {
+       static DEFINE_MUTEX(lzma_resize_mutex);
++      struct z_erofs_lzma_cfgs *lzma = data;
+       unsigned int dict_size, i;
+       struct z_erofs_lzma *strm, *head = NULL;
+       int err;
+diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
+index 4ff88d0dd980..d8de61350dc0 100644
+--- a/fs/erofs/internal.h
++++ b/fs/erofs/internal.h
+@@ -469,9 +469,6 @@ int __init z_erofs_init_zip_subsystem(void);
+ void z_erofs_exit_zip_subsystem(void);
+ int erofs_try_to_free_all_cached_pages(struct erofs_sb_info *sbi,
+                                      struct erofs_workgroup *egrp);
+-int z_erofs_load_lz4_config(struct super_block *sb,
+-                          struct erofs_super_block *dsb,
+-                          struct z_erofs_lz4_cfgs *lz4, int len);
+ int z_erofs_map_blocks_iter(struct inode *inode, struct erofs_map_blocks *map,
+                           int flags);
+ void *erofs_get_pcpubuf(unsigned int requiredpages);
+@@ -480,6 +477,7 @@ int erofs_pcpubuf_growsize(unsigned int nrpages);
+ void __init erofs_pcpubuf_init(void);
+ void erofs_pcpubuf_exit(void);
+ int erofs_init_managed_cache(struct super_block *sb);
++int z_erofs_parse_cfgs(struct super_block *sb, struct erofs_super_block *dsb);
+ #else
+ static inline void erofs_shrinker_register(struct super_block *sb) {}
+ static inline void erofs_shrinker_unregister(struct super_block *sb) {}
+@@ -487,16 +485,6 @@ static inline int erofs_init_shrinker(void) { return 0; }
+ static inline void erofs_exit_shrinker(void) {}
+ static inline int z_erofs_init_zip_subsystem(void) { return 0; }
+ static inline void z_erofs_exit_zip_subsystem(void) {}
+-static inline int z_erofs_load_lz4_config(struct super_block *sb,
+-                                struct erofs_super_block *dsb,
+-                                struct z_erofs_lz4_cfgs *lz4, int len)
+-{
+-      if (lz4 || dsb->u1.lz4_max_distance) {
+-              erofs_err(sb, "lz4 algorithm isn't enabled");
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+ static inline void erofs_pcpubuf_init(void) {}
+ static inline void erofs_pcpubuf_exit(void) {}
+ static inline int erofs_init_managed_cache(struct super_block *sb) { return 0; }
+@@ -505,41 +493,17 @@ static inline int erofs_init_managed_cache(struct super_block *sb) { return 0; }
+ #ifdef CONFIG_EROFS_FS_ZIP_LZMA
+ int __init z_erofs_lzma_init(void);
+ void z_erofs_lzma_exit(void);
+-int z_erofs_load_lzma_config(struct super_block *sb,
+-                           struct erofs_super_block *dsb,
+-                           struct z_erofs_lzma_cfgs *lzma, int size);
+ #else
+ static inline int z_erofs_lzma_init(void) { return 0; }
+ static inline int z_erofs_lzma_exit(void) { return 0; }
+-static inline int z_erofs_load_lzma_config(struct super_block *sb,
+-                           struct erofs_super_block *dsb,
+-                           struct z_erofs_lzma_cfgs *lzma, int size) {
+-      if (lzma) {
+-              erofs_err(sb, "lzma algorithm isn't enabled");
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+ #endif        /* !CONFIG_EROFS_FS_ZIP_LZMA */
+ #ifdef CONFIG_EROFS_FS_ZIP_DEFLATE
+ int __init z_erofs_deflate_init(void);
+ void z_erofs_deflate_exit(void);
+-int z_erofs_load_deflate_config(struct super_block *sb,
+-                              struct erofs_super_block *dsb,
+-                              struct z_erofs_deflate_cfgs *dfl, int size);
+ #else
+ static inline int z_erofs_deflate_init(void) { return 0; }
+ static inline int z_erofs_deflate_exit(void) { return 0; }
+-static inline int z_erofs_load_deflate_config(struct super_block *sb,
+-                      struct erofs_super_block *dsb,
+-                      struct z_erofs_deflate_cfgs *dfl, int size) {
+-      if (dfl) {
+-              erofs_err(sb, "deflate algorithm isn't enabled");
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+ #endif        /* !CONFIG_EROFS_FS_ZIP_DEFLATE */
+ #ifdef CONFIG_EROFS_FS_ONDEMAND
+diff --git a/fs/erofs/super.c b/fs/erofs/super.c
+index 3700af9ee173..cc44fb2e001e 100644
+--- a/fs/erofs/super.c
++++ b/fs/erofs/super.c
+@@ -156,68 +156,15 @@ void *erofs_read_metadata(struct super_block *sb, struct erofs_buf *buf,
+       return buffer;
+ }
+-#ifdef CONFIG_EROFS_FS_ZIP
+-static int erofs_load_compr_cfgs(struct super_block *sb,
+-                               struct erofs_super_block *dsb)
++#ifndef CONFIG_EROFS_FS_ZIP
++static int z_erofs_parse_cfgs(struct super_block *sb,
++                            struct erofs_super_block *dsb)
+ {
+-      struct erofs_sb_info *sbi = EROFS_SB(sb);
+-      struct erofs_buf buf = __EROFS_BUF_INITIALIZER;
+-      unsigned int algs, alg;
+-      erofs_off_t offset;
+-      int size, ret = 0;
+-
+-      sbi->available_compr_algs = le16_to_cpu(dsb->u1.available_compr_algs);
+-      if (sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS) {
+-              erofs_err(sb, "try to load compressed fs with unsupported algorithms %x",
+-                        sbi->available_compr_algs & ~Z_EROFS_ALL_COMPR_ALGS);
+-              return -EINVAL;
+-      }
+-
+-      erofs_init_metabuf(&buf, sb);
+-      offset = EROFS_SUPER_OFFSET + sbi->sb_size;
+-      alg = 0;
+-      for (algs = sbi->available_compr_algs; algs; algs >>= 1, ++alg) {
+-              void *data;
+-
+-              if (!(algs & 1))
+-                      continue;
+-
+-              data = erofs_read_metadata(sb, &buf, &offset, &size);
+-              if (IS_ERR(data)) {
+-                      ret = PTR_ERR(data);
+-                      break;
+-              }
++      if (!dsb->u1.available_compr_algs)
++              return 0;
+-              switch (alg) {
+-              case Z_EROFS_COMPRESSION_LZ4:
+-                      ret = z_erofs_load_lz4_config(sb, dsb, data, size);
+-                      break;
+-              case Z_EROFS_COMPRESSION_LZMA:
+-                      ret = z_erofs_load_lzma_config(sb, dsb, data, size);
+-                      break;
+-              case Z_EROFS_COMPRESSION_DEFLATE:
+-                      ret = z_erofs_load_deflate_config(sb, dsb, data, size);
+-                      break;
+-              default:
+-                      DBG_BUGON(1);
+-                      ret = -EFAULT;
+-              }
+-              kfree(data);
+-              if (ret)
+-                      break;
+-      }
+-      erofs_put_metabuf(&buf);
+-      return ret;
+-}
+-#else
+-static int erofs_load_compr_cfgs(struct super_block *sb,
+-                               struct erofs_super_block *dsb)
+-{
+-      if (dsb->u1.available_compr_algs) {
+-              erofs_err(sb, "try to load compressed fs when compression is disabled");
+-              return -EINVAL;
+-      }
+-      return 0;
++      erofs_err(sb, "compression disabled, unable to mount compressed EROFS");
++      return -EOPNOTSUPP;
+ }
+ #endif
+@@ -406,10 +353,7 @@ static int erofs_read_superblock(struct super_block *sb)
+       }
+       /* parse on-disk compression configurations */
+-      if (erofs_sb_has_compr_cfgs(sbi))
+-              ret = erofs_load_compr_cfgs(sb, dsb);
+-      else
+-              ret = z_erofs_load_lz4_config(sb, dsb, NULL, 0);
++      ret = z_erofs_parse_cfgs(sb, dsb);
+       if (ret < 0)
+               goto out;
+-- 
+2.43.0
+
diff --git a/queue-6.6/ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch b/queue-6.6/ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch
new file mode 100644 (file)
index 0000000..e433543
--- /dev/null
@@ -0,0 +1,64 @@
+From 122eec6132c1578980003899119f58d92525c782 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 13:03:14 +0100
+Subject: ethtool: netlink: Add missing ethnl_ops_begin/complete
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ludvig Pärsson <ludvig.parsson@axis.com>
+
+[ Upstream commit f1172f3ee3a98754d95b968968920a7d03fdebcc ]
+
+Accessing an ethernet device that is powered off or clock gated might
+cause the CPU to hang. Add ethnl_ops_begin/complete in
+ethnl_set_features() to protect against this.
+
+Fixes: 0980bfcd6954 ("ethtool: set netdev features with FEATURES_SET request")
+Signed-off-by: Ludvig Pärsson <ludvig.parsson@axis.com>
+Link: https://lore.kernel.org/r/20240117-etht2-v2-1-1a96b6e8c650@axis.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/features.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/net/ethtool/features.c b/net/ethtool/features.c
+index a79af8c25a07..b6cb101d7f19 100644
+--- a/net/ethtool/features.c
++++ b/net/ethtool/features.c
+@@ -234,17 +234,20 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
+       dev = req_info.dev;
+       rtnl_lock();
++      ret = ethnl_ops_begin(dev);
++      if (ret < 0)
++              goto out_rtnl;
+       ethnl_features_to_bitmap(old_active, dev->features);
+       ethnl_features_to_bitmap(old_wanted, dev->wanted_features);
+       ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
+                                tb[ETHTOOL_A_FEATURES_WANTED],
+                                netdev_features_strings, info->extack);
+       if (ret < 0)
+-              goto out_rtnl;
++              goto out_ops;
+       if (ethnl_bitmap_to_features(req_mask) & ~NETIF_F_ETHTOOL_BITS) {
+               GENL_SET_ERR_MSG(info, "attempt to change non-ethtool features");
+               ret = -EINVAL;
+-              goto out_rtnl;
++              goto out_ops;
+       }
+       /* set req_wanted bits not in req_mask from old_wanted */
+@@ -281,6 +284,8 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
+       if (mod)
+               netdev_features_change(dev);
++out_ops:
++      ethnl_ops_complete(dev);
+ out_rtnl:
+       rtnl_unlock();
+       ethnl_parse_header_dev_put(&req_info);
+-- 
+2.43.0
+
diff --git a/queue-6.6/gpio-mlxbf3-add-an-error-code-check-in-mlxbf3_gpio_p.patch b/queue-6.6/gpio-mlxbf3-add-an-error-code-check-in-mlxbf3_gpio_p.patch
new file mode 100644 (file)
index 0000000..ca0664e
--- /dev/null
@@ -0,0 +1,38 @@
+From b1d12050ca5b61959bcba65ed0476cf494c7a191 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 12:24:04 +0800
+Subject: gpio: mlxbf3: add an error code check in mlxbf3_gpio_probe
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit d460e9c2075164e9b1fa9c4c95f8c05517bd8752 ]
+
+Clang static checker warning: Value stored to 'ret' is never read.
+bgpio_init() returns error code if failed, it's better to add this
+check.
+
+Fixes: cd33f216d241 ("gpio: mlxbf3: Add gpio driver support")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+[Bartosz: add the Fixes: tag]
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpio-mlxbf3.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpio/gpio-mlxbf3.c b/drivers/gpio/gpio-mlxbf3.c
+index 7a3e1760fc5b..d5906d419b0a 100644
+--- a/drivers/gpio/gpio-mlxbf3.c
++++ b/drivers/gpio/gpio-mlxbf3.c
+@@ -215,6 +215,8 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev)
+                       gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR,
+                       gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET,
+                       gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0);
++      if (ret)
++              return dev_err_probe(dev, ret, "%s: bgpio_init() failed", __func__);
+       gc->request = gpiochip_generic_request;
+       gc->free = gpiochip_generic_free;
+-- 
+2.43.0
+
diff --git a/queue-6.6/hisi_acc_vfio_pci-update-migration-data-pointer-corr.patch b/queue-6.6/hisi_acc_vfio_pci-update-migration-data-pointer-corr.patch
new file mode 100644 (file)
index 0000000..9c3a352
--- /dev/null
@@ -0,0 +1,70 @@
+From 836b647f3c82ebf4d078f0c20aa8e96d18be1349 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Nov 2023 09:14:06 +0000
+Subject: hisi_acc_vfio_pci: Update migration data pointer correctly on
+ saving/resume
+
+From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+
+[ Upstream commit be12ad45e15b5ee0e2526a50266ba1d295d26a88 ]
+
+When the optional PRE_COPY support was added to speed up the device
+compatibility check, it failed to update the saving/resuming data
+pointers based on the fd offset. This results in migration data
+corruption and when the device gets started on the destination the
+following error is reported in some cases,
+
+[  478.907684] arm-smmu-v3 arm-smmu-v3.2.auto: event 0x10 received:
+[  478.913691] arm-smmu-v3 arm-smmu-v3.2.auto:  0x0000310200000010
+[  478.919603] arm-smmu-v3 arm-smmu-v3.2.auto:  0x000002088000007f
+[  478.925515] arm-smmu-v3 arm-smmu-v3.2.auto:  0x0000000000000000
+[  478.931425] arm-smmu-v3 arm-smmu-v3.2.auto:  0x0000000000000000
+[  478.947552] hisi_zip 0000:31:00.0: qm_axi_rresp [error status=0x1] found
+[  478.955930] hisi_zip 0000:31:00.0: qm_db_timeout [error status=0x400] found
+[  478.955944] hisi_zip 0000:31:00.0: qm sq doorbell timeout in function 2
+
+Fixes: d9a871e4a143 ("hisi_acc_vfio_pci: Introduce support for PRE_COPY state transitions")
+Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Link: https://lore.kernel.org/r/20231120091406.780-1-shameerali.kolothum.thodi@huawei.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+index b2f9778c8366..4d27465c8f1a 100644
+--- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
++++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c
+@@ -694,6 +694,7 @@ static ssize_t hisi_acc_vf_resume_write(struct file *filp, const char __user *bu
+                                       size_t len, loff_t *pos)
+ {
+       struct hisi_acc_vf_migration_file *migf = filp->private_data;
++      u8 *vf_data = (u8 *)&migf->vf_data;
+       loff_t requested_length;
+       ssize_t done = 0;
+       int ret;
+@@ -715,7 +716,7 @@ static ssize_t hisi_acc_vf_resume_write(struct file *filp, const char __user *bu
+               goto out_unlock;
+       }
+-      ret = copy_from_user(&migf->vf_data, buf, len);
++      ret = copy_from_user(vf_data + *pos, buf, len);
+       if (ret) {
+               done = -EFAULT;
+               goto out_unlock;
+@@ -835,7 +836,9 @@ static ssize_t hisi_acc_vf_save_read(struct file *filp, char __user *buf, size_t
+       len = min_t(size_t, migf->total_length - *pos, len);
+       if (len) {
+-              ret = copy_to_user(buf, &migf->vf_data, len);
++              u8 *vf_data = (u8 *)&migf->vf_data;
++
++              ret = copy_to_user(buf, vf_data + *pos, len);
+               if (ret) {
+                       done = -EFAULT;
+                       goto out_unlock;
+-- 
+2.43.0
+
diff --git a/queue-6.6/i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch b/queue-6.6/i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch
new file mode 100644 (file)
index 0000000..646f4ed
--- /dev/null
@@ -0,0 +1,50 @@
+From a5c32b5d4c916f5b219b2ee2dddabae6e2c97e15 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 17:43:52 +0100
+Subject: i2c: s3c24xx: fix read transfers in polling mode
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit 0d9cf23ed55d7ba3ab26d617a3ae507863674c8f ]
+
+To properly handle read transfers in polling mode, no waiting for the ACK
+state is needed as it will never come. Just wait a bit to ensure start
+state is on the bus and continue processing next bytes.
+
+Fixes: 117053f77a5a ("i2c: s3c2410: Add polling mode support")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Chanho Park <chanho61.park@samsung.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-s3c2410.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+index 127eb3805fac..fdd7a4259d2c 100644
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -216,8 +216,17 @@ static bool is_ack(struct s3c24xx_i2c *i2c)
+       int tries;
+       for (tries = 50; tries; --tries) {
+-              if (readl(i2c->regs + S3C2410_IICCON)
+-                      & S3C2410_IICCON_IRQPEND) {
++              unsigned long tmp = readl(i2c->regs + S3C2410_IICCON);
++
++              if (!(tmp & S3C2410_IICCON_ACKEN)) {
++                      /*
++                       * Wait a bit for the bus to stabilize,
++                       * delay estimated experimentally.
++                       */
++                      usleep_range(100, 200);
++                      return true;
++              }
++              if (tmp & S3C2410_IICCON_IRQPEND) {
+                       if (!(readl(i2c->regs + S3C2410_IICSTAT)
+                               & S3C2410_IICSTAT_LASTBIT))
+                               return true;
+-- 
+2.43.0
+
diff --git a/queue-6.6/i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch b/queue-6.6/i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch
new file mode 100644 (file)
index 0000000..ef84ca5
--- /dev/null
@@ -0,0 +1,88 @@
+From 951be04e2959429a6c3785978d7da1ba1743e500 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 17:43:53 +0100
+Subject: i2c: s3c24xx: fix transferring more than one message in polling mode
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit 990489e1042c6c5d6bccf56deca68f8dbeed8180 ]
+
+To properly handle ACK on the bus when transferring more than one
+message in polling mode, move the polling handling loop from
+s3c24xx_i2c_message_start() to s3c24xx_i2c_doxfer(). This way
+i2c_s3c_irq_nextbyte() is always executed till the end, properly
+acknowledging the IRQ bits and no recursive calls to
+i2c_s3c_irq_nextbyte() are made.
+
+While touching this, also fix finishing transfers in polling mode by
+using common code path and always waiting for the bus to become idle
+and disabled.
+
+Fixes: 117053f77a5a ("i2c: s3c2410: Add polling mode support")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Reviewed-by: Andi Shyti <andi.shyti@kernel.org>
+Signed-off-by: Wolfram Sang <wsa@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i2c/busses/i2c-s3c2410.c | 27 ++++++++++-----------------
+ 1 file changed, 10 insertions(+), 17 deletions(-)
+
+diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
+index fdd7a4259d2c..c324cb3c97e2 100644
+--- a/drivers/i2c/busses/i2c-s3c2410.c
++++ b/drivers/i2c/busses/i2c-s3c2410.c
+@@ -279,16 +279,6 @@ static void s3c24xx_i2c_message_start(struct s3c24xx_i2c *i2c,
+       stat |= S3C2410_IICSTAT_START;
+       writel(stat, i2c->regs + S3C2410_IICSTAT);
+-
+-      if (i2c->quirks & QUIRK_POLL) {
+-              while ((i2c->msg_num != 0) && is_ack(i2c)) {
+-                      i2c_s3c_irq_nextbyte(i2c, stat);
+-                      stat = readl(i2c->regs + S3C2410_IICSTAT);
+-
+-                      if (stat & S3C2410_IICSTAT_ARBITR)
+-                              dev_err(i2c->dev, "deal with arbitration loss\n");
+-              }
+-      }
+ }
+ static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
+@@ -695,7 +685,7 @@ static void s3c24xx_i2c_wait_idle(struct s3c24xx_i2c *i2c)
+ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
+                             struct i2c_msg *msgs, int num)
+ {
+-      unsigned long timeout;
++      unsigned long timeout = 0;
+       int ret;
+       ret = s3c24xx_i2c_set_master(i2c);
+@@ -715,16 +705,19 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c,
+       s3c24xx_i2c_message_start(i2c, msgs);
+       if (i2c->quirks & QUIRK_POLL) {
+-              ret = i2c->msg_idx;
++              while ((i2c->msg_num != 0) && is_ack(i2c)) {
++                      unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT);
+-              if (ret != num)
+-                      dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
++                      i2c_s3c_irq_nextbyte(i2c, stat);
+-              goto out;
++                      stat = readl(i2c->regs + S3C2410_IICSTAT);
++                      if (stat & S3C2410_IICSTAT_ARBITR)
++                              dev_err(i2c->dev, "deal with arbitration loss\n");
++              }
++      } else {
++              timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+       }
+-      timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
+-
+       ret = i2c->msg_idx;
+       /*
+-- 
+2.43.0
+
diff --git a/queue-6.6/iio-adc-ad9467-add-mutex-to-struct-ad9467_state.patch b/queue-6.6/iio-adc-ad9467-add-mutex-to-struct-ad9467_state.patch
new file mode 100644 (file)
index 0000000..e878603
--- /dev/null
@@ -0,0 +1,66 @@
+From bcff0530ed788c98b41c0424d6275952c3e420ee Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:26 +0100
+Subject: iio: adc: ad9467: add mutex to struct ad9467_state
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit 737720197be445bb9eec2986101e4a386e019337 ]
+
+When calling ad9467_set_scale(), multiple calls to ad9467_spi_write()
+are done which means we need to properly protect the whole operation so
+we are sure we will be in a sane state if two concurrent calls occur.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-3-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index d3c98c4eccd3..104c6d394a3e 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -4,8 +4,9 @@
+  *
+  * Copyright 2012-2020 Analog Devices Inc.
+  */
+-
++#include <linux/cleanup.h>
+ #include <linux/module.h>
++#include <linux/mutex.h>
+ #include <linux/device.h>
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+@@ -121,6 +122,8 @@ struct ad9467_state {
+       unsigned int                    output_mode;
+       struct gpio_desc                *pwrdown_gpio;
++      /* ensure consistent state obtained on multiple related accesses */
++      struct mutex                    lock;
+ };
+ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
+@@ -161,6 +164,7 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg,
+       int ret;
+       if (readval == NULL) {
++              guard(mutex)(&st->lock);
+               ret = ad9467_spi_write(spi, reg, writeval);
+               if (ret)
+                       return ret;
+@@ -310,6 +314,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+               if (scale_val[0] != val || scale_val[1] != val2)
+                       continue;
++              guard(mutex)(&st->lock);
+               ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
+                                      info->scale_table[i][1]);
+               if (ret < 0)
+-- 
+2.43.0
+
diff --git a/queue-6.6/iio-adc-ad9467-don-t-ignore-error-codes.patch b/queue-6.6/iio-adc-ad9467-don-t-ignore-error-codes.patch
new file mode 100644 (file)
index 0000000..60cefce
--- /dev/null
@@ -0,0 +1,85 @@
+From 28c59bd236841ce7945238d3fd2c4e80bb3b1a77 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:25 +0100
+Subject: iio: adc: ad9467: don't ignore error codes
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit e072e149cfb827e0ab4cafb0547e9658e35393cd ]
+
+Make sure functions that return errors are not ignored.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-2-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index 4fb9e48dc782..d3c98c4eccd3 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -162,9 +162,10 @@ static int ad9467_reg_access(struct adi_axi_adc_conv *conv, unsigned int reg,
+       if (readval == NULL) {
+               ret = ad9467_spi_write(spi, reg, writeval);
+-              ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
+-                               AN877_ADC_TRANSFER_SYNC);
+-              return ret;
++              if (ret)
++                      return ret;
++              return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER,
++                                      AN877_ADC_TRANSFER_SYNC);
+       }
+       ret = ad9467_spi_read(spi, reg);
+@@ -272,10 +273,13 @@ static int ad9467_get_scale(struct adi_axi_adc_conv *conv, int *val, int *val2)
+       const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info);
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       unsigned int i, vref_val;
++      int ret;
+-      vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF);
++      ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF);
++      if (ret < 0)
++              return ret;
+-      vref_val &= info1->vref_mask;
++      vref_val = ret & info1->vref_mask;
+       for (i = 0; i < info->num_scales; i++) {
+               if (vref_val == info->scale_table[i][1])
+@@ -296,6 +300,7 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+       unsigned int scale_val[2];
+       unsigned int i;
++      int ret;
+       if (val != 0)
+               return -EINVAL;
+@@ -305,11 +310,13 @@ static int ad9467_set_scale(struct adi_axi_adc_conv *conv, int val, int val2)
+               if (scale_val[0] != val || scale_val[1] != val2)
+                       continue;
+-              ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
+-                               info->scale_table[i][1]);
+-              ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
+-                               AN877_ADC_TRANSFER_SYNC);
+-              return 0;
++              ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF,
++                                     info->scale_table[i][1]);
++              if (ret < 0)
++                      return ret;
++
++              return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER,
++                                      AN877_ADC_TRANSFER_SYNC);
+       }
+       return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-6.6/iio-adc-ad9467-fix-reset-gpio-handling.patch b/queue-6.6/iio-adc-ad9467-fix-reset-gpio-handling.patch
new file mode 100644 (file)
index 0000000..45395d8
--- /dev/null
@@ -0,0 +1,91 @@
+From d803d73e87a1ff16a180cdb0d1c6f7dc5f009614 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:24 +0100
+Subject: iio: adc: ad9467: fix reset gpio handling
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit 76f028539cf360f750efd8cde560edda298e4c6b ]
+
+The reset gpio was being handled with inverted polarity. This means that
+as far as gpiolib is concerned we were actually leaving the pin asserted
+(in theory, this would mean reset). However, inverting the polarity in
+devicetree made things work. Fix it by doing it the proper way and how
+gpiolib expects it to be done.
+
+While at it, moved the handling to it's own function and dropped
+'reset_gpio' from the 'struct ad9467_state' as we only need it during
+probe. On top of that, refactored things so that we now request the gpio
+asserted (i.e in reset) and then de-assert it. Also note that we now use
+gpiod_set_value_cansleep() instead of gpiod_direction_output() as we
+already request the pin as output.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-1-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c | 31 ++++++++++++++++++-------------
+ 1 file changed, 18 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index 39eccc28debe..4fb9e48dc782 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -121,7 +121,6 @@ struct ad9467_state {
+       unsigned int                    output_mode;
+       struct gpio_desc                *pwrdown_gpio;
+-      struct gpio_desc                *reset_gpio;
+ };
+ static int ad9467_spi_read(struct spi_device *spi, unsigned int reg)
+@@ -378,6 +377,21 @@ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+       return ad9467_outputmode_set(st->spi, st->output_mode);
+ }
++static int ad9467_reset(struct device *dev)
++{
++      struct gpio_desc *gpio;
++
++      gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
++      if (IS_ERR_OR_NULL(gpio))
++              return PTR_ERR_OR_ZERO(gpio);
++
++      fsleep(1);
++      gpiod_set_value_cansleep(gpio, 0);
++      fsleep(10 * USEC_PER_MSEC);
++
++      return 0;
++}
++
+ static int ad9467_probe(struct spi_device *spi)
+ {
+       const struct ad9467_chip_info *info;
+@@ -408,18 +422,9 @@ static int ad9467_probe(struct spi_device *spi)
+       if (IS_ERR(st->pwrdown_gpio))
+               return PTR_ERR(st->pwrdown_gpio);
+-      st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset",
+-                                               GPIOD_OUT_LOW);
+-      if (IS_ERR(st->reset_gpio))
+-              return PTR_ERR(st->reset_gpio);
+-
+-      if (st->reset_gpio) {
+-              udelay(1);
+-              ret = gpiod_direction_output(st->reset_gpio, 1);
+-              if (ret)
+-                      return ret;
+-              mdelay(10);
+-      }
++      ret = ad9467_reset(&spi->dev);
++      if (ret)
++              return ret;
+       conv->chip_info = &info->axi_adc_info;
+-- 
+2.43.0
+
diff --git a/queue-6.6/iio-adc-ad9467-fix-scale-setting.patch b/queue-6.6/iio-adc-ad9467-fix-scale-setting.patch
new file mode 100644 (file)
index 0000000..b94bb0b
--- /dev/null
@@ -0,0 +1,255 @@
+From bea50ed2761e9f1acee3b25f874ec350a6b6a212 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 13:39:27 +0100
+Subject: iio: adc: ad9467: fix scale setting
+
+From: Nuno Sa <nuno.sa@analog.com>
+
+[ Upstream commit b73f08bb7fe5a0901646ca5ceaa1e7a2d5ee6293 ]
+
+When reading in_voltage_scale we can get something like:
+
+root@analog:/sys/bus/iio/devices/iio:device2# cat in_voltage_scale
+0.038146
+
+However, when reading the available options:
+
+root@analog:/sys/bus/iio/devices/iio:device2# cat
+in_voltage_scale_available
+2000.000000 2100.000006 2200.000007 2300.000008 2400.000009 2500.000010
+
+which does not make sense. Moreover, when trying to set a new scale we
+get an error because there's no call to __ad9467_get_scale() to give us
+values as given when reading in_voltage_scale. Fix it by computing the
+available scales during probe and properly pass the list when
+.read_available() is called.
+
+While at it, change to use .read_available() from iio_info. Also note
+that to properly fix this, adi-axi-adc.c has to be changed accordingly.
+
+Fixes: ad6797120238 ("iio: adc: ad9467: add support AD9467 ADC")
+Signed-off-by: Nuno Sa <nuno.sa@analog.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://lore.kernel.org/r/20231207-iio-backend-prep-v2-4-a4a33bc4d70e@analog.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iio/adc/ad9467.c            | 47 ++++++++++++++++++
+ drivers/iio/adc/adi-axi-adc.c       | 74 ++++++-----------------------
+ include/linux/iio/adc/adi-axi-adc.h |  4 ++
+ 3 files changed, 66 insertions(+), 59 deletions(-)
+
+diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c
+index 104c6d394a3e..f668313730cb 100644
+--- a/drivers/iio/adc/ad9467.c
++++ b/drivers/iio/adc/ad9467.c
+@@ -120,6 +120,7 @@ struct ad9467_state {
+       struct spi_device               *spi;
+       struct clk                      *clk;
+       unsigned int                    output_mode;
++      unsigned int                    (*scales)[2];
+       struct gpio_desc                *pwrdown_gpio;
+       /* ensure consistent state obtained on multiple related accesses */
+@@ -216,6 +217,7 @@ static void __ad9467_get_scale(struct adi_axi_adc_conv *conv, int index,
+       .channel = _chan,                                               \
+       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ),                           \
++      .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
+       .scan_index = _si,                                              \
+       .scan_type = {                                                  \
+               .sign = _sign,                                          \
+@@ -370,6 +372,26 @@ static int ad9467_write_raw(struct adi_axi_adc_conv *conv,
+       }
+ }
++static int ad9467_read_avail(struct adi_axi_adc_conv *conv,
++                           struct iio_chan_spec const *chan,
++                           const int **vals, int *type, int *length,
++                           long mask)
++{
++      const struct adi_axi_adc_chip_info *info = conv->chip_info;
++      struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
++
++      switch (mask) {
++      case IIO_CHAN_INFO_SCALE:
++              *vals = (const int *)st->scales;
++              *type = IIO_VAL_INT_PLUS_MICRO;
++              /* Values are stored in a 2D matrix */
++              *length = info->num_scales * 2;
++              return IIO_AVAIL_LIST;
++      default:
++              return -EINVAL;
++      }
++}
++
+ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
+ {
+       int ret;
+@@ -382,6 +404,26 @@ static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode)
+                               AN877_ADC_TRANSFER_SYNC);
+ }
++static int ad9467_scale_fill(struct adi_axi_adc_conv *conv)
++{
++      const struct adi_axi_adc_chip_info *info = conv->chip_info;
++      struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
++      unsigned int i, val1, val2;
++
++      st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales,
++                                      sizeof(*st->scales), GFP_KERNEL);
++      if (!st->scales)
++              return -ENOMEM;
++
++      for (i = 0; i < info->num_scales; i++) {
++              __ad9467_get_scale(conv, i, &val1, &val2);
++              st->scales[i][0] = val1;
++              st->scales[i][1] = val2;
++      }
++
++      return 0;
++}
++
+ static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv)
+ {
+       struct ad9467_state *st = adi_axi_adc_conv_priv(conv);
+@@ -440,6 +482,10 @@ static int ad9467_probe(struct spi_device *spi)
+       conv->chip_info = &info->axi_adc_info;
++      ret = ad9467_scale_fill(conv);
++      if (ret)
++              return ret;
++
+       id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID);
+       if (id != conv->chip_info->id) {
+               dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
+@@ -450,6 +496,7 @@ static int ad9467_probe(struct spi_device *spi)
+       conv->reg_access = ad9467_reg_access;
+       conv->write_raw = ad9467_write_raw;
+       conv->read_raw = ad9467_read_raw;
++      conv->read_avail = ad9467_read_avail;
+       conv->preenable_setup = ad9467_preenable_setup;
+       st->output_mode = info->default_output_mode |
+diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c
+index aff0532a974a..ae83ada7f9f2 100644
+--- a/drivers/iio/adc/adi-axi-adc.c
++++ b/drivers/iio/adc/adi-axi-adc.c
+@@ -144,6 +144,20 @@ static int adi_axi_adc_write_raw(struct iio_dev *indio_dev,
+       return conv->write_raw(conv, chan, val, val2, mask);
+ }
++static int adi_axi_adc_read_avail(struct iio_dev *indio_dev,
++                                struct iio_chan_spec const *chan,
++                                const int **vals, int *type, int *length,
++                                long mask)
++{
++      struct adi_axi_adc_state *st = iio_priv(indio_dev);
++      struct adi_axi_adc_conv *conv = &st->client->conv;
++
++      if (!conv->read_avail)
++              return -EOPNOTSUPP;
++
++      return conv->read_avail(conv, chan, vals, type, length, mask);
++}
++
+ static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev,
+                                       const unsigned long *scan_mask)
+ {
+@@ -228,69 +242,11 @@ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
+ }
+ EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI);
+-static ssize_t in_voltage_scale_available_show(struct device *dev,
+-                                             struct device_attribute *attr,
+-                                             char *buf)
+-{
+-      struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+-      struct adi_axi_adc_state *st = iio_priv(indio_dev);
+-      struct adi_axi_adc_conv *conv = &st->client->conv;
+-      size_t len = 0;
+-      int i;
+-
+-      for (i = 0; i < conv->chip_info->num_scales; i++) {
+-              const unsigned int *s = conv->chip_info->scale_table[i];
+-
+-              len += scnprintf(buf + len, PAGE_SIZE - len,
+-                               "%u.%06u ", s[0], s[1]);
+-      }
+-      buf[len - 1] = '\n';
+-
+-      return len;
+-}
+-
+-static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0);
+-
+-enum {
+-      ADI_AXI_ATTR_SCALE_AVAIL,
+-};
+-
+-#define ADI_AXI_ATTR(_en_, _file_)                    \
+-      [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr
+-
+-static struct attribute *adi_axi_adc_attributes[] = {
+-      ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available),
+-      NULL
+-};
+-
+-static umode_t axi_adc_attr_is_visible(struct kobject *kobj,
+-                                     struct attribute *attr, int n)
+-{
+-      struct device *dev = kobj_to_dev(kobj);
+-      struct iio_dev *indio_dev = dev_to_iio_dev(dev);
+-      struct adi_axi_adc_state *st = iio_priv(indio_dev);
+-      struct adi_axi_adc_conv *conv = &st->client->conv;
+-
+-      switch (n) {
+-      case ADI_AXI_ATTR_SCALE_AVAIL:
+-              if (!conv->chip_info->num_scales)
+-                      return 0;
+-              return attr->mode;
+-      default:
+-              return attr->mode;
+-      }
+-}
+-
+-static const struct attribute_group adi_axi_adc_attribute_group = {
+-      .attrs = adi_axi_adc_attributes,
+-      .is_visible = axi_adc_attr_is_visible,
+-};
+-
+ static const struct iio_info adi_axi_adc_info = {
+       .read_raw = &adi_axi_adc_read_raw,
+       .write_raw = &adi_axi_adc_write_raw,
+-      .attrs = &adi_axi_adc_attribute_group,
+       .update_scan_mode = &adi_axi_adc_update_scan_mode,
++      .read_avail = &adi_axi_adc_read_avail,
+ };
+ static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = {
+diff --git a/include/linux/iio/adc/adi-axi-adc.h b/include/linux/iio/adc/adi-axi-adc.h
+index 52620e5b8052..b7904992d561 100644
+--- a/include/linux/iio/adc/adi-axi-adc.h
++++ b/include/linux/iio/adc/adi-axi-adc.h
+@@ -41,6 +41,7 @@ struct adi_axi_adc_chip_info {
+  * @reg_access                IIO debugfs_reg_access hook for the client ADC
+  * @read_raw          IIO read_raw hook for the client ADC
+  * @write_raw         IIO write_raw hook for the client ADC
++ * @read_avail                IIO read_avail hook for the client ADC
+  */
+ struct adi_axi_adc_conv {
+       const struct adi_axi_adc_chip_info              *chip_info;
+@@ -54,6 +55,9 @@ struct adi_axi_adc_conv {
+       int (*write_raw)(struct adi_axi_adc_conv *conv,
+                        struct iio_chan_spec const *chan,
+                        int val, int val2, long mask);
++      int (*read_avail)(struct adi_axi_adc_conv *conv,
++                        struct iio_chan_spec const *chan,
++                        const int **val, int *type, int *length, long mask);
+ };
+ struct adi_axi_adc_conv *devm_adi_axi_adc_conv_register(struct device *dev,
+-- 
+2.43.0
+
diff --git a/queue-6.6/io_uring-adjust-defer-tw-counting.patch b/queue-6.6/io_uring-adjust-defer-tw-counting.patch
new file mode 100644 (file)
index 0000000..ee57a67
--- /dev/null
@@ -0,0 +1,45 @@
+From 5f79c202aba81ca8c13c828fdea51a268de33de8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 00:57:26 +0000
+Subject: io_uring: adjust defer tw counting
+
+From: Pavel Begunkov <asml.silence@gmail.com>
+
+[ Upstream commit dc12d1799ce710fd90abbe0ced71e7e1ae0894fc ]
+
+The UINT_MAX work item counting bias in io_req_local_work_add() in case
+of !IOU_F_TWQ_LAZY_WAKE works in a sense that we will not miss a wake up,
+however it's still eerie. In particular, if we add a lazy work item
+after a non-lazy one, we'll increment it and get nr_tw==0, and
+subsequent adds may try to unnecessarily wake up the task, which is
+though not so likely to happen in real workloads.
+
+Half the bias, it's still large enough to be larger than any valid
+->cq_wait_nr, which is limited by IORING_MAX_CQ_ENTRIES, but further
+have a good enough of space before it overflows.
+
+Fixes: 8751d15426a31 ("io_uring: reduce scheduling due to tw")
+Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
+Link: https://lore.kernel.org/r/108b971e958deaf7048342930c341ba90f75d806.1705438669.git.asml.silence@gmail.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ io_uring/io_uring.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c
+index 1cc4c7b05949..ea772a02c140 100644
+--- a/io_uring/io_uring.c
++++ b/io_uring/io_uring.c
+@@ -1339,7 +1339,7 @@ static inline void io_req_local_work_add(struct io_kiocb *req, unsigned flags)
+               nr_tw = nr_tw_prev + 1;
+               /* Large enough to fail the nr_wait comparison below */
+               if (!(flags & IOU_F_TWQ_LAZY_WAKE))
+-                      nr_tw = -1U;
++                      nr_tw = INT_MAX;
+               req->nr_tw = nr_tw;
+               req->io_task_work.node.next = first;
+-- 
+2.43.0
+
diff --git a/queue-6.6/iommu-don-t-reserve-0-length-iova-region.patch b/queue-6.6/iommu-don-t-reserve-0-length-iova-region.patch
new file mode 100644 (file)
index 0000000..7536bee
--- /dev/null
@@ -0,0 +1,50 @@
+From ade1b356ede75584eb6a4525e1401d8e1dc0e08d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 12:26:56 +0530
+Subject: iommu: Don't reserve 0-length IOVA region
+
+From: Ashish Mhetre <amhetre@nvidia.com>
+
+[ Upstream commit bb57f6705960bebeb832142ce9abf43220c3eab1 ]
+
+When the bootloader/firmware doesn't setup the framebuffers, their
+address and size are 0 in "iommu-addresses" property. If IOVA region is
+reserved with 0 length, then it ends up corrupting the IOVA rbtree with
+an entry which has pfn_hi < pfn_lo.
+If we intend to use display driver in kernel without framebuffer then
+it's causing the display IOMMU mappings to fail as entire valid IOVA
+space is reserved when address and length are passed as 0.
+An ideal solution would be firmware removing the "iommu-addresses"
+property and corresponding "memory-region" if display is not present.
+But the kernel should be able to handle this by checking for size of
+IOVA region and skipping the IOVA reservation if size is 0. Also, add
+a warning if firmware is requesting 0-length IOVA region reservation.
+
+Fixes: a5bf3cfce8cb ("iommu: Implement of_iommu_get_resv_regions()")
+Signed-off-by: Ashish Mhetre <amhetre@nvidia.com>
+Acked-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/20231205065656.9544-1-amhetre@nvidia.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/of_iommu.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
+index 47302b637cc0..42cffb0ee5e2 100644
+--- a/drivers/iommu/of_iommu.c
++++ b/drivers/iommu/of_iommu.c
+@@ -264,6 +264,10 @@ void of_iommu_get_resv_regions(struct device *dev, struct list_head *list)
+                                       prot |= IOMMU_CACHE;
+                               maps = of_translate_dma_region(np, maps, &iova, &length);
++                              if (length == 0) {
++                                      dev_warn(dev, "Cannot reserve IOVA region of 0 size\n");
++                                      continue;
++                              }
+                               type = iommu_resv_region_get_type(dev, &phys, iova, length);
+                               region = iommu_alloc_resv_region(iova, length, prot, type,
+-- 
+2.43.0
+
diff --git a/queue-6.6/iommu-map-reserved-memory-as-cacheable-if-device-is-.patch b/queue-6.6/iommu-map-reserved-memory-as-cacheable-if-device-is-.patch
new file mode 100644 (file)
index 0000000..6412245
--- /dev/null
@@ -0,0 +1,43 @@
+From 3220f8df94ad4e32855adad7482714cd463e6ae3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Sep 2023 18:26:00 +0300
+Subject: iommu: Map reserved memory as cacheable if device is coherent
+
+From: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+
+[ Upstream commit f1aad9df93f39267e890836a28d22511f23474e1 ]
+
+Check if the device is marked as DMA coherent in the DT and if so,
+map its reserved memory as cacheable in the IOMMU.
+This fixes the recently added IOMMU reserved memory support which
+uses IOMMU_RESV_DIRECT without properly building the PROT for the
+mapping.
+
+Fixes: a5bf3cfce8cb ("iommu: Implement of_iommu_get_resv_regions()")
+Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
+Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
+Acked-by: Thierry Reding <treding@nvidia.com>
+Link: https://lore.kernel.org/r/20230926152600.8749-1-laurentiu.tudor@nxp.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/of_iommu.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
+index 35ba090f3b5e..47302b637cc0 100644
+--- a/drivers/iommu/of_iommu.c
++++ b/drivers/iommu/of_iommu.c
+@@ -260,6 +260,9 @@ void of_iommu_get_resv_regions(struct device *dev, struct list_head *list)
+                               phys_addr_t iova;
+                               size_t length;
++                              if (of_dma_is_coherent(dev->of_node))
++                                      prot |= IOMMU_CACHE;
++
+                               maps = of_translate_dma_region(np, maps, &iova, &length);
+                               type = iommu_resv_region_get_type(dev, &phys, iova, length);
+-- 
+2.43.0
+
diff --git a/queue-6.6/ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch b/queue-6.6/ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch
new file mode 100644 (file)
index 0000000..1bb4fa3
--- /dev/null
@@ -0,0 +1,81 @@
+From eceacbf8cde07d70fe6baf8e2d481474bd51c65d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 09:21:02 -0800
+Subject: ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+[ Upstream commit 2e7ef287f07c74985f1bf2858bedc62bd9ebf155 ]
+
+idev->mc_ifc_count can be written over without proper locking.
+
+Originally found by syzbot [1], fix this issue by encapsulating calls
+to mld_ifc_stop_work() (and mld_gq_stop_work() for good measure) with
+mutex_lock() and mutex_unlock() accordingly as these functions
+should only be called with mc_lock per their declarations.
+
+[1]
+BUG: KCSAN: data-race in ipv6_mc_down / mld_ifc_work
+
+write to 0xffff88813a80c832 of 1 bytes by task 3771 on cpu 0:
+ mld_ifc_stop_work net/ipv6/mcast.c:1080 [inline]
+ ipv6_mc_down+0x10a/0x280 net/ipv6/mcast.c:2725
+ addrconf_ifdown+0xe32/0xf10 net/ipv6/addrconf.c:3949
+ addrconf_notify+0x310/0x980
+ notifier_call_chain kernel/notifier.c:93 [inline]
+ raw_notifier_call_chain+0x6b/0x1c0 kernel/notifier.c:461
+ __dev_notify_flags+0x205/0x3d0
+ dev_change_flags+0xab/0xd0 net/core/dev.c:8685
+ do_setlink+0x9f6/0x2430 net/core/rtnetlink.c:2916
+ rtnl_group_changelink net/core/rtnetlink.c:3458 [inline]
+ __rtnl_newlink net/core/rtnetlink.c:3717 [inline]
+ rtnl_newlink+0xbb3/0x1670 net/core/rtnetlink.c:3754
+ rtnetlink_rcv_msg+0x807/0x8c0 net/core/rtnetlink.c:6558
+ netlink_rcv_skb+0x126/0x220 net/netlink/af_netlink.c:2545
+ rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:6576
+ netlink_unicast_kernel net/netlink/af_netlink.c:1342 [inline]
+ netlink_unicast+0x589/0x650 net/netlink/af_netlink.c:1368
+ netlink_sendmsg+0x66e/0x770 net/netlink/af_netlink.c:1910
+ ...
+
+write to 0xffff88813a80c832 of 1 bytes by task 22 on cpu 1:
+ mld_ifc_work+0x54c/0x7b0 net/ipv6/mcast.c:2653
+ process_one_work kernel/workqueue.c:2627 [inline]
+ process_scheduled_works+0x5b8/0xa30 kernel/workqueue.c:2700
+ worker_thread+0x525/0x730 kernel/workqueue.c:2781
+ ...
+
+Fixes: 2d9a93b4902b ("mld: convert from timer to delayed work")
+Reported-by: syzbot+a9400cabb1d784e49abf@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/000000000000994e09060ebcdffb@google.com/
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Acked-by: Taehee Yoo <ap420073@gmail.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://lore.kernel.org/r/20240117172102.12001-1-n.zhandarovich@fintech.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/mcast.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
+index 5ce25bcb9974..f948cf7bfc44 100644
+--- a/net/ipv6/mcast.c
++++ b/net/ipv6/mcast.c
+@@ -2723,8 +2723,12 @@ void ipv6_mc_down(struct inet6_dev *idev)
+       synchronize_net();
+       mld_query_stop_work(idev);
+       mld_report_stop_work(idev);
++
++      mutex_lock(&idev->mc_lock);
+       mld_ifc_stop_work(idev);
+       mld_gq_stop_work(idev);
++      mutex_unlock(&idev->mc_lock);
++
+       mld_dad_stop_work(idev);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch b/queue-6.6/ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch
new file mode 100644 (file)
index 0000000..75d0662
--- /dev/null
@@ -0,0 +1,83 @@
+From 7ac9cac28e3b3553e82b725f72ca3de75dd04956 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 17:39:22 +0300
+Subject: ipvs: avoid stat macros calls from preemptible context
+
+From: Fedor Pchelkin <pchelkin@ispras.ru>
+
+[ Upstream commit d6938c1c76c64f42363d0d1f051e1b4641c2ad40 ]
+
+Inside decrement_ttl() upon discovering that the packet ttl has exceeded,
+__IP_INC_STATS and __IP6_INC_STATS macros can be called from preemptible
+context having the following backtrace:
+
+check_preemption_disabled: 48 callbacks suppressed
+BUG: using __this_cpu_add() in preemptible [00000000] code: curl/1177
+caller is decrement_ttl+0x217/0x830
+CPU: 5 PID: 1177 Comm: curl Not tainted 6.7.0+ #34
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0xbd/0xe0
+ check_preemption_disabled+0xd1/0xe0
+ decrement_ttl+0x217/0x830
+ __ip_vs_get_out_rt+0x4e0/0x1ef0
+ ip_vs_nat_xmit+0x205/0xcd0
+ ip_vs_in_hook+0x9b1/0x26a0
+ nf_hook_slow+0xc2/0x210
+ nf_hook+0x1fb/0x770
+ __ip_local_out+0x33b/0x640
+ ip_local_out+0x2a/0x490
+ __ip_queue_xmit+0x990/0x1d10
+ __tcp_transmit_skb+0x288b/0x3d10
+ tcp_connect+0x3466/0x5180
+ tcp_v4_connect+0x1535/0x1bb0
+ __inet_stream_connect+0x40d/0x1040
+ inet_stream_connect+0x57/0xa0
+ __sys_connect_file+0x162/0x1a0
+ __sys_connect+0x137/0x160
+ __x64_sys_connect+0x72/0xb0
+ do_syscall_64+0x6f/0x140
+ entry_SYSCALL_64_after_hwframe+0x6e/0x76
+RIP: 0033:0x7fe6dbbc34e0
+
+Use the corresponding preemption-aware variants: IP_INC_STATS and
+IP6_INC_STATS.
+
+Found by Linux Verification Center (linuxtesting.org).
+
+Fixes: 8d8e20e2d7bb ("ipvs: Decrement ttl")
+Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
+Acked-by: Julian Anastasov <ja@ssi.bg>
+Acked-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/ipvs/ip_vs_xmit.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
+index 9193e109e6b3..65e0259178da 100644
+--- a/net/netfilter/ipvs/ip_vs_xmit.c
++++ b/net/netfilter/ipvs/ip_vs_xmit.c
+@@ -271,7 +271,7 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+                       skb->dev = dst->dev;
+                       icmpv6_send(skb, ICMPV6_TIME_EXCEED,
+                                   ICMPV6_EXC_HOPLIMIT, 0);
+-                      __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
++                      IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
+                       return false;
+               }
+@@ -286,7 +286,7 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs,
+       {
+               if (ip_hdr(skb)->ttl <= 1) {
+                       /* Tell the sender its packet died... */
+-                      __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
++                      IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
+                       icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
+                       return false;
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.6/kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch b/queue-6.6/kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch
new file mode 100644 (file)
index 0000000..64231e2
--- /dev/null
@@ -0,0 +1,45 @@
+From 9f0f7e34e903b2610e71a96e8fe246a39949e84f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Nov 2023 13:05:04 +0100
+Subject: kdb: Fix a potential buffer overflow in kdb_local()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 4f41d30cd6dc865c3cbc1a852372321eba6d4e4c ]
+
+When appending "[defcmd]" to 'kdb_prompt_str', the size of the string
+already in the buffer should be taken into account.
+
+An option could be to switch from strncat() to strlcat() which does the
+correct test to avoid such an overflow.
+
+However, this actually looks as dead code, because 'defcmd_in_progress'
+can't be true here.
+See a more detailed explanation at [1].
+
+[1]: https://lore.kernel.org/all/CAD=FV=WSh7wKN7Yp-3wWiDgX4E3isQ8uh0LCzTmd1v9Cg9j+nQ@mail.gmail.com/
+
+Fixes: 5d5314d6795f ("kdb: core for kgdb back end (1 of 2)")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/debug/kdb/kdb_main.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
+index 438b868cbfa9..35aa2e98a92a 100644
+--- a/kernel/debug/kdb/kdb_main.c
++++ b/kernel/debug/kdb/kdb_main.c
+@@ -1349,8 +1349,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs,
+               /* PROMPT can only be set if we have MEM_READ permission. */
+               snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"),
+                        raw_smp_processor_id());
+-              if (defcmd_in_progress)
+-                      strncat(kdb_prompt_str, "[defcmd]", CMD_BUFLEN);
+               /*
+                * Fetch command from keyboard
+-- 
+2.43.0
+
diff --git a/queue-6.6/leds-aw200xx-fix-write-to-dim-parameter.patch b/queue-6.6/leds-aw200xx-fix-write-to-dim-parameter.patch
new file mode 100644 (file)
index 0000000..b0460df
--- /dev/null
@@ -0,0 +1,52 @@
+From f7f8c38ed434cd1e715e7539c20284bc5bb94a90 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 25 Nov 2023 23:05:09 +0300
+Subject: leds: aw200xx: Fix write to DIM parameter
+
+From: Martin Kurbanov <mmkurbanov@salutedevices.com>
+
+[ Upstream commit adfd4621b78d0c02da91335da2b9ad847cb7b39e ]
+
+If write only DIM value to the page 4, LED brightness will not be
+updated, as both DIM and FADE need to be written to the page 4.
+Therefore, write DIM to the page 1.
+
+Fixes: 36a87f371b7a ("leds: Add AW20xx driver")
+Signed-off-by: Martin Kurbanov <mmkurbanov@salutedevices.com>
+Signed-off-by: Dmitry Rokosov <ddrokosov@salutedevices.com>
+Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
+Link: https://lore.kernel.org/r/20231125200519.1750-2-ddrokosov@salutedevices.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/leds-aw200xx.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/leds/leds-aw200xx.c b/drivers/leds/leds-aw200xx.c
+index 691a743cc9b0..5142efea2339 100644
+--- a/drivers/leds/leds-aw200xx.c
++++ b/drivers/leds/leds-aw200xx.c
+@@ -74,6 +74,10 @@
+ #define AW200XX_LED2REG(x, columns) \
+       ((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns))))
++/* DIM current configuration register on page 1 */
++#define AW200XX_REG_DIM_PAGE1(x, columns) \
++      AW200XX_REG(AW200XX_PAGE1, AW200XX_LED2REG(x, columns))
++
+ /*
+  * DIM current configuration register (page 4).
+  * The even address for current DIM configuration.
+@@ -153,7 +157,8 @@ static ssize_t dim_store(struct device *dev, struct device_attribute *devattr,
+       if (dim >= 0) {
+               ret = regmap_write(chip->regmap,
+-                                 AW200XX_REG_DIM(led->num, columns), dim);
++                                 AW200XX_REG_DIM_PAGE1(led->num, columns),
++                                 dim);
+               if (ret)
+                       goto out_unlock;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/leds-aw2013-select-missing-dependency-regmap_i2c.patch b/queue-6.6/leds-aw2013-select-missing-dependency-regmap_i2c.patch
new file mode 100644 (file)
index 0000000..43e1aa8
--- /dev/null
@@ -0,0 +1,41 @@
+From 708a6160926d7adc381c52bd823914c2a753ccef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 3 Nov 2023 18:42:03 +0700
+Subject: leds: aw2013: Select missing dependency REGMAP_I2C
+
+From: Dang Huynh <danct12@riseup.net>
+
+[ Upstream commit 75469bb0537ad2ab0fc1fb6e534a79cfc03f3b3f ]
+
+The AW2013 driver uses devm_regmap_init_i2c, so REGMAP_I2C needs to
+be selected.
+
+Otherwise build process may fail with:
+  ld: drivers/leds/leds-aw2013.o: in function `aw2013_probe':
+    leds-aw2013.c:345: undefined reference to `__devm_regmap_init_i2c'
+
+Signed-off-by: Dang Huynh <danct12@riseup.net>
+Acked-by: Nikita Travkin <nikita@trvn.ru>
+Fixes: 59ea3c9faf32 ("leds: add aw2013 driver")
+Link: https://lore.kernel.org/r/20231103114203.1108922-1-danct12@riseup.net
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/leds/Kconfig | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
+index b92208eccdea..3132439f99e0 100644
+--- a/drivers/leds/Kconfig
++++ b/drivers/leds/Kconfig
+@@ -110,6 +110,7 @@ config LEDS_AW200XX
+ config LEDS_AW2013
+       tristate "LED support for Awinic AW2013"
+       depends on LEDS_CLASS && I2C && OF
++      select REGMAP_I2C
+       help
+         This option enables support for the AW2013 3-channel
+         LED driver.
+-- 
+2.43.0
+
diff --git a/queue-6.6/libapi-add-missing-linux-types.h-header-to-get-the-_.patch b/queue-6.6/libapi-add-missing-linux-types.h-header-to-get-the-_.patch
new file mode 100644 (file)
index 0000000..86333ac
--- /dev/null
@@ -0,0 +1,40 @@
+From e80456df5b77825ae22f7cedc7b5e60cd53e6425 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 14:11:45 -0300
+Subject: libapi: Add missing linux/types.h header to get the __u64 type on
+ io.h
+
+From: Arnaldo Carvalho de Melo <acme@redhat.com>
+
+[ Upstream commit af76b2dec0984a079d8497bfa37d29a9b55932e1 ]
+
+There are functions using __u64, so we need to have the linux/types.h
+header otherwise we'll break when its not included before api/io.h.
+
+Fixes: e95770af4c4a280f ("tools api: Add a lightweight buffered reading api")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/lkml/ZWjDPL+IzPPsuC3X@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/lib/api/io.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/lib/api/io.h b/tools/lib/api/io.h
+index 9fc429d2852d..f4a9328035bd 100644
+--- a/tools/lib/api/io.h
++++ b/tools/lib/api/io.h
+@@ -12,6 +12,7 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
++#include <linux/types.h>
+ struct io {
+       /* File descriptor being read/ */
+-- 
+2.43.0
+
diff --git a/queue-6.6/loongarch-bpf-prevent-out-of-bounds-memory-access.patch b/queue-6.6/loongarch-bpf-prevent-out-of-bounds-memory-access.patch
new file mode 100644 (file)
index 0000000..4e57002
--- /dev/null
@@ -0,0 +1,116 @@
+From 3a9a066c86c5b7cabf221af96fe1ff3045ba4ab7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 12:43:13 +0800
+Subject: LoongArch: BPF: Prevent out-of-bounds memory access
+
+From: Hengqi Chen <hengqi.chen@gmail.com>
+
+[ Upstream commit 36a87385e31c9343af9a4756598e704741250a67 ]
+
+The test_tag test triggers an unhandled page fault:
+
+  # ./test_tag
+  [  130.640218] CPU 0 Unable to handle kernel paging request at virtual address ffff80001b898004, era == 9000000003137f7c, ra == 9000000003139e70
+  [  130.640501] Oops[#3]:
+  [  130.640553] CPU: 0 PID: 1326 Comm: test_tag Tainted: G      D    O       6.7.0-rc4-loong-devel-gb62ab1a397cf #47 61985c1d94084daa2432f771daa45b56b10d8d2a
+  [  130.640764] Hardware name: QEMU QEMU Virtual Machine, BIOS unknown 2/2/2022
+  [  130.640874] pc 9000000003137f7c ra 9000000003139e70 tp 9000000104cb4000 sp 9000000104cb7a40
+  [  130.641001] a0 ffff80001b894000 a1 ffff80001b897ff8 a2 000000006ba210be a3 0000000000000000
+  [  130.641128] a4 000000006ba210be a5 00000000000000f1 a6 00000000000000b3 a7 0000000000000000
+  [  130.641256] t0 0000000000000000 t1 00000000000007f6 t2 0000000000000000 t3 9000000004091b70
+  [  130.641387] t4 000000006ba210be t5 0000000000000004 t6 fffffffffffffff0 t7 90000000040913e0
+  [  130.641512] t8 0000000000000005 u0 0000000000000dc0 s9 0000000000000009 s0 9000000104cb7ae0
+  [  130.641641] s1 00000000000007f6 s2 0000000000000009 s3 0000000000000095 s4 0000000000000000
+  [  130.641771] s5 ffff80001b894000 s6 ffff80001b897fb0 s7 9000000004090c50 s8 0000000000000000
+  [  130.641900]    ra: 9000000003139e70 build_body+0x1fcc/0x4988
+  [  130.642007]   ERA: 9000000003137f7c build_body+0xd8/0x4988
+  [  130.642112]  CRMD: 000000b0 (PLV0 -IE -DA +PG DACF=CC DACM=CC -WE)
+  [  130.642261]  PRMD: 00000004 (PPLV0 +PIE -PWE)
+  [  130.642353]  EUEN: 00000003 (+FPE +SXE -ASXE -BTE)
+  [  130.642458]  ECFG: 00071c1c (LIE=2-4,10-12 VS=7)
+  [  130.642554] ESTAT: 00010000 [PIL] (IS= ECode=1 EsubCode=0)
+  [  130.642658]  BADV: ffff80001b898004
+  [  130.642719]  PRID: 0014c010 (Loongson-64bit, Loongson-3A5000)
+  [  130.642815] Modules linked in: [last unloaded: bpf_testmod(O)]
+  [  130.642924] Process test_tag (pid: 1326, threadinfo=00000000f7f4015f, task=000000006499f9fd)
+  [  130.643062] Stack : 0000000000000000 9000000003380724 0000000000000000 0000000104cb7be8
+  [  130.643213]         0000000000000000 25af8d9b6e600558 9000000106250ea0 9000000104cb7ae0
+  [  130.643378]         0000000000000000 0000000000000000 9000000104cb7be8 90000000049f6000
+  [  130.643538]         0000000000000090 9000000106250ea0 ffff80001b894000 ffff80001b894000
+  [  130.643685]         00007ffffb917790 900000000313ca94 0000000000000000 0000000000000000
+  [  130.643831]         ffff80001b894000 0000000000000ff7 0000000000000000 9000000100468000
+  [  130.643983]         0000000000000000 0000000000000000 0000000000000040 25af8d9b6e600558
+  [  130.644131]         0000000000000bb7 ffff80001b894048 0000000000000000 0000000000000000
+  [  130.644276]         9000000104cb7be8 90000000049f6000 0000000000000090 9000000104cb7bdc
+  [  130.644423]         ffff80001b894000 0000000000000000 00007ffffb917790 90000000032acfb0
+  [  130.644572]         ...
+  [  130.644629] Call Trace:
+  [  130.644641] [<9000000003137f7c>] build_body+0xd8/0x4988
+  [  130.644785] [<900000000313ca94>] bpf_int_jit_compile+0x228/0x4ec
+  [  130.644891] [<90000000032acfb0>] bpf_prog_select_runtime+0x158/0x1b0
+  [  130.645003] [<90000000032b3504>] bpf_prog_load+0x760/0xb44
+  [  130.645089] [<90000000032b6744>] __sys_bpf+0xbb8/0x2588
+  [  130.645175] [<90000000032b8388>] sys_bpf+0x20/0x2c
+  [  130.645259] [<9000000003f6ab38>] do_syscall+0x7c/0x94
+  [  130.645369] [<9000000003121c5c>] handle_syscall+0xbc/0x158
+  [  130.645507]
+  [  130.645539] Code: 380839f6  380831f9  28412bae <24000ca6> 004081ad  0014cb50  004083e8  02bff34c  58008e91
+  [  130.645729]
+  [  130.646418] ---[ end trace 0000000000000000 ]---
+
+On my machine, which has CONFIG_PAGE_SIZE_16KB=y, the test failed at
+loading a BPF prog with 2039 instructions:
+
+  prog = (struct bpf_prog *)ffff80001b894000
+  insn = (struct bpf_insn *)(prog->insnsi)ffff80001b894048
+  insn + 2039 = (struct bpf_insn *)ffff80001b898000 <- end of the page
+
+In the build_insn() function, we are trying to access next instruction
+unconditionally, i.e. `(insn + 1)->imm`. The address lies in the next
+page and can be not owned by the current process, thus an page fault is
+inevitable and then segfault.
+
+So, let's access next instruction only under `dst = imm64` context.
+
+With this fix, we have:
+
+  # ./test_tag
+  test_tag: OK (40945 tests)
+
+Fixes: bbfddb904df6f82 ("LoongArch: BPF: Avoid declare variables in switch-case")
+Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn>
+Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/loongarch/net/bpf_jit.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c
+index 00915fb3cb82..9eb7753d117d 100644
+--- a/arch/loongarch/net/bpf_jit.c
++++ b/arch/loongarch/net/bpf_jit.c
+@@ -461,7 +461,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
+       const u8 dst = regmap[insn->dst_reg];
+       const s16 off = insn->off;
+       const s32 imm = insn->imm;
+-      const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm;
+       const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32;
+       switch (code) {
+@@ -865,8 +864,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
+       /* dst = imm64 */
+       case BPF_LD | BPF_IMM | BPF_DW:
++      {
++              const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm;
++
+               move_imm(ctx, dst, imm64, is32);
+               return 1;
++      }
+       /* dst = *(size *)(src + off) */
+       case BPF_LDX | BPF_MEM | BPF_B:
+-- 
+2.43.0
+
diff --git a/queue-6.6/loop-fix-the-the-direct-i-o-support-check-when-used-.patch b/queue-6.6/loop-fix-the-the-direct-i-o-support-check-when-used-.patch
new file mode 100644 (file)
index 0000000..5af5f4c
--- /dev/null
@@ -0,0 +1,108 @@
+From cecc627f37b919567a98a407e39a741341e612de Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 18:59:01 +0100
+Subject: loop: fix the the direct I/O support check when used on top of block
+ devices
+
+From: Christoph Hellwig <hch@lst.de>
+
+[ Upstream commit baa7d536077dcdfe2b70c476a8873d1745d3de0f ]
+
+__loop_update_dio only checks the alignment requirement for block backed
+file systems, but misses them for the case where the loop device is
+created directly on top of another block device.  Due to this creating
+a loop device with default option plus the direct I/O flag on a > 512 byte
+sector size file system will lead to incorrect I/O being submitted to the
+lower block device and a lot of error from the lock layer.  This can
+be seen with xfstests generic/563.
+
+Fix the code in __loop_update_dio by factoring the alignment check into
+a helper, and calling that also for the struct block_device of a block
+device inode.
+
+Also remove the TODO comment talking about dynamically switching between
+buffered and direct I/O, which is a would be a recipe for horrible
+performance and occasional data loss.
+
+Fixes: 2e5ab5f379f9 ("block: loop: prepare for supporing direct IO")
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20240117175901.871796-1-hch@lst.de
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/loop.c | 52 +++++++++++++++++++++-----------------------
+ 1 file changed, 25 insertions(+), 27 deletions(-)
+
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index 9f2d412fc560..552f56a84a7e 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -165,39 +165,37 @@ static loff_t get_loop_size(struct loop_device *lo, struct file *file)
+       return get_size(lo->lo_offset, lo->lo_sizelimit, file);
+ }
++/*
++ * We support direct I/O only if lo_offset is aligned with the logical I/O size
++ * of backing device, and the logical block size of loop is bigger than that of
++ * the backing device.
++ */
++static bool lo_bdev_can_use_dio(struct loop_device *lo,
++              struct block_device *backing_bdev)
++{
++      unsigned short sb_bsize = bdev_logical_block_size(backing_bdev);
++
++      if (queue_logical_block_size(lo->lo_queue) < sb_bsize)
++              return false;
++      if (lo->lo_offset & (sb_bsize - 1))
++              return false;
++      return true;
++}
++
+ static void __loop_update_dio(struct loop_device *lo, bool dio)
+ {
+       struct file *file = lo->lo_backing_file;
+-      struct address_space *mapping = file->f_mapping;
+-      struct inode *inode = mapping->host;
+-      unsigned short sb_bsize = 0;
+-      unsigned dio_align = 0;
++      struct inode *inode = file->f_mapping->host;
++      struct block_device *backing_bdev = NULL;
+       bool use_dio;
+-      if (inode->i_sb->s_bdev) {
+-              sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
+-              dio_align = sb_bsize - 1;
+-      }
++      if (S_ISBLK(inode->i_mode))
++              backing_bdev = I_BDEV(inode);
++      else if (inode->i_sb->s_bdev)
++              backing_bdev = inode->i_sb->s_bdev;
+-      /*
+-       * We support direct I/O only if lo_offset is aligned with the
+-       * logical I/O size of backing device, and the logical block
+-       * size of loop is bigger than the backing device's.
+-       *
+-       * TODO: the above condition may be loosed in the future, and
+-       * direct I/O may be switched runtime at that time because most
+-       * of requests in sane applications should be PAGE_SIZE aligned
+-       */
+-      if (dio) {
+-              if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
+-                  !(lo->lo_offset & dio_align) &&
+-                  (file->f_mode & FMODE_CAN_ODIRECT))
+-                      use_dio = true;
+-              else
+-                      use_dio = false;
+-      } else {
+-              use_dio = false;
+-      }
++      use_dio = dio && (file->f_mode & FMODE_CAN_ODIRECT) &&
++              (!backing_bdev || lo_bdev_can_use_dio(lo, backing_bdev));
+       if (lo->use_dio == use_dio)
+               return;
+-- 
+2.43.0
+
diff --git a/queue-6.6/mfd-cs42l43-correct-soundwire-port-list.patch b/queue-6.6/mfd-cs42l43-correct-soundwire-port-list.patch
new file mode 100644 (file)
index 0000000..898d6c4
--- /dev/null
@@ -0,0 +1,140 @@
+From dda191db6b77af8395adaaf2795db0e022213032 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 11:57:11 +0000
+Subject: mfd: cs42l43: Correct SoundWire port list
+
+From: Charles Keepax <ckeepax@opensource.cirrus.com>
+
+[ Upstream commit 47b1b03dc56ebc302620ce43e967aa8f33516f6f ]
+
+Two ports are missing from the port list, and the wrong port is set
+to 4 channels. Also the attempt to list them by function is rather
+misguided, there is nothing in the hardware that fixes a particular
+port to one function. Factor out the port properties to an actual
+struct, fixing the missing ports and correcting the port set to 4
+channels.
+
+Fixes: ace6d1448138 ("mfd: cs42l43: Add support for cs42l43 core driver")
+Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
+Link: https://lore.kernel.org/r/20231130115712.669180-1-ckeepax@opensource.cirrus.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/cs42l43-sdw.c | 74 +++++++++++++++------------------------
+ 1 file changed, 28 insertions(+), 46 deletions(-)
+
+diff --git a/drivers/mfd/cs42l43-sdw.c b/drivers/mfd/cs42l43-sdw.c
+index 7392b3d2e6b9..4be4df9dd8cf 100644
+--- a/drivers/mfd/cs42l43-sdw.c
++++ b/drivers/mfd/cs42l43-sdw.c
+@@ -17,13 +17,12 @@
+ #include "cs42l43.h"
+-enum cs42l43_sdw_ports {
+-      CS42L43_DMIC_DEC_ASP_PORT = 1,
+-      CS42L43_SPK_TX_PORT,
+-      CS42L43_SPDIF_HP_PORT,
+-      CS42L43_SPK_RX_PORT,
+-      CS42L43_ASP_PORT,
+-};
++#define CS42L43_SDW_PORT(port, chans) { \
++      .num = port, \
++      .max_ch = chans, \
++      .type = SDW_DPN_FULL, \
++      .max_word = 24, \
++}
+ static const struct regmap_config cs42l43_sdw_regmap = {
+       .reg_bits               = 32,
+@@ -42,65 +41,48 @@ static const struct regmap_config cs42l43_sdw_regmap = {
+       .num_reg_defaults       = ARRAY_SIZE(cs42l43_reg_default),
+ };
++static const struct sdw_dpn_prop cs42l43_src_port_props[] = {
++      CS42L43_SDW_PORT(1, 4),
++      CS42L43_SDW_PORT(2, 2),
++      CS42L43_SDW_PORT(3, 2),
++      CS42L43_SDW_PORT(4, 2),
++};
++
++static const struct sdw_dpn_prop cs42l43_sink_port_props[] = {
++      CS42L43_SDW_PORT(5, 2),
++      CS42L43_SDW_PORT(6, 2),
++      CS42L43_SDW_PORT(7, 2),
++};
++
+ static int cs42l43_read_prop(struct sdw_slave *sdw)
+ {
+       struct sdw_slave_prop *prop = &sdw->prop;
+       struct device *dev = &sdw->dev;
+-      struct sdw_dpn_prop *dpn;
+-      unsigned long addr;
+-      int nval;
+       int i;
+-      u32 bit;
+       prop->use_domain_irq = true;
+       prop->paging_support = true;
+       prop->wake_capable = true;
+-      prop->source_ports = BIT(CS42L43_DMIC_DEC_ASP_PORT) | BIT(CS42L43_SPK_TX_PORT);
+-      prop->sink_ports = BIT(CS42L43_SPDIF_HP_PORT) |
+-                         BIT(CS42L43_SPK_RX_PORT) | BIT(CS42L43_ASP_PORT);
+       prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
+       prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY |
+                             SDW_SCP_INT1_IMPL_DEF;
+-      nval = hweight32(prop->source_ports);
+-      prop->src_dpn_prop = devm_kcalloc(dev, nval, sizeof(*prop->src_dpn_prop),
+-                                        GFP_KERNEL);
++      for (i = 0; i < ARRAY_SIZE(cs42l43_src_port_props); i++)
++              prop->source_ports |= BIT(cs42l43_src_port_props[i].num);
++
++      prop->src_dpn_prop = devm_kmemdup(dev, cs42l43_src_port_props,
++                                        sizeof(cs42l43_src_port_props), GFP_KERNEL);
+       if (!prop->src_dpn_prop)
+               return -ENOMEM;
+-      i = 0;
+-      dpn = prop->src_dpn_prop;
+-      addr = prop->source_ports;
+-      for_each_set_bit(bit, &addr, 32) {
+-              dpn[i].num = bit;
+-              dpn[i].max_ch = 2;
+-              dpn[i].type = SDW_DPN_FULL;
+-              dpn[i].max_word = 24;
+-              i++;
+-      }
+-      /*
+-       * All ports are 2 channels max, except the first one,
+-       * CS42L43_DMIC_DEC_ASP_PORT.
+-       */
+-      dpn[CS42L43_DMIC_DEC_ASP_PORT].max_ch = 4;
++      for (i = 0; i < ARRAY_SIZE(cs42l43_sink_port_props); i++)
++              prop->sink_ports |= BIT(cs42l43_sink_port_props[i].num);
+-      nval = hweight32(prop->sink_ports);
+-      prop->sink_dpn_prop = devm_kcalloc(dev, nval, sizeof(*prop->sink_dpn_prop),
+-                                         GFP_KERNEL);
++      prop->sink_dpn_prop = devm_kmemdup(dev, cs42l43_sink_port_props,
++                                         sizeof(cs42l43_sink_port_props), GFP_KERNEL);
+       if (!prop->sink_dpn_prop)
+               return -ENOMEM;
+-      i = 0;
+-      dpn = prop->sink_dpn_prop;
+-      addr = prop->sink_ports;
+-      for_each_set_bit(bit, &addr, 32) {
+-              dpn[i].num = bit;
+-              dpn[i].max_ch = 2;
+-              dpn[i].type = SDW_DPN_FULL;
+-              dpn[i].max_word = 24;
+-              i++;
+-      }
+-
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch b/queue-6.6/mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch
new file mode 100644 (file)
index 0000000..5d6a316
--- /dev/null
@@ -0,0 +1,40 @@
+From 54bd649974d7f61b39d48ff806de70f647b8d4af Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 13:14:41 +0200
+Subject: mfd: intel-lpss: Fix the fractional clock divider flags
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 03d790f04fb2507173913cad9c213272ac983a60 ]
+
+The conversion to CLK_FRAC_DIVIDER_POWER_OF_TWO_PS uses wrong flags
+in the parameters and hence miscalculates the values in the clock
+divider. Fix this by applying the flag to the proper parameter.
+
+Fixes: 82f53f9ee577 ("clk: fractional-divider: Introduce POWER_OF_TWO_PS flag")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reported-by: Alex Vinarskis <alex.vinarskis@gmail.com>
+Link: https://lore.kernel.org/r/20231211111441.3910083-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/intel-lpss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
+index 9591b354072a..00e7b578bb3e 100644
+--- a/drivers/mfd/intel-lpss.c
++++ b/drivers/mfd/intel-lpss.c
+@@ -301,8 +301,8 @@ static int intel_lpss_register_clock_divider(struct intel_lpss *lpss,
+       snprintf(name, sizeof(name), "%s-div", devname);
+       tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp),
++                                            0, lpss->priv, 1, 15, 16, 15,
+                                             CLK_FRAC_DIVIDER_POWER_OF_TWO_PS,
+-                                            lpss->priv, 1, 15, 16, 15, 0,
+                                             NULL);
+       if (IS_ERR(tmp))
+               return PTR_ERR(tmp);
+-- 
+2.43.0
+
diff --git a/queue-6.6/mfd-rk8xx-fixup-devices-registration-with-platform_d.patch b/queue-6.6/mfd-rk8xx-fixup-devices-registration-with-platform_d.patch
new file mode 100644 (file)
index 0000000..41971ba
--- /dev/null
@@ -0,0 +1,173 @@
+From 9d52af2af48ddcc3b73dbb73d74e646773ba9bd7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 15:05:13 +0100
+Subject: mfd: rk8xx: fixup devices registration with PLATFORM_DEVID_AUTO
+
+From: Neil Armstrong <neil.armstrong@linaro.org>
+
+[ Upstream commit 4aedcd4aa61d536ca17e67ecd5bc5d42529164f4 ]
+
+Since commit 210f418f8ace ("mfd: rk8xx: Add rk806 support"), devices are
+registered with "0" as id, causing devices to not have an automatic device id
+and prevents having multiple RK8xx PMICs on the same system.
+
+Properly pass PLATFORM_DEVID_AUTO to devm_mfd_add_devices() and since
+it will ignore the cells .id with this special value, also cleanup
+by removing all now ignored cells .id values.
+
+Now we have the same behaviour as before rk806 introduction and rk806
+retains the intended behavior.
+
+This fixes a regression while booting the Odroid Go Ultra on v6.6.1:
+sysfs: cannot create duplicate filename '/bus/platform/devices/rk808-clkout'
+CPU: 3 PID: 97 Comm: kworker/u12:2 Not tainted 6.6.1 #1
+Hardware name: Hardkernel ODROID-GO-Ultra (DT)
+Workqueue: events_unbound deferred_probe_work_func
+Call trace:
+dump_backtrace+0x9c/0x11c
+show_stack+0x18/0x24
+dump_stack_lvl+0x78/0xc4
+dump_stack+0x18/0x24
+sysfs_warn_dup+0x64/0x80
+sysfs_do_create_link_sd+0xf0/0xf8
+sysfs_create_link+0x20/0x40
+bus_add_device+0x114/0x160
+device_add+0x3f0/0x7cc
+platform_device_add+0x180/0x270
+mfd_add_device+0x390/0x4a8
+devm_mfd_add_devices+0xb0/0x150
+rk8xx_probe+0x26c/0x410
+rk8xx_i2c_probe+0x64/0x98
+i2c_device_probe+0x104/0x2e8
+really_probe+0x184/0x3c8
+__driver_probe_device+0x7c/0x16c
+driver_probe_device+0x3c/0x10c
+__device_attach_driver+0xbc/0x158
+bus_for_each_drv+0x80/0xdc
+__device_attach+0x9c/0x1ac
+device_initial_probe+0x14/0x20
+bus_probe_device+0xac/0xb0
+deferred_probe_work_func+0xa0/0xf4
+process_one_work+0x1bc/0x378
+worker_thread+0x1dc/0x3d4
+kthread+0x104/0x118
+ret_from_fork+0x10/0x20
+rk8xx-i2c 0-001c: error -EEXIST: failed to add MFD devices
+rk8xx-i2c: probe of 0-001c failed with error -17
+
+Fixes: 210f418f8ace ("mfd: rk8xx: Add rk806 support")
+Reported-by: Adam Green <greena88@gmail.com>
+Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
+Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Link: https://lore.kernel.org/r/20231116-topic-amlogic-upstream-fix-rk8xx-devid-auto-v2-1-3f1bad68ab9d@linaro.org
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/rk8xx-core.c | 34 +++++++++++++---------------------
+ 1 file changed, 13 insertions(+), 21 deletions(-)
+
+diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c
+index 11a831e92da8..a577f950c632 100644
+--- a/drivers/mfd/rk8xx-core.c
++++ b/drivers/mfd/rk8xx-core.c
+@@ -53,76 +53,68 @@ static const struct resource rk817_charger_resources[] = {
+ };
+ static const struct mfd_cell rk805s[] = {
+-      { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+-      { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
+-      { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_NONE, },
++      { .name = "rk808-clkout", },
++      { .name = "rk808-regulator", },
++      { .name = "rk805-pinctrl", },
+       {
+               .name = "rk808-rtc",
+               .num_resources = ARRAY_SIZE(rtc_resources),
+               .resources = &rtc_resources[0],
+-              .id = PLATFORM_DEVID_NONE,
+       },
+       {       .name = "rk805-pwrkey",
+               .num_resources = ARRAY_SIZE(rk805_key_resources),
+               .resources = &rk805_key_resources[0],
+-              .id = PLATFORM_DEVID_NONE,
+       },
+ };
+ static const struct mfd_cell rk806s[] = {
+-      { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, },
+-      { .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, },
++      { .name = "rk805-pinctrl", },
++      { .name = "rk808-regulator", },
+       {
+               .name = "rk805-pwrkey",
+               .resources = rk806_pwrkey_resources,
+               .num_resources = ARRAY_SIZE(rk806_pwrkey_resources),
+-              .id = PLATFORM_DEVID_AUTO,
+       },
+ };
+ static const struct mfd_cell rk808s[] = {
+-      { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+-      { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
++      { .name = "rk808-clkout", },
++      { .name = "rk808-regulator", },
+       {
+               .name = "rk808-rtc",
+               .num_resources = ARRAY_SIZE(rtc_resources),
+               .resources = rtc_resources,
+-              .id = PLATFORM_DEVID_NONE,
+       },
+ };
+ static const struct mfd_cell rk817s[] = {
+-      { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+-      { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
++      { .name = "rk808-clkout", },
++      { .name = "rk808-regulator", },
+       {
+               .name = "rk805-pwrkey",
+               .num_resources = ARRAY_SIZE(rk817_pwrkey_resources),
+               .resources = &rk817_pwrkey_resources[0],
+-              .id = PLATFORM_DEVID_NONE,
+       },
+       {
+               .name = "rk808-rtc",
+               .num_resources = ARRAY_SIZE(rk817_rtc_resources),
+               .resources = &rk817_rtc_resources[0],
+-              .id = PLATFORM_DEVID_NONE,
+       },
+-      { .name = "rk817-codec", .id = PLATFORM_DEVID_NONE, },
++      { .name = "rk817-codec", },
+       {
+               .name = "rk817-charger",
+               .num_resources = ARRAY_SIZE(rk817_charger_resources),
+               .resources = &rk817_charger_resources[0],
+-              .id = PLATFORM_DEVID_NONE,
+       },
+ };
+ static const struct mfd_cell rk818s[] = {
+-      { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, },
+-      { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, },
++      { .name = "rk808-clkout", },
++      { .name = "rk808-regulator", },
+       {
+               .name = "rk808-rtc",
+               .num_resources = ARRAY_SIZE(rtc_resources),
+               .resources = rtc_resources,
+-              .id = PLATFORM_DEVID_NONE,
+       },
+ };
+@@ -680,7 +672,7 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap
+                                            pre_init_reg[i].addr);
+       }
+-      ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0,
++      ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0,
+                             regmap_irq_get_domain(rk808->irq_data));
+       if (ret)
+               return dev_err_probe(dev, ret, "failed to add MFD devices\n");
+-- 
+2.43.0
+
diff --git a/queue-6.6/mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch b/queue-6.6/mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch
new file mode 100644 (file)
index 0000000..4c8e90b
--- /dev/null
@@ -0,0 +1,40 @@
+From 6b30d404d554e1c219ec6854cdd1640826602e94 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 17:24:43 +0800
+Subject: mfd: syscon: Fix null pointer dereference in of_syscon_register()
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 41673c66b3d0c09915698fec5c13b24336f18dd1 ]
+
+kasprintf() returns a pointer to dynamically allocated memory
+which can be NULL upon failure.
+
+Fixes: e15d7f2b81d2 ("mfd: syscon: Use a unique name with regmap_config")
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Reviewed-by: Arnd Bergmann <arnd@arndb.de>
+Link: https://lore.kernel.org/r/20231204092443.2462115-1-chentao@kylinos.cn
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/syscon.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
+index 57b29c325131..c9550368d9ea 100644
+--- a/drivers/mfd/syscon.c
++++ b/drivers/mfd/syscon.c
+@@ -105,6 +105,10 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res)
+       }
+       syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start);
++      if (!syscon_config.name) {
++              ret = -ENOMEM;
++              goto err_regmap;
++      }
+       syscon_config.reg_stride = reg_io_width;
+       syscon_config.val_bits = reg_io_width * 8;
+       syscon_config.max_register = resource_size(&res) - reg_io_width;
+-- 
+2.43.0
+
diff --git a/queue-6.6/mfd-tps6594-add-null-pointer-check-to-tps6594_device.patch b/queue-6.6/mfd-tps6594-add-null-pointer-check-to-tps6594_device.patch
new file mode 100644 (file)
index 0000000..ea2502a
--- /dev/null
@@ -0,0 +1,39 @@
+From 86c0958e57bae54bf54fface639027c929d2c3f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Dec 2023 11:33:20 +0800
+Subject: mfd: tps6594: Add null pointer check to tps6594_device_init()
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 825906f2ebe83977d747d8bce61675dddd72485d ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory
+which can be NULL upon failure.
+
+Fixes: 325bec7157b3 ("mfd: tps6594: Add driver for TI TPS6594 PMIC")
+Suggested-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Link: https://lore.kernel.org/r/20231208033320.49345-1-chentao@kylinos.cn
+Signed-off-by: Lee Jones <lee@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/tps6594-core.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/mfd/tps6594-core.c b/drivers/mfd/tps6594-core.c
+index 0fb9c5cf213a..783ee59901e8 100644
+--- a/drivers/mfd/tps6594-core.c
++++ b/drivers/mfd/tps6594-core.c
+@@ -433,6 +433,9 @@ int tps6594_device_init(struct tps6594 *tps, bool enable_crc)
+       tps6594_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x",
+                                              dev->driver->name, tps->chip_id, tps->reg);
++      if (!tps6594_irq_chip.name)
++              return -ENOMEM;
++
+       ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT,
+                                      0, &tps6594_irq_chip, &tps->irq_data);
+       if (ret)
+-- 
+2.43.0
+
diff --git a/queue-6.6/mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch b/queue-6.6/mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch
new file mode 100644 (file)
index 0000000..7f7746c
--- /dev/null
@@ -0,0 +1,36 @@
+From c324bc5424d8baf7c8b702f7d15724f9d54250bf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 19:07:36 +0100
+Subject: MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 89c4b588d11e9acf01d604de4b0c715884f59213 ]
+
+When calling spi_register_board_info(), we should pass the number of
+elements in 'db1200_spi_devs', not 'db1200_i2c_devs'.
+
+Fixes: 63323ec54a7e ("MIPS: Alchemy: Extended DB1200 board support.")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/alchemy/devboards/db1200.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c
+index f521874ebb07..67f067706af2 100644
+--- a/arch/mips/alchemy/devboards/db1200.c
++++ b/arch/mips/alchemy/devboards/db1200.c
+@@ -847,7 +847,7 @@ int __init db1200_dev_setup(void)
+       i2c_register_board_info(0, db1200_i2c_devs,
+                               ARRAY_SIZE(db1200_i2c_devs));
+       spi_register_board_info(db1200_spi_devs,
+-                              ARRAY_SIZE(db1200_i2c_devs));
++                              ARRAY_SIZE(db1200_spi_devs));
+       /* SWITCHES:    S6.8 I2C/SPI selector  (OFF=I2C  ON=SPI)
+        *              S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
+-- 
+2.43.0
+
diff --git a/queue-6.6/mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch b/queue-6.6/mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch
new file mode 100644 (file)
index 0000000..447a084
--- /dev/null
@@ -0,0 +1,35 @@
+From 117f281c05f4f4d5212fce701b82caf70b6c14b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 19:09:46 +0100
+Subject: MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 3c1e5abcda64bed0c7bffa65af2316995f269a61 ]
+
+When calling spi_register_board_info(),
+
+Fixes: f869d42e580f ("MIPS: Alchemy: Improved DB1550 support, with audio and serial busses.")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/alchemy/devboards/db1550.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c
+index fd91d9c9a252..6c6837181f55 100644
+--- a/arch/mips/alchemy/devboards/db1550.c
++++ b/arch/mips/alchemy/devboards/db1550.c
+@@ -589,7 +589,7 @@ int __init db1550_dev_setup(void)
+       i2c_register_board_info(0, db1550_i2c_devs,
+                               ARRAY_SIZE(db1550_i2c_devs));
+       spi_register_board_info(db1550_spi_devs,
+-                              ARRAY_SIZE(db1550_i2c_devs));
++                              ARRAY_SIZE(db1550_spi_devs));
+       c = clk_get(NULL, "psc0_intclk");
+       if (!IS_ERR(c)) {
+-- 
+2.43.0
+
diff --git a/queue-6.6/mips-dmi-fix-early-remap-on-mips32.patch b/queue-6.6/mips-dmi-fix-early-remap-on-mips32.patch
new file mode 100644 (file)
index 0000000..2ac63dc
--- /dev/null
@@ -0,0 +1,44 @@
+From cceb666f922674324d30a57937eb70be8b06499b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Dec 2023 14:14:18 +0300
+Subject: mips: dmi: Fix early remap on MIPS32
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit 0d0a3748a2cb38f9da1f08d357688ebd982eb788 ]
+
+dmi_early_remap() has been defined as ioremap_cache() which on MIPS32 gets
+to be converted to the VM-based mapping. DMI early remapping is performed
+at the setup_arch() stage with no VM available. So calling the
+dmi_early_remap() for MIPS32 causes the system to crash at the early boot
+time. Fix that by converting dmi_early_remap() to the uncached remapping
+which is always available on both 32 and 64-bits MIPS systems.
+
+Note this change shall not cause any regressions on the current DMI
+support implementation because on the early boot-up stage neither MIPS32
+nor MIPS64 has the cacheable ioremapping support anyway.
+
+Fixes: be8fa1cb444c ("MIPS: Add support for Desktop Management Interface (DMI)")
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/include/asm/dmi.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/include/asm/dmi.h b/arch/mips/include/asm/dmi.h
+index 27415a288adf..dc397f630c66 100644
+--- a/arch/mips/include/asm/dmi.h
++++ b/arch/mips/include/asm/dmi.h
+@@ -5,7 +5,7 @@
+ #include <linux/io.h>
+ #include <linux/memblock.h>
+-#define dmi_early_remap(x, l)         ioremap_cache(x, l)
++#define dmi_early_remap(x, l)         ioremap(x, l)
+ #define dmi_early_unmap(x, l)         iounmap(x)
+ #define dmi_remap(x, l)                       ioremap_cache(x, l)
+ #define dmi_unmap(x)                  iounmap(x)
+-- 
+2.43.0
+
diff --git a/queue-6.6/mips-fix-incorrect-max_low_pfn-adjustment.patch b/queue-6.6/mips-fix-incorrect-max_low_pfn-adjustment.patch
new file mode 100644 (file)
index 0000000..1a9cf4e
--- /dev/null
@@ -0,0 +1,80 @@
+From ce4e5b3811d3fc618e821e0be5c38aaad80f6d53 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 2 Dec 2023 14:14:19 +0300
+Subject: mips: Fix incorrect max_low_pfn adjustment
+
+From: Serge Semin <fancer.lancer@gmail.com>
+
+[ Upstream commit 0f5cc249ff73552d3bd864e62f85841dafaa107d ]
+
+max_low_pfn variable is incorrectly adjusted if the kernel is built with
+high memory support and the later is detected in a running system, so the
+memory which actually can be directly mapped is getting into the highmem
+zone. See the ZONE_NORMAL range on my MIPS32r5 system:
+
+> Zone ranges:
+>   DMA      [mem 0x0000000000000000-0x0000000000ffffff]
+>   Normal   [mem 0x0000000001000000-0x0000000007ffffff]
+>   HighMem  [mem 0x0000000008000000-0x000000020fffffff]
+
+while the zones are supposed to look as follows:
+
+> Zone ranges:
+>   DMA      [mem 0x0000000000000000-0x0000000000ffffff]
+>   Normal   [mem 0x0000000001000000-0x000000001fffffff]
+>   HighMem  [mem 0x0000000020000000-0x000000020fffffff]
+
+Even though the physical memory within the range [0x08000000;0x20000000]
+belongs to MMIO on our system, we don't really want it to be considered as
+high memory since on MIPS32 that range still can be directly mapped.
+
+Note there might be other problems caused by the max_low_pfn variable
+misconfiguration. For instance high_memory variable is initialize with
+virtual address corresponding to the max_low_pfn PFN, and by design it
+must define the upper bound on direct map memory, then end of the normal
+zone. That in its turn potentially may cause problems in accessing the
+memory by means of the /dev/mem and /dev/kmem devices.
+
+Let's fix the discovered misconfiguration then. It turns out the commit
+a94e4f24ec83 ("MIPS: init: Drop boot_mem_map") didn't introduce the
+max_low_pfn adjustment quite correct. If the kernel is built with high
+memory support and the system is equipped with high memory, the
+max_low_pfn variable will need to be initialized with PFN of the most
+upper directly reachable memory address so the zone normal would be
+correctly setup. On MIPS that PFN corresponds to PFN_DOWN(HIGHMEM_START).
+If the system is built with no high memory support and one is detected in
+the running system, we'll just need to adjust the max_pfn variable to
+discard the found high memory from the system and leave the max_low_pfn as
+is, since the later will be less than PFN_DOWN(HIGHMEM_START) anyway by
+design of the for_each_memblock() loop performed a bit early in the
+bootmem_init() method.
+
+Fixes: a94e4f24ec83 ("MIPS: init: Drop boot_mem_map")
+Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/kernel/setup.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index cb871eb784a7..f88a2f83c5ea 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -326,11 +326,11 @@ static void __init bootmem_init(void)
+               panic("Incorrect memory mapping !!!");
+       if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
++              max_low_pfn = PFN_DOWN(HIGHMEM_START);
+ #ifdef CONFIG_HIGHMEM
+-              highstart_pfn = PFN_DOWN(HIGHMEM_START);
++              highstart_pfn = max_low_pfn;
+               highend_pfn = max_pfn;
+ #else
+-              max_low_pfn = PFN_DOWN(HIGHMEM_START);
+               max_pfn = max_low_pfn;
+ #endif
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch b/queue-6.6/mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch
new file mode 100644 (file)
index 0000000..c1c5eeb
--- /dev/null
@@ -0,0 +1,185 @@
+From 0393b8e3fc9fbc7da518042c66bf4ae6e67726be Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:16 +0100
+Subject: mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit 6d6eeabcfaba2fcadf5443b575789ea606f9de83 ]
+
+Lately, a bug was found when many TC filters are added - at some point,
+several bugs are printed to dmesg [1] and the switch is crashed with
+segmentation fault.
+
+The issue starts when gen_pool_free() fails because of unexpected
+behavior - a try to free memory which is already freed, this leads to BUG()
+call which crashes the switch and makes many other bugs.
+
+Trying to track down the unexpected behavior led to a bug in eRP code. The
+function mlxsw_sp_acl_erp_table_alloc() gets a pointer to the allocated
+index, sets the value and returns an error code. When gen_pool_alloc()
+fails it returns address 0, we track it and return -ENOBUFS outside, BUT
+the call for gen_pool_alloc() already override the index in erp_table
+structure. This is a problem when such allocation is done as part of
+table expansion. This is not a new table, which will not be used in case
+of allocation failure. We try to expand eRP table and override the
+current index (non-zero) with zero. Then, it leads to an unexpected
+behavior when address 0 is freed twice. Note that address 0 is valid in
+erp_table->base_index and indeed other tables use it.
+
+gen_pool_alloc() fails in case that there is no space left in the
+pre-allocated pool, in our case, the pool is limited to
+ACL_MAX_ERPT_BANK_SIZE, which is read from hardware. When more than max
+erp entries are required, we exceed the limit and return an error, this
+error leads to "Failed to migrate vregion" print.
+
+Fix this by changing erp_table->base_index only in case of a successful
+allocation.
+
+Add a test case for such a scenario. Without this fix it causes
+segmentation fault:
+
+$ TESTS="max_erp_entries_test" ./tc_flower.sh
+./tc_flower.sh: line 988:  1560 Segmentation fault      tc filter del dev $h2 ingress chain $i protocol ip pref $i handle $j flower &>/dev/null
+
+[1]:
+kernel BUG at lib/genalloc.c:508!
+invalid opcode: 0000 [#1] PREEMPT SMP
+CPU: 6 PID: 3531 Comm: tc Not tainted 6.7.0-rc5-custom-ga6893f479f5e #1
+Hardware name: Mellanox Technologies Ltd. MSN4700/VMOD0010, BIOS 5.11 07/12/2021
+RIP: 0010:gen_pool_free_owner+0xc9/0xe0
+...
+Call Trace:
+ <TASK>
+ __mlxsw_sp_acl_erp_table_other_dec+0x70/0xa0 [mlxsw_spectrum]
+ mlxsw_sp_acl_erp_mask_destroy+0xf5/0x110 [mlxsw_spectrum]
+ objagg_obj_root_destroy+0x18/0x80 [objagg]
+ objagg_obj_destroy+0x12c/0x130 [objagg]
+ mlxsw_sp_acl_erp_mask_put+0x37/0x50 [mlxsw_spectrum]
+ mlxsw_sp_acl_ctcam_region_entry_remove+0x74/0xa0 [mlxsw_spectrum]
+ mlxsw_sp_acl_ctcam_entry_del+0x1e/0x40 [mlxsw_spectrum]
+ mlxsw_sp_acl_tcam_ventry_del+0x78/0xd0 [mlxsw_spectrum]
+ mlxsw_sp_flower_destroy+0x4d/0x70 [mlxsw_spectrum]
+ mlxsw_sp_flow_block_cb+0x73/0xb0 [mlxsw_spectrum]
+ tc_setup_cb_destroy+0xc1/0x180
+ fl_hw_destroy_filter+0x94/0xc0 [cls_flower]
+ __fl_delete+0x1ac/0x1c0 [cls_flower]
+ fl_destroy+0xc2/0x150 [cls_flower]
+ tcf_proto_destroy+0x1a/0xa0
+...
+mlxsw_spectrum3 0000:07:00.0: Failed to migrate vregion
+mlxsw_spectrum3 0000:07:00.0: Failed to migrate vregion
+
+Fixes: f465261aa105 ("mlxsw: spectrum_acl: Implement common eRP core")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/4cfca254dfc0e5d283974801a24371c7b6db5989.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlxsw/spectrum_acl_erp.c         |  8 +--
+ .../drivers/net/mlxsw/spectrum-2/tc_flower.sh | 52 ++++++++++++++++++-
+ 2 files changed, 56 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
+index 4c98950380d5..d231f4d2888b 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c
+@@ -301,6 +301,7 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
+                            unsigned long *p_index)
+ {
+       unsigned int num_rows, entry_size;
++      unsigned long index;
+       /* We only allow allocations of entire rows */
+       if (num_erps % erp_core->num_erp_banks != 0)
+@@ -309,10 +310,11 @@ mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
+       entry_size = erp_core->erpt_entries_size[region_type];
+       num_rows = num_erps / erp_core->num_erp_banks;
+-      *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
+-      if (*p_index == 0)
++      index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
++      if (!index)
+               return -ENOBUFS;
+-      *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;
++
++      *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;
+       return 0;
+ }
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+index fb850e0ec837..7bf56ea161e3 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+@@ -10,7 +10,8 @@ lib_dir=$(dirname $0)/../../../../net/forwarding
+ ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
+       multiple_masks_test ctcam_edge_cases_test delta_simple_test \
+       delta_two_masks_one_key_test delta_simple_rehash_test \
+-      bloom_simple_test bloom_complex_test bloom_delta_test"
++      bloom_simple_test bloom_complex_test bloom_delta_test \
++      max_erp_entries_test"
+ NUM_NETIFS=2
+ source $lib_dir/lib.sh
+ source $lib_dir/tc_common.sh
+@@ -983,6 +984,55 @@ bloom_delta_test()
+       log_test "bloom delta test ($tcflags)"
+ }
++max_erp_entries_test()
++{
++      # The number of eRP entries is limited. Once the maximum number of eRPs
++      # has been reached, filters cannot be added. This test verifies that
++      # when this limit is reached, inserstion fails without crashing.
++
++      RET=0
++
++      local num_masks=32
++      local num_regions=15
++      local chain_failed
++      local mask_failed
++      local ret
++
++      if [[ "$tcflags" != "skip_sw" ]]; then
++              return 0;
++      fi
++
++      for ((i=1; i < $num_regions; i++)); do
++              for ((j=$num_masks; j >= 0; j--)); do
++                      tc filter add dev $h2 ingress chain $i protocol ip \
++                              pref $i handle $j flower $tcflags \
++                              dst_ip 192.1.0.0/$j &> /dev/null
++                      ret=$?
++
++                      if [ $ret -ne 0 ]; then
++                              chain_failed=$i
++                              mask_failed=$j
++                              break 2
++                      fi
++              done
++      done
++
++      # We expect to exceed the maximum number of eRP entries, so that
++      # insertion eventually fails. Otherwise, the test should be adjusted to
++      # add more filters.
++      check_fail $ret "expected to exceed number of eRP entries"
++
++      for ((; i >= 1; i--)); do
++              for ((j=0; j <= $num_masks; j++)); do
++                      tc filter del dev $h2 ingress chain $i protocol ip \
++                              pref $i handle $j flower &> /dev/null
++              done
++      done
++
++      log_test "max eRP entries test ($tcflags). " \
++              "max chain $chain_failed, mask $mask_failed"
++}
++
+ setup_prepare()
+ {
+       h1=${NETIFS[p1]}
+-- 
+2.43.0
+
diff --git a/queue-6.6/mlxsw-spectrum_acl_tcam-fix-null-pointer-dereference.patch b/queue-6.6/mlxsw-spectrum_acl_tcam-fix-null-pointer-dereference.patch
new file mode 100644 (file)
index 0000000..1bd8e2c
--- /dev/null
@@ -0,0 +1,75 @@
+From dca8f0d9b0a5c26b772f20897de13f411cbdd6d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:17 +0100
+Subject: mlxsw: spectrum_acl_tcam: Fix NULL pointer dereference in error path
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit efeb7dfea8ee10cdec11b6b6ba4e405edbe75809 ]
+
+When calling mlxsw_sp_acl_tcam_region_destroy() from an error path after
+failing to attach the region to an ACL group, we hit a NULL pointer
+dereference upon 'region->group->tcam' [1].
+
+Fix by retrieving the 'tcam' pointer using mlxsw_sp_acl_to_tcam().
+
+[1]
+BUG: kernel NULL pointer dereference, address: 0000000000000000
+[...]
+RIP: 0010:mlxsw_sp_acl_tcam_region_destroy+0xa0/0xd0
+[...]
+Call Trace:
+ mlxsw_sp_acl_tcam_vchunk_get+0x88b/0xa20
+ mlxsw_sp_acl_tcam_ventry_add+0x25/0xe0
+ mlxsw_sp_acl_rule_add+0x47/0x240
+ mlxsw_sp_flower_replace+0x1a9/0x1d0
+ tc_setup_cb_add+0xdc/0x1c0
+ fl_hw_replace_filter+0x146/0x1f0
+ fl_change+0xc17/0x1360
+ tc_new_tfilter+0x472/0xb90
+ rtnetlink_rcv_msg+0x313/0x3b0
+ netlink_rcv_skb+0x58/0x100
+ netlink_unicast+0x244/0x390
+ netlink_sendmsg+0x1e4/0x440
+ ____sys_sendmsg+0x164/0x260
+ ___sys_sendmsg+0x9a/0xe0
+ __sys_sendmsg+0x7a/0xc0
+ do_syscall_64+0x40/0xe0
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Fixes: 22a677661f56 ("mlxsw: spectrum: Introduce ACL core with simple TCAM implementation")
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/fb6a4542bbc9fcab5a523802d97059bffbca7126.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index d50786b0a6ce..7d1e91196e94 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -681,13 +681,13 @@ static void
+ mlxsw_sp_acl_tcam_region_destroy(struct mlxsw_sp *mlxsw_sp,
+                                struct mlxsw_sp_acl_tcam_region *region)
+ {
++      struct mlxsw_sp_acl_tcam *tcam = mlxsw_sp_acl_to_tcam(mlxsw_sp->acl);
+       const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops;
+       ops->region_fini(mlxsw_sp, region->priv);
+       mlxsw_sp_acl_tcam_region_disable(mlxsw_sp, region);
+       mlxsw_sp_acl_tcam_region_free(mlxsw_sp, region);
+-      mlxsw_sp_acl_tcam_region_id_put(region->group->tcam,
+-                                      region->id);
++      mlxsw_sp_acl_tcam_region_id_put(tcam, region->id);
+       kfree(region);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch b/queue-6.6/mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch
new file mode 100644 (file)
index 0000000..d144b68
--- /dev/null
@@ -0,0 +1,162 @@
+From 9fcd0b6642584dc177534ef503f960dc607a8621 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:18 +0100
+Subject: mlxsw: spectrum_acl_tcam: Fix stack corruption
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 483ae90d8f976f8339cf81066312e1329f2d3706 ]
+
+When tc filters are first added to a net device, the corresponding local
+port gets bound to an ACL group in the device. The group contains a list
+of ACLs. In turn, each ACL points to a different TCAM region where the
+filters are stored. During forwarding, the ACLs are sequentially
+evaluated until a match is found.
+
+One reason to place filters in different regions is when they are added
+with decreasing priorities and in an alternating order so that two
+consecutive filters can never fit in the same region because of their
+key usage.
+
+In Spectrum-2 and newer ASICs the firmware started to report that the
+maximum number of ACLs in a group is more than 16, but the layout of the
+register that configures ACL groups (PAGT) was not updated to account
+for that. It is therefore possible to hit stack corruption [1] in the
+rare case where more than 16 ACLs in a group are required.
+
+Fix by limiting the maximum ACL group size to the minimum between what
+the firmware reports and the maximum ACLs that fit in the PAGT register.
+
+Add a test case to make sure the machine does not crash when this
+condition is hit.
+
+[1]
+Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: mlxsw_sp_acl_tcam_group_update+0x116/0x120
+[...]
+ dump_stack_lvl+0x36/0x50
+ panic+0x305/0x330
+ __stack_chk_fail+0x15/0x20
+ mlxsw_sp_acl_tcam_group_update+0x116/0x120
+ mlxsw_sp_acl_tcam_group_region_attach+0x69/0x110
+ mlxsw_sp_acl_tcam_vchunk_get+0x492/0xa20
+ mlxsw_sp_acl_tcam_ventry_add+0x25/0xe0
+ mlxsw_sp_acl_rule_add+0x47/0x240
+ mlxsw_sp_flower_replace+0x1a9/0x1d0
+ tc_setup_cb_add+0xdc/0x1c0
+ fl_hw_replace_filter+0x146/0x1f0
+ fl_change+0xc17/0x1360
+ tc_new_tfilter+0x472/0xb90
+ rtnetlink_rcv_msg+0x313/0x3b0
+ netlink_rcv_skb+0x58/0x100
+ netlink_unicast+0x244/0x390
+ netlink_sendmsg+0x1e4/0x440
+ ____sys_sendmsg+0x164/0x260
+ ___sys_sendmsg+0x9a/0xe0
+ __sys_sendmsg+0x7a/0xc0
+ do_syscall_64+0x40/0xe0
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Fixes: c3ab435466d5 ("mlxsw: spectrum: Extend to support Spectrum-2 ASIC")
+Reported-by: Orel Hagag <orelh@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Amit Cohen <amcohen@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/2d91c89afba59c22587b444994ae419dbea8d876.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../mellanox/mlxsw/spectrum_acl_tcam.c        |  2 +
+ .../drivers/net/mlxsw/spectrum-2/tc_flower.sh | 56 ++++++++++++++++++-
+ 2 files changed, 57 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+index 7d1e91196e94..50ea1eff02b2 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c
+@@ -1564,6 +1564,8 @@ int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
+       tcam->max_groups = max_groups;
+       tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
+                                                 ACL_MAX_GROUP_SIZE);
++      tcam->max_group_size = min_t(unsigned int, tcam->max_group_size,
++                                   MLXSW_REG_PAGT_ACL_MAX_NUM);
+       err = ops->init(mlxsw_sp, tcam->priv, tcam);
+       if (err)
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+index 7bf56ea161e3..616d3581419c 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum-2/tc_flower.sh
+@@ -11,7 +11,7 @@ ALL_TESTS="single_mask_test identical_filters_test two_masks_test \
+       multiple_masks_test ctcam_edge_cases_test delta_simple_test \
+       delta_two_masks_one_key_test delta_simple_rehash_test \
+       bloom_simple_test bloom_complex_test bloom_delta_test \
+-      max_erp_entries_test"
++      max_erp_entries_test max_group_size_test"
+ NUM_NETIFS=2
+ source $lib_dir/lib.sh
+ source $lib_dir/tc_common.sh
+@@ -1033,6 +1033,60 @@ max_erp_entries_test()
+               "max chain $chain_failed, mask $mask_failed"
+ }
++max_group_size_test()
++{
++      # The number of ACLs in an ACL group is limited. Once the maximum
++      # number of ACLs has been reached, filters cannot be added. This test
++      # verifies that when this limit is reached, insertion fails without
++      # crashing.
++
++      RET=0
++
++      local num_acls=32
++      local max_size
++      local ret
++
++      if [[ "$tcflags" != "skip_sw" ]]; then
++              return 0;
++      fi
++
++      for ((i=1; i < $num_acls; i++)); do
++              if [[ $(( i % 2 )) == 1 ]]; then
++                      tc filter add dev $h2 ingress pref $i proto ipv4 \
++                              flower $tcflags dst_ip 198.51.100.1/32 \
++                              ip_proto tcp tcp_flags 0x01/0x01 \
++                              action drop &> /dev/null
++              else
++                      tc filter add dev $h2 ingress pref $i proto ipv6 \
++                              flower $tcflags dst_ip 2001:db8:1::1/128 \
++                              action drop &> /dev/null
++              fi
++
++              ret=$?
++              [[ $ret -ne 0 ]] && max_size=$((i - 1)) && break
++      done
++
++      # We expect to exceed the maximum number of ACLs in a group, so that
++      # insertion eventually fails. Otherwise, the test should be adjusted to
++      # add more filters.
++      check_fail $ret "expected to exceed number of ACLs in a group"
++
++      for ((; i >= 1; i--)); do
++              if [[ $(( i % 2 )) == 1 ]]; then
++                      tc filter del dev $h2 ingress pref $i proto ipv4 \
++                              flower $tcflags dst_ip 198.51.100.1/32 \
++                              ip_proto tcp tcp_flags 0x01/0x01 \
++                              action drop &> /dev/null
++              else
++                      tc filter del dev $h2 ingress pref $i proto ipv6 \
++                              flower $tcflags dst_ip 2001:db8:1::1/128 \
++                              action drop &> /dev/null
++              fi
++      done
++
++      log_test "max ACL group size test ($tcflags). max size $max_size"
++}
++
+ setup_prepare()
+ {
+       h1=${NETIFS[p1]}
+-- 
+2.43.0
+
diff --git a/queue-6.6/mlxsw-spectrum_router-register-netdevice-notifier-be.patch b/queue-6.6/mlxsw-spectrum_router-register-netdevice-notifier-be.patch
new file mode 100644 (file)
index 0000000..910bbb7
--- /dev/null
@@ -0,0 +1,114 @@
+From 59f513d3387b7729ff740d3a2fc2f509622d1c57 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:19 +0100
+Subject: mlxsw: spectrum_router: Register netdevice notifier before nexthop
+
+From: Petr Machata <petrm@nvidia.com>
+
+[ Upstream commit 62bef63646c194e0f82b40304a0f2d060b28687b ]
+
+If there are IPIP nexthops at the time when the driver is loaded (or the
+devlink instance reloaded), the driver looks up the corresponding IPIP
+entry. But IPIP entries are only created as a result of netdevice
+notifications. Since the netdevice notifier is registered after the nexthop
+notifier, mlxsw_sp_nexthop_type_init() never finds the IPIP entry,
+registers the nexthop MLXSW_SP_NEXTHOP_TYPE_ETH, and fails to assign a CRIF
+to the nexthop. Later on when the CRIF is necessary, the WARN_ON in
+mlxsw_sp_nexthop_rif() triggers, causing the splat [1].
+
+In order to fix the issue, reorder the netdevice notifier to be registered
+before the nexthop one.
+
+[1] (edited for clarity):
+
+    WARNING: CPU: 1 PID: 1364 at drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3245 mlxsw_sp_nexthop_rif (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3246 (discriminator 1)) mlxsw_spectrum
+    Hardware name: Mellanox Technologies Ltd. MSN4410/VMOD0010, BIOS 5.11 01/06/2019
+    Call Trace:
+    ? mlxsw_sp_nexthop_rif (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3246 (discriminator 1)) mlxsw_spectrum
+    __mlxsw_sp_nexthop_eth_update (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3637) mlxsw_spectrum
+    mlxsw_sp_nexthop_update (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3679 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3727) mlxsw_spectrum
+    mlxsw_sp_nexthop_group_update (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:3757) mlxsw_spectrum
+    mlxsw_sp_nexthop_group_refresh (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:4112) mlxsw_spectrum
+    mlxsw_sp_nexthop_obj_event (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5118 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5191 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5315 drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:5500) mlxsw_spectrum
+    nexthops_dump (net/ipv4/nexthop.c:217 net/ipv4/nexthop.c:440 net/ipv4/nexthop.c:3609)
+    register_nexthop_notifier (net/ipv4/nexthop.c:3624)
+    mlxsw_sp_router_init (drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c:11486) mlxsw_spectrum
+    mlxsw_sp_init (drivers/net/ethernet/mellanox/mlxsw/spectrum.c:3267) mlxsw_spectrum
+    __mlxsw_core_bus_device_register (drivers/net/ethernet/mellanox/mlxsw/core.c:2202) mlxsw_core
+    mlxsw_devlink_core_bus_device_reload_up (drivers/net/ethernet/mellanox/mlxsw/core.c:2265 drivers/net/ethernet/mellanox/mlxsw/core.c:1603) mlxsw_core
+    devlink_reload (net/devlink/dev.c:314 net/devlink/dev.c:475)
+    [...]
+
+Fixes: 9464a3d68ea9 ("mlxsw: spectrum_router: Track next hops at CRIFs")
+Reported-by: Maksym Yaremchuk <maksymy@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/74edb8d45d004e8d8f5318eede6ccc3d786d8ba9.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/mellanox/mlxsw/spectrum_router.c | 24 +++++++++----------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index debd2c466f11..ae2fb9efbc50 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -11458,6 +11458,13 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_register_netevent_notifier;
++      mlxsw_sp->router->netdevice_nb.notifier_call =
++              mlxsw_sp_router_netdevice_event;
++      err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
++                                            &mlxsw_sp->router->netdevice_nb);
++      if (err)
++              goto err_register_netdev_notifier;
++
+       mlxsw_sp->router->nexthop_nb.notifier_call =
+               mlxsw_sp_nexthop_obj_event;
+       err = register_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
+@@ -11473,22 +11480,15 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp,
+       if (err)
+               goto err_register_fib_notifier;
+-      mlxsw_sp->router->netdevice_nb.notifier_call =
+-              mlxsw_sp_router_netdevice_event;
+-      err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
+-                                            &mlxsw_sp->router->netdevice_nb);
+-      if (err)
+-              goto err_register_netdev_notifier;
+-
+       return 0;
+-err_register_netdev_notifier:
+-      unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp),
+-                              &mlxsw_sp->router->fib_nb);
+ err_register_fib_notifier:
+       unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
+                                   &mlxsw_sp->router->nexthop_nb);
+ err_register_nexthop_notifier:
++      unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
++                                        &router->netdevice_nb);
++err_register_netdev_notifier:
+       unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb);
+ err_register_netevent_notifier:
+       unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb);
+@@ -11536,11 +11536,11 @@ void mlxsw_sp_router_fini(struct mlxsw_sp *mlxsw_sp)
+ {
+       struct mlxsw_sp_router *router = mlxsw_sp->router;
+-      unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
+-                                        &router->netdevice_nb);
+       unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), &router->fib_nb);
+       unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp),
+                                   &router->nexthop_nb);
++      unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp),
++                                        &router->netdevice_nb);
+       unregister_netevent_notifier(&router->netevent_nb);
+       unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb);
+       unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb);
+-- 
+2.43.0
+
diff --git a/queue-6.6/mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch b/queue-6.6/mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch
new file mode 100644 (file)
index 0000000..621254c
--- /dev/null
@@ -0,0 +1,77 @@
+From c05933565c5cf107c726e1bf55543f1227464bdd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:13 +0000
+Subject: mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 89e23277f9c16df6f9f9c1a1a07f8f132339c15c ]
+
+mptcp_parse_option() currently sets OPTIONS_MPTCP_MPJ, for the three
+possible cases handled for MPTCPOPT_MP_JOIN option.
+
+OPTIONS_MPTCP_MPJ is the combination of three flags:
+- OPTION_MPTCP_MPJ_SYN
+- OPTION_MPTCP_MPJ_SYNACK
+- OPTION_MPTCP_MPJ_ACK
+
+This is a problem, because backup, join_id, token, nonce and/or hmac fields
+could be left uninitialized in some cases.
+
+Distinguish the three cases, as following patches will need this step.
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/options.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c
+index c53914012d01..d2527d189a79 100644
+--- a/net/mptcp/options.c
++++ b/net/mptcp/options.c
+@@ -123,8 +123,8 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+               break;
+       case MPTCPOPT_MP_JOIN:
+-              mp_opt->suboptions |= OPTIONS_MPTCP_MPJ;
+               if (opsize == TCPOLEN_MPTCP_MPJ_SYN) {
++                      mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYN;
+                       mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP;
+                       mp_opt->join_id = *ptr++;
+                       mp_opt->token = get_unaligned_be32(ptr);
+@@ -135,6 +135,7 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+                                mp_opt->backup, mp_opt->join_id,
+                                mp_opt->token, mp_opt->nonce);
+               } else if (opsize == TCPOLEN_MPTCP_MPJ_SYNACK) {
++                      mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYNACK;
+                       mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP;
+                       mp_opt->join_id = *ptr++;
+                       mp_opt->thmac = get_unaligned_be64(ptr);
+@@ -145,11 +146,10 @@ static void mptcp_parse_option(const struct sk_buff *skb,
+                                mp_opt->backup, mp_opt->join_id,
+                                mp_opt->thmac, mp_opt->nonce);
+               } else if (opsize == TCPOLEN_MPTCP_MPJ_ACK) {
++                      mp_opt->suboptions |= OPTION_MPTCP_MPJ_ACK;
+                       ptr += 2;
+                       memcpy(mp_opt->hmac, ptr, MPTCPOPT_HMAC_LEN);
+                       pr_debug("MP_JOIN hmac");
+-              } else {
+-                      mp_opt->suboptions &= ~OPTIONS_MPTCP_MPJ;
+               }
+               break;
+-- 
+2.43.0
+
diff --git a/queue-6.6/mptcp-refine-opt_mp_capable-determination.patch b/queue-6.6/mptcp-refine-opt_mp_capable-determination.patch
new file mode 100644 (file)
index 0000000..e5aae5f
--- /dev/null
@@ -0,0 +1,80 @@
+From 929aae11c29698f57e347332b1808576ab0504d3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:17 +0000
+Subject: mptcp: refine opt_mp_capable determination
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 724b00c12957973656d312dce2a110c75ae2c680 ]
+
+OPTIONS_MPTCP_MPC is a combination of three flags.
+
+It would be better to be strict about testing what
+flag is expected, at least for code readability.
+
+mptcp_parse_option() already makes the distinction.
+
+- subflow_check_req() should use OPTION_MPTCP_MPC_SYN.
+
+- mptcp_subflow_init_cookie_req() should use OPTION_MPTCP_MPC_ACK.
+
+- subflow_finish_connect() should use OPTION_MPTCP_MPC_SYNACK
+
+- subflow_syn_recv_sock should use OPTION_MPTCP_MPC_ACK
+
+Suggested-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Fixes: 74c7dfbee3e1 ("mptcp: consolidate in_opt sub-options fields in a bitmask")
+Link: https://lore.kernel.org/r/20240111194917.4044654-6-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 93f43a5cce40..70b7a47a53c7 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -157,7 +157,7 @@ static int subflow_check_req(struct request_sock *req,
+       mptcp_get_options(skb, &mp_opt);
+-      opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
++      opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYN);
+       opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYN);
+       if (opt_mp_capable) {
+               SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
+@@ -254,7 +254,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+       subflow_init_req(req, sk_listener);
+       mptcp_get_options(skb, &mp_opt);
+-      opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
++      opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_ACK);
+       opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK);
+       if (opt_mp_capable && opt_mp_join)
+               return -EINVAL;
+@@ -486,7 +486,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+       mptcp_get_options(skb, &mp_opt);
+       if (subflow->request_mptcp) {
+-              if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) {
++              if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYNACK)) {
+                       MPTCP_INC_STATS(sock_net(sk),
+                                       MPTCP_MIB_MPCAPABLEACTIVEFALLBACK);
+                       mptcp_do_fallback(sk);
+@@ -783,7 +783,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+                * options.
+                */
+               mptcp_get_options(skb, &mp_opt);
+-              if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC))
++              if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_ACK))
+                       fallback = true;
+       } else if (subflow_req->mp_join) {
+-- 
+2.43.0
+
diff --git a/queue-6.6/mptcp-relax-check-on-mpc-passive-fallback.patch b/queue-6.6/mptcp-relax-check-on-mpc-passive-fallback.patch
new file mode 100644 (file)
index 0000000..ac9f71c
--- /dev/null
@@ -0,0 +1,42 @@
+From 36b51263de9de3d6101e7f6f74601eee94767d3b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jan 2024 18:18:47 +0100
+Subject: mptcp: relax check on MPC passive fallback
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit c0f5aec28edf98906d28f08daace6522adf9ee7a ]
+
+While testing the blamed commit below, I was able to miss (!)
+packetdrill failures in the fastopen test-cases.
+
+On passive fastopen the child socket is created by incoming TCP MPC syn,
+allow for both MPC_SYN and MPC_ACK header.
+
+Fixes: 724b00c12957 ("mptcp: refine opt_mp_capable determination")
+Reviewed-by: Matthieu Baerts <matttbe@kernel.org>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 70b7a47a53c7..d3c5ecf8ddf5 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -783,7 +783,8 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+                * options.
+                */
+               mptcp_get_options(skb, &mp_opt);
+-              if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_ACK))
++              if (!(mp_opt.suboptions &
++                    (OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_ACK)))
+                       fallback = true;
+       } else if (subflow_req->mp_join) {
+-- 
+2.43.0
+
diff --git a/queue-6.6/mptcp-strict-validation-before-using-mp_opt-hmac.patch b/queue-6.6/mptcp-strict-validation-before-using-mp_opt-hmac.patch
new file mode 100644 (file)
index 0000000..a4b1639
--- /dev/null
@@ -0,0 +1,47 @@
+From 16f8db293f0507486361beee36ce291a051872ce Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:14 +0000
+Subject: mptcp: strict validation before using mp_opt->hmac
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit c1665273bdc7c201766c65e561c06711f2e050dc ]
+
+mp_opt->hmac contains uninitialized data unless OPTION_MPTCP_MPJ_ACK
+was set in mptcp_parse_option().
+
+We must refine the condition before we call subflow_hmac_valid().
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 45b8115b363b..d6ee0e52ea41 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -788,7 +788,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
+       } else if (subflow_req->mp_join) {
+               mptcp_get_options(skb, &mp_opt);
+-              if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) ||
++              if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK) ||
+                   !subflow_hmac_valid(req, &mp_opt) ||
+                   !mptcp_can_accept_new_subflow(subflow_req->msk)) {
+                       SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
+-- 
+2.43.0
+
diff --git a/queue-6.6/mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch b/queue-6.6/mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch
new file mode 100644 (file)
index 0000000..d4d1100
--- /dev/null
@@ -0,0 +1,105 @@
+From 89d5908136718f5182aaf411cb791ca889ad0713 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:16 +0000
+Subject: mptcp: use OPTION_MPTCP_MPJ_SYN in subflow_check_req()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 66ff70df1a919a066942844bb095d6fcb748d78d ]
+
+syzbot reported that subflow_check_req() was using uninitialized data in
+subflow_check_req() [1]
+
+This is because mp_opt.token is only set when OPTION_MPTCP_MPJ_SYN is also set.
+
+While we are are it, fix mptcp_subflow_init_cookie_req()
+to test for OPTION_MPTCP_MPJ_ACK.
+
+[1]
+
+BUG: KMSAN: uninit-value in subflow_token_join_request net/mptcp/subflow.c:91 [inline]
+ BUG: KMSAN: uninit-value in subflow_check_req+0x1028/0x15d0 net/mptcp/subflow.c:209
+  subflow_token_join_request net/mptcp/subflow.c:91 [inline]
+  subflow_check_req+0x1028/0x15d0 net/mptcp/subflow.c:209
+  subflow_v6_route_req+0x269/0x410 net/mptcp/subflow.c:367
+  tcp_conn_request+0x153a/0x4240 net/ipv4/tcp_input.c:7164
+ subflow_v6_conn_request+0x3ee/0x510
+  tcp_rcv_state_process+0x2e1/0x4ac0 net/ipv4/tcp_input.c:6659
+  tcp_v6_do_rcv+0x11bf/0x1fe0 net/ipv6/tcp_ipv6.c:1669
+  tcp_v6_rcv+0x480b/0x4fb0 net/ipv6/tcp_ipv6.c:1900
+  ip6_protocol_deliver_rcu+0xda6/0x2a60 net/ipv6/ip6_input.c:438
+  ip6_input_finish net/ipv6/ip6_input.c:483 [inline]
+  NF_HOOK include/linux/netfilter.h:314 [inline]
+  ip6_input+0x15d/0x430 net/ipv6/ip6_input.c:492
+  dst_input include/net/dst.h:461 [inline]
+  ip6_rcv_finish+0x5db/0x870 net/ipv6/ip6_input.c:79
+  NF_HOOK include/linux/netfilter.h:314 [inline]
+  ipv6_rcv+0xda/0x390 net/ipv6/ip6_input.c:310
+  __netif_receive_skb_one_core net/core/dev.c:5532 [inline]
+  __netif_receive_skb+0x1a6/0x5a0 net/core/dev.c:5646
+  netif_receive_skb_internal net/core/dev.c:5732 [inline]
+  netif_receive_skb+0x58/0x660 net/core/dev.c:5791
+  tun_rx_batched+0x3ee/0x980 drivers/net/tun.c:1555
+  tun_get_user+0x53af/0x66d0 drivers/net/tun.c:2002
+  tun_chr_write_iter+0x3af/0x5d0 drivers/net/tun.c:2048
+  call_write_iter include/linux/fs.h:2020 [inline]
+  new_sync_write fs/read_write.c:491 [inline]
+  vfs_write+0x8ef/0x1490 fs/read_write.c:584
+  ksys_write+0x20f/0x4c0 fs/read_write.c:637
+  __do_sys_write fs/read_write.c:649 [inline]
+  __se_sys_write fs/read_write.c:646 [inline]
+  __x64_sys_write+0x93/0xd0 fs/read_write.c:646
+  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+  do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Local variable mp_opt created at:
+  subflow_check_req+0x6d/0x15d0 net/mptcp/subflow.c:145
+  subflow_v6_route_req+0x269/0x410 net/mptcp/subflow.c:367
+
+CPU: 1 PID: 5924 Comm: syz-executor.3 Not tainted 6.7.0-rc8-syzkaller-00055-g5eff55d725a4 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-5-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index 5b37fee2a85a..93f43a5cce40 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -158,7 +158,7 @@ static int subflow_check_req(struct request_sock *req,
+       mptcp_get_options(skb, &mp_opt);
+       opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
+-      opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ);
++      opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYN);
+       if (opt_mp_capable) {
+               SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE);
+@@ -255,7 +255,7 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
+       mptcp_get_options(skb, &mp_opt);
+       opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC);
+-      opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ);
++      opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK);
+       if (opt_mp_capable && opt_mp_join)
+               return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-6.6/mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch b/queue-6.6/mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch
new file mode 100644 (file)
index 0000000..441101e
--- /dev/null
@@ -0,0 +1,46 @@
+From 03b349650ec3f177dbde99cfd529819cd830361f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 19:49:15 +0000
+Subject: mptcp: use OPTION_MPTCP_MPJ_SYNACK in subflow_finish_connect()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit be1d9d9d38da922bd4beeec5b6dd821ff5a1dfeb ]
+
+subflow_finish_connect() uses four fields (backup, join_id, thmac, none)
+that may contain garbage unless OPTION_MPTCP_MPJ_SYNACK has been set
+in mptcp_parse_option()
+
+Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Florian Westphal <fw@strlen.de>
+Cc: Peter Krystad <peter.krystad@linux.intel.com>
+Cc: Matthieu Baerts <matttbe@kernel.org>
+Cc: Mat Martineau <martineau@kernel.org>
+Cc: Geliang Tang <geliang.tang@linux.dev>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Link: https://lore.kernel.org/r/20240111194917.4044654-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/mptcp/subflow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
+index d6ee0e52ea41..5b37fee2a85a 100644
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -506,7 +506,7 @@ static void subflow_finish_connect(struct sock *sk, const struct sk_buff *skb)
+       } else if (subflow->request_join) {
+               u8 hmac[SHA256_DIGEST_SIZE];
+-              if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ)) {
++              if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYNACK)) {
+                       subflow->reset_reason = MPTCP_RST_EMPTCP;
+                       goto do_reset;
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-add-more-sanity-check-in-virtio_net_hdr_to_skb.patch b/queue-6.6/net-add-more-sanity-check-in-virtio_net_hdr_to_skb.patch
new file mode 100644 (file)
index 0000000..1e9e7b2
--- /dev/null
@@ -0,0 +1,136 @@
+From e37f0c0aca4ee9b703af0a6f7cc5cbb7c6525cfe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 12:28:16 +0000
+Subject: net: add more sanity check in virtio_net_hdr_to_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 9181d6f8a2bb32d158de66a84164fac05e3ddd18 ]
+
+syzbot/KMSAN reports access to uninitialized data from gso_features_check() [1]
+
+The repro use af_packet, injecting a gso packet and hdrlen == 0.
+
+We could fix the issue making gso_features_check() more careful
+while dealing with NETIF_F_TSO_MANGLEID in fast path.
+
+Or we can make sure virtio_net_hdr_to_skb() pulls minimal network and
+transport headers as intended.
+
+Note that for GSO packets coming from untrusted sources, SKB_GSO_DODGY
+bit forces a proper header validation (and pull) before the packet can
+hit any device ndo_start_xmit(), thus we do not need a precise disection
+at virtio_net_hdr_to_skb() stage.
+
+[1]
+BUG: KMSAN: uninit-value in skb_gso_segment include/net/gso.h:83 [inline]
+BUG: KMSAN: uninit-value in validate_xmit_skb+0x10f2/0x1930 net/core/dev.c:3629
+ skb_gso_segment include/net/gso.h:83 [inline]
+ validate_xmit_skb+0x10f2/0x1930 net/core/dev.c:3629
+ __dev_queue_xmit+0x1eac/0x5130 net/core/dev.c:4341
+ dev_queue_xmit include/linux/netdevice.h:3134 [inline]
+ packet_xmit+0x9c/0x6b0 net/packet/af_packet.c:276
+ packet_snd net/packet/af_packet.c:3087 [inline]
+ packet_sendmsg+0x8b1d/0x9f30 net/packet/af_packet.c:3119
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg net/socket.c:745 [inline]
+ ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2584
+ ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2638
+ __sys_sendmsg net/socket.c:2667 [inline]
+ __do_sys_sendmsg net/socket.c:2676 [inline]
+ __se_sys_sendmsg net/socket.c:2674 [inline]
+ __x64_sys_sendmsg+0x307/0x490 net/socket.c:2674
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+Uninit was created at:
+ slab_post_alloc_hook+0x129/0xa70 mm/slab.h:768
+ slab_alloc_node mm/slub.c:3478 [inline]
+ kmem_cache_alloc_node+0x5e9/0xb10 mm/slub.c:3523
+ kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:560
+ __alloc_skb+0x318/0x740 net/core/skbuff.c:651
+ alloc_skb include/linux/skbuff.h:1286 [inline]
+ alloc_skb_with_frags+0xc8/0xbd0 net/core/skbuff.c:6334
+ sock_alloc_send_pskb+0xa80/0xbf0 net/core/sock.c:2780
+ packet_alloc_skb net/packet/af_packet.c:2936 [inline]
+ packet_snd net/packet/af_packet.c:3030 [inline]
+ packet_sendmsg+0x70e8/0x9f30 net/packet/af_packet.c:3119
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg net/socket.c:745 [inline]
+ ____sys_sendmsg+0x9c2/0xd60 net/socket.c:2584
+ ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2638
+ __sys_sendmsg net/socket.c:2667 [inline]
+ __do_sys_sendmsg net/socket.c:2676 [inline]
+ __se_sys_sendmsg net/socket.c:2674 [inline]
+ __x64_sys_sendmsg+0x307/0x490 net/socket.c:2674
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+CPU: 0 PID: 5025 Comm: syz-executor279 Not tainted 6.7.0-rc7-syzkaller-00003-gfbafc3e621c3 #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023
+
+Reported-by: syzbot+7f4d0ea3df4d4fa9a65f@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/netdev/0000000000005abd7b060eb160cd@google.com/
+Fixes: 9274124f023b ("net: stricter validation of untrusted gso packets")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Cc: Willem de Bruijn <willemb@google.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/virtio_net.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
+index 27cc1d464321..4dfa9b69ca8d 100644
+--- a/include/linux/virtio_net.h
++++ b/include/linux/virtio_net.h
+@@ -3,6 +3,8 @@
+ #define _LINUX_VIRTIO_NET_H
+ #include <linux/if_vlan.h>
++#include <linux/ip.h>
++#include <linux/ipv6.h>
+ #include <linux/udp.h>
+ #include <uapi/linux/tcp.h>
+ #include <uapi/linux/virtio_net.h>
+@@ -49,6 +51,7 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
+                                       const struct virtio_net_hdr *hdr,
+                                       bool little_endian)
+ {
++      unsigned int nh_min_len = sizeof(struct iphdr);
+       unsigned int gso_type = 0;
+       unsigned int thlen = 0;
+       unsigned int p_off = 0;
+@@ -65,6 +68,7 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
+                       gso_type = SKB_GSO_TCPV6;
+                       ip_proto = IPPROTO_TCP;
+                       thlen = sizeof(struct tcphdr);
++                      nh_min_len = sizeof(struct ipv6hdr);
+                       break;
+               case VIRTIO_NET_HDR_GSO_UDP:
+                       gso_type = SKB_GSO_UDP;
+@@ -100,7 +104,8 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
+               if (!skb_partial_csum_set(skb, start, off))
+                       return -EINVAL;
+-              p_off = skb_transport_offset(skb) + thlen;
++              nh_min_len = max_t(u32, nh_min_len, skb_transport_offset(skb));
++              p_off = nh_min_len + thlen;
+               if (!pskb_may_pull(skb, p_off))
+                       return -EINVAL;
+       } else {
+@@ -140,7 +145,7 @@ static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
+                       skb_set_transport_header(skb, keys.control.thoff);
+               } else if (gso_type) {
+-                      p_off = thlen;
++                      p_off = nh_min_len + thlen;
+                       if (!pskb_may_pull(skb, p_off))
+                               return -EINVAL;
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch b/queue-6.6/net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch
new file mode 100644 (file)
index 0000000..4543ba3
--- /dev/null
@@ -0,0 +1,39 @@
+From 368e88bd55e152b47026c357ae31c0e148e82209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 15:20:18 +0800
+Subject: net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 776dac5a662774f07a876b650ba578d0a62d20db ]
+
+devm_kasprintf() returns a pointer to dynamically allocated memory
+which can be NULL upon failure.
+
+Fixes: 05bd97fc559d ("net: dsa: Add Vitesse VSC73xx DSA router driver")
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Suggested-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240111072018.75971-1-chentao@kylinos.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/dsa/vitesse-vsc73xx-core.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c
+index 4f09e7438f3b..c99fb1bd4c25 100644
+--- a/drivers/net/dsa/vitesse-vsc73xx-core.c
++++ b/drivers/net/dsa/vitesse-vsc73xx-core.c
+@@ -1118,6 +1118,8 @@ static int vsc73xx_gpio_probe(struct vsc73xx *vsc)
+       vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x",
+                                      vsc->chipid);
++      if (!vsc->gc.label)
++              return -ENOMEM;
+       vsc->gc.ngpio = 4;
+       vsc->gc.owner = THIS_MODULE;
+       vsc->gc.parent = vsc->dev;
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch b/queue-6.6/net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch
new file mode 100644 (file)
index 0000000..c16c42f
--- /dev/null
@@ -0,0 +1,63 @@
+From 0b8903a6fd15648cd4e543b6b3c50b3239d9948a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 08:55:43 +0000
+Subject: net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sanjuán García, Jorge <Jorge.SanjuanGarcia@duagon.com>
+
+[ Upstream commit 64e47d8afb5ca533b27efc006405e5bcae2c4a7b ]
+
+The value of AM65_CPSW_MAX_PACKET_SIZE represents the maximum length
+of a received frame. This value is written to the register
+AM65_CPSW_PORT_REG_RX_MAXLEN.
+
+The maximum MTU configured on the network device should then leave
+some room for the ethernet headers and frame check. Otherwise, if
+the network interface is configured to its maximum mtu possible,
+the frames will be larger than AM65_CPSW_MAX_PACKET_SIZE and will
+get dropped as oversized.
+
+The switch supports ethernet frame sizes between 64 and 2024 bytes
+(including VLAN) as stated in the technical reference manual, so
+define AM65_CPSW_MAX_PACKET_SIZE with that maximum size.
+
+Fixes: 93a76530316a ("net: ethernet: ti: introduce am65x/j721e gigabit eth subsystem driver")
+Signed-off-by: Jorge Sanjuan Garcia <jorge.sanjuangarcia@duagon.com>
+Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Link: https://lore.kernel.org/r/20240105085530.14070-2-jorge.sanjuangarcia@duagon.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ti/am65-cpsw-nuss.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+index 24120605502f..c62b0f99f2bc 100644
+--- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c
++++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c
+@@ -56,7 +56,7 @@
+ #define AM65_CPSW_MAX_PORTS   8
+ #define AM65_CPSW_MIN_PACKET_SIZE     VLAN_ETH_ZLEN
+-#define AM65_CPSW_MAX_PACKET_SIZE     (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
++#define AM65_CPSW_MAX_PACKET_SIZE     2024
+ #define AM65_CPSW_REG_CTL             0x004
+ #define AM65_CPSW_REG_STAT_PORT_EN    0x014
+@@ -2167,7 +2167,8 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx)
+       eth_hw_addr_set(port->ndev, port->slave.mac_addr);
+       port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE;
+-      port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE;
++      port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE -
++                            (VLAN_ETH_HLEN + ETH_FCS_LEN);
+       port->ndev->hw_features = NETIF_F_SG |
+                                 NETIF_F_RXCSUM |
+                                 NETIF_F_HW_CSUM |
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-micrel-fix-ptp-frame-parsing-for-lan8841.patch b/queue-6.6/net-micrel-fix-ptp-frame-parsing-for-lan8841.patch
new file mode 100644 (file)
index 0000000..b7b7ff1
--- /dev/null
@@ -0,0 +1,60 @@
+From 3b550d9fb24820dcc0d5520eba015efb98a4a32a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 12:37:30 +0100
+Subject: net: micrel: Fix PTP frame parsing for lan8841
+
+From: Horatiu Vultur <horatiu.vultur@microchip.com>
+
+[ Upstream commit acd66c2126eb9b5da2d89ae07dbcd73b909c2111 ]
+
+The HW has the capability to check each frame if it is a PTP frame,
+which domain it is, which ptp frame type it is, different ip address in
+the frame. And if one of these checks fail then the frame is not
+timestamp. Most of these checks were disabled except checking the field
+minorVersionPTP inside the PTP header. Meaning that once a partner sends
+a frame compliant to 8021AS which has minorVersionPTP set to 1, then the
+frame was not timestamp because the HW expected by default a value of 0
+in minorVersionPTP.
+Fix this issue by removing this check so the userspace can decide on this.
+
+Fixes: cafc3662ee3f ("net: micrel: Add PHC support for lan8841")
+Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
+Reviewed-by: Divya Koppera <divya.koppera@microchip.com>
+Reviewed-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index 927d3d54658e..a345d02a9edf 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -3313,8 +3313,10 @@ static int lan8814_probe(struct phy_device *phydev)
+ #define LAN8841_ADC_CHANNEL_MASK              198
+ #define LAN8841_PTP_RX_PARSE_L2_ADDR_EN               370
+ #define LAN8841_PTP_RX_PARSE_IP_ADDR_EN               371
++#define LAN8841_PTP_RX_VERSION                        374
+ #define LAN8841_PTP_TX_PARSE_L2_ADDR_EN               434
+ #define LAN8841_PTP_TX_PARSE_IP_ADDR_EN               435
++#define LAN8841_PTP_TX_VERSION                        438
+ #define LAN8841_PTP_CMD_CTL                   256
+ #define LAN8841_PTP_CMD_CTL_PTP_ENABLE                BIT(2)
+ #define LAN8841_PTP_CMD_CTL_PTP_DISABLE               BIT(1)
+@@ -3358,6 +3360,12 @@ static int lan8841_config_init(struct phy_device *phydev)
+       phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
+                     LAN8841_PTP_RX_PARSE_IP_ADDR_EN, 0);
++      /* Disable checking for minorVersionPTP field */
++      phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
++                    LAN8841_PTP_RX_VERSION, 0xff00);
++      phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG,
++                    LAN8841_PTP_TX_VERSION, 0xff00);
++
+       /* 100BT Clause 40 improvenent errata */
+       phy_write_mmd(phydev, LAN8841_MMD_ANALOG_REG,
+                     LAN8841_ANALOG_CONTROL_1,
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-netdev_queue-netdev_txq_completed_mb-fix-wake-co.patch b/queue-6.6/net-netdev_queue-netdev_txq_completed_mb-fix-wake-co.patch
new file mode 100644 (file)
index 0000000..f98f29f
--- /dev/null
@@ -0,0 +1,39 @@
+From 9a463af849ced9f31bc5566d920869951b7c4689 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 17:13:14 +0100
+Subject: net: netdev_queue: netdev_txq_completed_mb(): fix wake condition
+
+From: Marc Kleine-Budde <mkl@pengutronix.de>
+
+[ Upstream commit 894d7508316e7ad722df597d68b4b1797a9eee11 ]
+
+netif_txq_try_stop() uses "get_desc >= start_thrs" as the check for
+the call to netif_tx_start_queue().
+
+Use ">=" i netdev_txq_completed_mb(), too.
+
+Fixes: c91c46de6bbc ("net: provide macros for commonly copied lockless queue stop/wake code")
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Acked-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/netdev_queues.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
+index d68b0a483431..8b8ed4e13d74 100644
+--- a/include/net/netdev_queues.h
++++ b/include/net/netdev_queues.h
+@@ -128,7 +128,7 @@ netdev_txq_completed_mb(struct netdev_queue *dev_queue,
+               netdev_txq_completed_mb(txq, pkts, bytes);              \
+                                                                       \
+               _res = -1;                                              \
+-              if (pkts && likely(get_desc > start_thrs)) {            \
++              if (pkts && likely(get_desc >= start_thrs)) {           \
+                       _res = 1;                                       \
+                       if (unlikely(netif_tx_queue_stopped(txq)) &&    \
+                           !(down_cond)) {                             \
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-netdevsim-don-t-try-to-destroy-phc-on-vfs.patch b/queue-6.6/net-netdevsim-don-t-try-to-destroy-phc-on-vfs.patch
new file mode 100644 (file)
index 0000000..db04722
--- /dev/null
@@ -0,0 +1,76 @@
+From 2cd39d0e812121e9b68e70e634d47f2fd2656320 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Jan 2024 11:14:00 -0800
+Subject: net: netdevsim: don't try to destroy PHC on VFs
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit ea937f77208323d35ffe2f8d8fc81b00118bfcda ]
+
+PHC gets initialized in nsim_init_netdevsim(), which
+is only called if (nsim_dev_port_is_pf()).
+
+Create a counterpart of nsim_init_netdevsim() and
+move the mock_phc_destroy() there.
+
+This fixes a crash trying to destroy netdevsim with
+VFs instantiated, as caught by running the devlink.sh test:
+
+    BUG: kernel NULL pointer dereference, address: 00000000000000b8
+    RIP: 0010:mock_phc_destroy+0xd/0x30
+    Call Trace:
+     <TASK>
+     nsim_destroy+0x4a/0x70 [netdevsim]
+     __nsim_dev_port_del+0x47/0x70 [netdevsim]
+     nsim_dev_reload_destroy+0x105/0x120 [netdevsim]
+     nsim_drv_remove+0x2f/0xb0 [netdevsim]
+     device_release_driver_internal+0x1a1/0x210
+     bus_remove_device+0xd5/0x120
+     device_del+0x159/0x490
+     device_unregister+0x12/0x30
+     del_device_store+0x11a/0x1a0 [netdevsim]
+     kernfs_fop_write_iter+0x130/0x1d0
+     vfs_write+0x30b/0x4b0
+     ksys_write+0x69/0xf0
+     do_syscall_64+0xcc/0x1e0
+     entry_SYSCALL_64_after_hwframe+0x6f/0x77
+
+Fixes: b63e78fca889 ("net: netdevsim: use mock PHC driver")
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/netdevsim/netdev.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c
+index 2eac92f49631..d8ca82addfe1 100644
+--- a/drivers/net/netdevsim/netdev.c
++++ b/drivers/net/netdevsim/netdev.c
+@@ -369,6 +369,12 @@ static int nsim_init_netdevsim_vf(struct netdevsim *ns)
+       return err;
+ }
++static void nsim_exit_netdevsim(struct netdevsim *ns)
++{
++      nsim_udp_tunnels_info_destroy(ns->netdev);
++      mock_phc_destroy(ns->phc);
++}
++
+ struct netdevsim *
+ nsim_create(struct nsim_dev *nsim_dev, struct nsim_dev_port *nsim_dev_port)
+ {
+@@ -417,8 +423,7 @@ void nsim_destroy(struct netdevsim *ns)
+       }
+       rtnl_unlock();
+       if (nsim_dev_port_is_pf(ns->nsim_dev_port))
+-              nsim_udp_tunnels_info_destroy(dev);
+-      mock_phc_destroy(ns->phc);
++              nsim_exit_netdevsim(ns);
+       free_netdev(dev);
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-phy-micrel-populate-.soft_reset-for-ksz9131.patch b/queue-6.6/net-phy-micrel-populate-.soft_reset-for-ksz9131.patch
new file mode 100644 (file)
index 0000000..63067bd
--- /dev/null
@@ -0,0 +1,100 @@
+From e9dd177f30815d4d83cf8413f27e804e93cffa46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 10:52:42 +0200
+Subject: net: phy: micrel: populate .soft_reset for KSZ9131
+
+From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+
+[ Upstream commit e398822c4751017fe401f57409488f5948d12fb5 ]
+
+The RZ/G3S SMARC Module has 2 KSZ9131 PHYs. In this setup, the KSZ9131 PHY
+is used with the ravb Ethernet driver. It has been discovered that when
+bringing the Ethernet interface down/up continuously, e.g., with the
+following sh script:
+
+$ while :; do ifconfig eth0 down; ifconfig eth0 up; done
+
+the link speed and duplex are wrong after interrupting the bring down/up
+operation even though the Ethernet interface is up. To recover from this
+state the following configuration sequence is necessary (executed
+manually):
+
+$ ifconfig eth0 down
+$ ifconfig eth0 up
+
+The behavior has been identified also on the Microchip SAMA7G5-EK board
+which runs the macb driver and uses the same PHY.
+
+The order of PHY-related operations in ravb_open() is as follows:
+ravb_open() ->
+  ravb_phy_start() ->
+    ravb_phy_init() ->
+      of_phy_connect() ->
+        phy_connect_direct() ->
+         phy_attach_direct() ->
+           phy_init_hw() ->
+             phydev->drv->soft_reset()
+             phydev->drv->config_init()
+             phydev->drv->config_intr()
+           phy_resume()
+             kszphy_resume()
+
+The order of PHY-related operations in ravb_close is as follows:
+ravb_close() ->
+  phy_stop() ->
+    phy_suspend() ->
+      kszphy_suspend() ->
+        genphy_suspend()
+         // set BMCR_PDOWN bit in MII_BMCR
+
+In genphy_suspend() setting the BMCR_PDWN bit in MII_BMCR switches the PHY
+to Software Power-Down (SPD) mode (according to the KSZ9131 datasheet).
+Thus, when opening the interface after it has been  previously closed (via
+ravb_close()), the phydev->drv->config_init() and
+phydev->drv->config_intr() reach the KSZ9131 PHY driver via the
+ksz9131_config_init() and kszphy_config_intr() functions.
+
+KSZ9131 specifies that the MII management interface remains operational
+during SPD (Software Power-Down), but (according to manual):
+- Only access to the standard registers (0 through 31) is supported.
+- Access to MMD address spaces other than MMD address space 1 is possible
+  if the spd_clock_gate_override bit is set.
+- Access to MMD address space 1 is not possible.
+
+The spd_clock_gate_override bit is not used in the KSZ9131 driver.
+
+ksz9131_config_init() configures RGMII delay, pad skews and LEDs by
+accessesing MMD registers other than those in address space 1.
+
+The datasheet for the KSZ9131 does not specify what happens if registers
+from an unsupported address space are accessed while the PHY is in SPD.
+
+To fix the issue the .soft_reset method has been instantiated for KSZ9131,
+too. This resets the PHY to the default state before doing any
+configurations to it, thus switching it out of SPD.
+
+Fixes: bff5b4b37372 ("net: phy: micrel: add Microchip KSZ9131 initial driver")
+Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
+Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/micrel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
+index a345d02a9edf..dfd5f8e78e29 100644
+--- a/drivers/net/phy/micrel.c
++++ b/drivers/net/phy/micrel.c
+@@ -4828,6 +4828,7 @@ static struct phy_driver ksphy_driver[] = {
+       .flags          = PHY_POLL_CABLE_TEST,
+       .driver_data    = &ksz9131_type,
+       .probe          = kszphy_probe,
++      .soft_reset     = genphy_soft_reset,
+       .config_init    = ksz9131_config_init,
+       .config_intr    = kszphy_config_intr,
+       .config_aneg    = ksz9131_config_aneg,
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch b/queue-6.6/net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch
new file mode 100644 (file)
index 0000000..cf24750
--- /dev/null
@@ -0,0 +1,105 @@
+From 1a85335efc1df0364321fe2707d637062346bd43 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 14:14:00 +0800
+Subject: net: qualcomm: rmnet: fix global oob in rmnet_policy
+
+From: Lin Ma <linma@zju.edu.cn>
+
+[ Upstream commit b33fb5b801c6db408b774a68e7c8722796b59ecc ]
+
+The variable rmnet_link_ops assign a *bigger* maxtype which leads to a
+global out-of-bounds read when parsing the netlink attributes. See bug
+trace below:
+
+==================================================================
+BUG: KASAN: global-out-of-bounds in validate_nla lib/nlattr.c:386 [inline]
+BUG: KASAN: global-out-of-bounds in __nla_validate_parse+0x24af/0x2750 lib/nlattr.c:600
+Read of size 1 at addr ffffffff92c438d0 by task syz-executor.6/84207
+
+CPU: 0 PID: 84207 Comm: syz-executor.6 Tainted: G                 N 6.1.0 #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:88 [inline]
+ dump_stack_lvl+0x8b/0xb3 lib/dump_stack.c:106
+ print_address_description mm/kasan/report.c:284 [inline]
+ print_report+0x172/0x475 mm/kasan/report.c:395
+ kasan_report+0xbb/0x1c0 mm/kasan/report.c:495
+ validate_nla lib/nlattr.c:386 [inline]
+ __nla_validate_parse+0x24af/0x2750 lib/nlattr.c:600
+ __nla_parse+0x3e/0x50 lib/nlattr.c:697
+ nla_parse_nested_deprecated include/net/netlink.h:1248 [inline]
+ __rtnl_newlink+0x50a/0x1880 net/core/rtnetlink.c:3485
+ rtnl_newlink+0x64/0xa0 net/core/rtnetlink.c:3594
+ rtnetlink_rcv_msg+0x43c/0xd70 net/core/rtnetlink.c:6091
+ netlink_rcv_skb+0x14f/0x410 net/netlink/af_netlink.c:2540
+ netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
+ netlink_unicast+0x54e/0x800 net/netlink/af_netlink.c:1345
+ netlink_sendmsg+0x930/0xe50 net/netlink/af_netlink.c:1921
+ sock_sendmsg_nosec net/socket.c:714 [inline]
+ sock_sendmsg+0x154/0x190 net/socket.c:734
+ ____sys_sendmsg+0x6df/0x840 net/socket.c:2482
+ ___sys_sendmsg+0x110/0x1b0 net/socket.c:2536
+ __sys_sendmsg+0xf3/0x1c0 net/socket.c:2565
+ do_syscall_x64 arch/x86/entry/common.c:50 [inline]
+ do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80
+ entry_SYSCALL_64_after_hwframe+0x63/0xcd
+RIP: 0033:0x7fdcf2072359
+Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 f1 19 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
+RSP: 002b:00007fdcf13e3168 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+RAX: ffffffffffffffda RBX: 00007fdcf219ff80 RCX: 00007fdcf2072359
+RDX: 0000000000000000 RSI: 0000000020000200 RDI: 0000000000000003
+RBP: 00007fdcf20bd493 R08: 0000000000000000 R09: 0000000000000000
+R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+R13: 00007fffbb8d7bdf R14: 00007fdcf13e3300 R15: 0000000000022000
+ </TASK>
+
+The buggy address belongs to the variable:
+ rmnet_policy+0x30/0xe0
+
+The buggy address belongs to the physical page:
+page:0000000065bdeb3c refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x155243
+flags: 0x200000000001000(reserved|node=0|zone=2)
+raw: 0200000000001000 ffffea00055490c8 ffffea00055490c8 0000000000000000
+raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
+page dumped because: kasan: bad access detected
+
+Memory state around the buggy address:
+ ffffffff92c43780: f9 f9 f9 f9 00 00 00 02 f9 f9 f9 f9 00 00 00 07
+ ffffffff92c43800: f9 f9 f9 f9 00 00 00 05 f9 f9 f9 f9 06 f9 f9 f9
+>ffffffff92c43880: f9 f9 f9 f9 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9
+                                                 ^
+ ffffffff92c43900: 00 00 00 00 00 00 00 00 07 f9 f9 f9 f9 f9 f9 f9
+ ffffffff92c43980: 00 00 00 07 f9 f9 f9 f9 00 00 00 05 f9 f9 f9 f9
+
+According to the comment of `nla_parse_nested_deprecated`, the maxtype
+should be len(destination array) - 1. Hence use `IFLA_RMNET_MAX` here.
+
+Fixes: 14452ca3b5ce ("net: qualcomm: rmnet: Export mux_id and flags to netlink")
+Signed-off-by: Lin Ma <linma@zju.edu.cn>
+Reviewed-by: Subash Abhinov Kasiviswanathan <quic_subashab@quicinc.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://lore.kernel.org/r/20240110061400.3356108-1-linma@zju.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+index 39d24e07f306..5b69b9268c75 100644
+--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c
+@@ -396,7 +396,7 @@ static int rmnet_fill_info(struct sk_buff *skb, const struct net_device *dev)
+ struct rtnl_link_ops rmnet_link_ops __read_mostly = {
+       .kind           = "rmnet",
+-      .maxtype        = __IFLA_RMNET_MAX,
++      .maxtype        = IFLA_RMNET_MAX,
+       .priv_size      = sizeof(struct rmnet_priv),
+       .setup          = rmnet_vnd_setup,
+       .validate       = rmnet_rtnl_validate,
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-ravb-fix-dma_addr_t-truncation-in-error-case.patch b/queue-6.6/net-ravb-fix-dma_addr_t-truncation-in-error-case.patch
new file mode 100644 (file)
index 0000000..4444b44
--- /dev/null
@@ -0,0 +1,53 @@
+From d80096ae1e8628a25c203820db680e90736e0c27 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 13 Jan 2024 10:22:21 +0600
+Subject: net: ravb: Fix dma_addr_t truncation in error case
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+
+[ Upstream commit e327b2372bc0f18c30433ac40be07741b59231c5 ]
+
+In ravb_start_xmit(), ravb driver uses u32 variable to store result of
+dma_map_single() call. Since ravb hardware has 32-bit address fields in
+descriptors, this works properly when mapping is successful - it is
+platform's job to provide mapping addresses that fit into hardware
+limitations.
+
+However, in failure case dma_map_single() returns DMA_MAPPING_ERROR
+constant that is 64-bit when dma_addr_t is 64-bit. Storing this constant
+in u32 leads to truncation, and further call to dma_mapping_error()
+fails to notice the error.
+
+Fix that by storing result of dma_map_single() in a dma_addr_t
+variable.
+
+Fixes: c156633f1353 ("Renesas Ethernet AVB driver proper")
+Signed-off-by: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
+Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
+Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/renesas/ravb_main.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
+index 3c2a6b23c202..8fec0dbbbe7b 100644
+--- a/drivers/net/ethernet/renesas/ravb_main.c
++++ b/drivers/net/ethernet/renesas/ravb_main.c
+@@ -1949,7 +1949,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+       struct ravb_tstamp_skb *ts_skb;
+       struct ravb_tx_desc *desc;
+       unsigned long flags;
+-      u32 dma_addr;
++      dma_addr_t dma_addr;
+       void *buffer;
+       u32 entry;
+       u32 len;
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch b/queue-6.6/net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch
new file mode 100644 (file)
index 0000000..8a27cf9
--- /dev/null
@@ -0,0 +1,105 @@
+From 3fc043ca2e5e2d6e3aaa804c983c490468a1ae63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 10:12:49 +0800
+Subject: net: stmmac: ethtool: Fixed calltrace caused by unbalanced
+ disable_irq_wake calls
+
+From: Qiang Ma <maqianga@uniontech.com>
+
+[ Upstream commit a23aa04042187cbde16f470b49d4ad60d32e9206 ]
+
+We found the following dmesg calltrace when testing the GMAC NIC notebook:
+
+[9.448656] ------------[ cut here ]------------
+[9.448658] Unbalanced IRQ 43 wake disable
+[9.448673] WARNING: CPU: 3 PID: 1083 at kernel/irq/manage.c:688 irq_set_irq_wake+0xe0/0x128
+[9.448717] CPU: 3 PID: 1083 Comm: ethtool Tainted: G           O      4.19 #1
+[9.448773]         ...
+[9.448774] Call Trace:
+[9.448781] [<9000000000209b5c>] show_stack+0x34/0x140
+[9.448788] [<9000000000d52700>] dump_stack+0x98/0xd0
+[9.448794] [<9000000000228610>] __warn+0xa8/0x120
+[9.448797] [<9000000000d2fb60>] report_bug+0x98/0x130
+[9.448800] [<900000000020a418>] do_bp+0x248/0x2f0
+[9.448805] [<90000000002035f4>] handle_bp_int+0x4c/0x78
+[9.448808] [<900000000029ea40>] irq_set_irq_wake+0xe0/0x128
+[9.448813] [<9000000000a96a7c>] stmmac_set_wol+0x134/0x150
+[9.448819] [<9000000000be6ed0>] dev_ethtool+0x1368/0x2440
+[9.448824] [<9000000000c08350>] dev_ioctl+0x1f8/0x3e0
+[9.448827] [<9000000000bb2a34>] sock_ioctl+0x2a4/0x450
+[9.448832] [<900000000046f044>] do_vfs_ioctl+0xa4/0x738
+[9.448834] [<900000000046f778>] ksys_ioctl+0xa0/0xe8
+[9.448837] [<900000000046f7d8>] sys_ioctl+0x18/0x28
+[9.448840] [<9000000000211ab4>] syscall_common+0x20/0x34
+[9.448842] ---[ end trace 40c18d9aec863c3e ]---
+
+Multiple disable_irq_wake() calls will keep decreasing the IRQ
+wake_depth, When wake_depth is 0, calling disable_irq_wake() again,
+will report the above calltrace.
+
+Due to the need to appear in pairs, we cannot call disable_irq_wake()
+without calling enable_irq_wake(). Fix this by making sure there are
+no unbalanced disable_irq_wake() calls.
+
+Fixes: 3172d3afa998 ("stmmac: support wake up irq from external sources (v3)")
+Signed-off-by: Qiang Ma <maqianga@uniontech.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240112021249.24598-1-maqianga@uniontech.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h         |  1 +
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 10 ++++++++--
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c    |  1 +
+ 3 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+index cd7a9768de5f..b8c93b881a65 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -255,6 +255,7 @@ struct stmmac_priv {
+       u32 msg_enable;
+       int wolopts;
+       int wol_irq;
++      bool wol_irq_disabled;
+       int clk_csr;
+       struct timer_list eee_ctrl_timer;
+       int lpi_irq;
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index 419efe43951e..69c8c2528524 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -822,10 +822,16 @@ static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+       if (wol->wolopts) {
+               pr_info("stmmac: wakeup enable\n");
+               device_set_wakeup_enable(priv->device, 1);
+-              enable_irq_wake(priv->wol_irq);
++              /* Avoid unbalanced enable_irq_wake calls */
++              if (priv->wol_irq_disabled)
++                      enable_irq_wake(priv->wol_irq);
++              priv->wol_irq_disabled = false;
+       } else {
+               device_set_wakeup_enable(priv->device, 0);
+-              disable_irq_wake(priv->wol_irq);
++              /* Avoid unbalanced disable_irq_wake calls */
++              if (!priv->wol_irq_disabled)
++                      disable_irq_wake(priv->wol_irq);
++              priv->wol_irq_disabled = true;
+       }
+       mutex_lock(&priv->lock);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 69b9c71f0ede..1bfcf673b3ce 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -3549,6 +3549,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
+       /* Request the Wake IRQ in case of another line
+        * is used for WoL
+        */
++      priv->wol_irq_disabled = true;
+       if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) {
+               int_name = priv->int_name_wol;
+               sprintf(int_name, "%s:%s", dev->name, "wol");
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-stmmac-fix-ethool-link-settings-ops-for-integrat.patch b/queue-6.6/net-stmmac-fix-ethool-link-settings-ops-for-integrat.patch
new file mode 100644 (file)
index 0000000..1d13fae
--- /dev/null
@@ -0,0 +1,54 @@
+From 6a06bfc5608c38525e696b3fe36b640a0d9b5aeb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 20:17:29 +0530
+Subject: net: stmmac: Fix ethool link settings ops for integrated PCS
+
+From: Sneh Shah <quic_snehshah@quicinc.com>
+
+[ Upstream commit 08300adac3b8dab9e2fd3be0155c7d3093c755f4 ]
+
+Currently get/set_link_ksettings ethtool ops are dependent on PCS.
+When PCS is integrated, it will not have separate link config.
+Bypass configuring and checking PCS for integrated PCS.
+
+Fixes: aa571b6275fb ("net: stmmac: add new switch to struct plat_stmmacenet_data")
+Tested-by: Andrew Halaney <ahalaney@redhat.com> # sa8775p-ride
+Signed-off-by: Sneh Shah <quic_snehshah@quicinc.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+index aea5f898ebf4..419efe43951e 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -311,8 +311,9 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev,
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
+-      if (priv->hw->pcs & STMMAC_PCS_RGMII ||
+-          priv->hw->pcs & STMMAC_PCS_SGMII) {
++      if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&
++          (priv->hw->pcs & STMMAC_PCS_RGMII ||
++           priv->hw->pcs & STMMAC_PCS_SGMII)) {
+               struct rgmii_adv adv;
+               u32 supported, advertising, lp_advertising;
+@@ -397,8 +398,9 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev,
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
+-      if (priv->hw->pcs & STMMAC_PCS_RGMII ||
+-          priv->hw->pcs & STMMAC_PCS_SGMII) {
++      if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) &&
++          (priv->hw->pcs & STMMAC_PCS_RGMII ||
++           priv->hw->pcs & STMMAC_PCS_SGMII)) {
+               /* Only support ANE */
+               if (cmd->base.autoneg != AUTONEG_ENABLE)
+                       return -EINVAL;
+-- 
+2.43.0
+
diff --git a/queue-6.6/net-tls-fix-warniing-in-__sk_msg_free.patch b/queue-6.6/net-tls-fix-warniing-in-__sk_msg_free.patch
new file mode 100644 (file)
index 0000000..aec433e
--- /dev/null
@@ -0,0 +1,62 @@
+From 19492de3c552887cef0ff926ea771a5119f6eede Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 16:32:57 -0800
+Subject: net: tls, fix WARNIING in __sk_msg_free
+
+From: John Fastabend <john.fastabend@gmail.com>
+
+[ Upstream commit dc9dfc8dc629e42f2234e3327b75324ffc752bc9 ]
+
+A splice with MSG_SPLICE_PAGES will cause tls code to use the
+tls_sw_sendmsg_splice path in the TLS sendmsg code to move the user
+provided pages from the msg into the msg_pl. This will loop over the
+msg until msg_pl is full, checked by sk_msg_full(msg_pl). The user
+can also set the MORE flag to hint stack to delay sending until receiving
+more pages and ideally a full buffer.
+
+If the user adds more pages to the msg than can fit in the msg_pl
+scatterlist (MAX_MSG_FRAGS) we should ignore the MORE flag and send
+the buffer anyways.
+
+What actually happens though is we abort the msg to msg_pl scatterlist
+setup and then because we forget to set 'full record' indicating we
+can no longer consume data without a send we fallthrough to the 'continue'
+path which will check if msg_data_left(msg) has more bytes to send and
+then attempts to fit them in the already full msg_pl. Then next
+iteration of sender doing send will encounter a full msg_pl and throw
+the warning in the syzbot report.
+
+To fix simply check if we have a full_record in splice code path and
+if not send the msg regardless of MORE flag.
+
+Reported-and-tested-by: syzbot+f2977222e0e95cec15c8@syzkaller.appspotmail.com
+Reported-by: Edward Adam Davis <eadavis@qq.com>
+Fixes: fe1e81d4f73b ("tls/sw: Support MSG_SPLICE_PAGES")
+Reviewed-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: John Fastabend <john.fastabend@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_sw.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
+index 27cc0f0a90e1..dba523cdc73d 100644
+--- a/net/tls/tls_sw.c
++++ b/net/tls/tls_sw.c
+@@ -1052,7 +1052,11 @@ static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg,
+                       if (ret < 0)
+                               goto send_end;
+                       tls_ctx->pending_open_record_frags = true;
+-                      if (full_record || eor || sk_msg_full(msg_pl))
++
++                      if (sk_msg_full(msg_pl))
++                              full_record = true;
++
++                      if (full_record || eor)
+                               goto copied;
+                       continue;
+               }
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-bridge-replace-physindev-with-physinif-in-.patch b/queue-6.6/netfilter-bridge-replace-physindev-with-physinif-in-.patch
new file mode 100644 (file)
index 0000000..d04780c
--- /dev/null
@@ -0,0 +1,306 @@
+From a4ce2ae6342f280d6901a380ac05ea1436366ea9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 23:06:40 +0800
+Subject: netfilter: bridge: replace physindev with physinif in nf_bridge_info
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+[ Upstream commit 9874808878d9eed407e3977fd11fee49de1e1d86 ]
+
+An skb can be added to a neigh->arp_queue while waiting for an arp
+reply. Where original skb's skb->dev can be different to neigh's
+neigh->dev. For instance in case of bridging dnated skb from one veth to
+another, the skb would be added to a neigh->arp_queue of the bridge.
+
+As skb->dev can be reset back to nf_bridge->physindev and used, and as
+there is no explicit mechanism that prevents this physindev from been
+freed under us (for instance neigh_flush_dev doesn't cleanup skbs from
+different device's neigh queue) we can crash on e.g. this stack:
+
+arp_process
+  neigh_update
+    skb = __skb_dequeue(&neigh->arp_queue)
+      neigh_resolve_output(..., skb)
+        ...
+          br_nf_dev_xmit
+            br_nf_pre_routing_finish_bridge_slow
+              skb->dev = nf_bridge->physindev
+              br_handle_frame_finish
+
+Let's use plain ifindex instead of net_device link. To peek into the
+original net_device we will use dev_get_by_index_rcu(). Thus either we
+get device and are safe to use it or we don't get it and drop skb.
+
+Fixes: c4e70a87d975 ("netfilter: bridge: rename br_netfilter.c to br_netfilter_hooks.c")
+Suggested-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netfilter_bridge.h    |  4 +--
+ include/linux/skbuff.h              |  2 +-
+ net/bridge/br_netfilter_hooks.c     | 42 +++++++++++++++++++++++------
+ net/bridge/br_netfilter_ipv6.c      | 14 +++++++---
+ net/ipv4/netfilter/nf_reject_ipv4.c |  9 ++++---
+ net/ipv6/netfilter/nf_reject_ipv6.c | 11 +++++---
+ 6 files changed, 61 insertions(+), 21 deletions(-)
+
+diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
+index e927b9a15a55..743475ca7e9d 100644
+--- a/include/linux/netfilter_bridge.h
++++ b/include/linux/netfilter_bridge.h
+@@ -42,7 +42,7 @@ static inline int nf_bridge_get_physinif(const struct sk_buff *skb)
+       if (!nf_bridge)
+               return 0;
+-      return nf_bridge->physindev ? nf_bridge->physindev->ifindex : 0;
++      return nf_bridge->physinif;
+ }
+ static inline int nf_bridge_get_physoutif(const struct sk_buff *skb)
+@@ -60,7 +60,7 @@ nf_bridge_get_physindev(const struct sk_buff *skb, struct net *net)
+ {
+       const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+-      return nf_bridge ? nf_bridge->physindev : NULL;
++      return nf_bridge ? dev_get_by_index_rcu(net, nf_bridge->physinif) : NULL;
+ }
+ static inline struct net_device *
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 97bfef071255..ddfe86deb4e7 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -295,7 +295,7 @@ struct nf_bridge_info {
+       u8                      bridged_dnat:1;
+       u8                      sabotage_in_done:1;
+       __u16                   frag_max_size;
+-      struct net_device       *physindev;
++      int                     physinif;
+       /* always valid & non-NULL from FORWARD on, for physdev match */
+       struct net_device       *physoutdev;
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index 033034d68f1f..92dae4c4922c 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -279,8 +279,17 @@ int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_
+               if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) &&
+                   READ_ONCE(neigh->hh.hh_len)) {
++                      struct net_device *br_indev;
++
++                      br_indev = nf_bridge_get_physindev(skb, net);
++                      if (!br_indev) {
++                              neigh_release(neigh);
++                              goto free_skb;
++                      }
++
+                       neigh_hh_bridge(&neigh->hh, skb);
+-                      skb->dev = nf_bridge->physindev;
++                      skb->dev = br_indev;
++
+                       ret = br_handle_frame_finish(net, sk, skb);
+               } else {
+                       /* the neighbour function below overwrites the complete
+@@ -352,12 +361,18 @@ br_nf_ipv4_daddr_was_changed(const struct sk_buff *skb,
+  */
+ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
+ {
+-      struct net_device *dev = skb->dev;
++      struct net_device *dev = skb->dev, *br_indev;
+       struct iphdr *iph = ip_hdr(skb);
+       struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+       struct rtable *rt;
+       int err;
++      br_indev = nf_bridge_get_physindev(skb, net);
++      if (!br_indev) {
++              kfree_skb(skb);
++              return 0;
++      }
++
+       nf_bridge->frag_max_size = IPCB(skb)->frag_max_size;
+       if (nf_bridge->pkt_otherhost) {
+@@ -397,7 +412,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
+               } else {
+                       if (skb_dst(skb)->dev == dev) {
+ bridged_dnat:
+-                              skb->dev = nf_bridge->physindev;
++                              skb->dev = br_indev;
+                               nf_bridge_update_protocol(skb);
+                               nf_bridge_push_encap_header(skb);
+                               br_nf_hook_thresh(NF_BR_PRE_ROUTING,
+@@ -410,7 +425,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
+                       skb->pkt_type = PACKET_HOST;
+               }
+       } else {
+-              rt = bridge_parent_rtable(nf_bridge->physindev);
++              rt = bridge_parent_rtable(br_indev);
+               if (!rt) {
+                       kfree_skb(skb);
+                       return 0;
+@@ -419,7 +434,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
+               skb_dst_set_noref(skb, &rt->dst);
+       }
+-      skb->dev = nf_bridge->physindev;
++      skb->dev = br_indev;
+       nf_bridge_update_protocol(skb);
+       nf_bridge_push_encap_header(skb);
+       br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, skb->dev, NULL,
+@@ -456,7 +471,7 @@ struct net_device *setup_pre_routing(struct sk_buff *skb, const struct net *net)
+       }
+       nf_bridge->in_prerouting = 1;
+-      nf_bridge->physindev = skb->dev;
++      nf_bridge->physinif = skb->dev->ifindex;
+       skb->dev = brnf_get_logical_dev(skb, skb->dev, net);
+       if (skb->protocol == htons(ETH_P_8021Q))
+@@ -553,7 +568,11 @@ static int br_nf_forward_finish(struct net *net, struct sock *sk, struct sk_buff
+               if (skb->protocol == htons(ETH_P_IPV6))
+                       nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size;
+-              in = nf_bridge->physindev;
++              in = nf_bridge_get_physindev(skb, net);
++              if (!in) {
++                      kfree_skb(skb);
++                      return 0;
++              }
+               if (nf_bridge->pkt_otherhost) {
+                       skb->pkt_type = PACKET_OTHERHOST;
+                       nf_bridge->pkt_otherhost = false;
+@@ -897,6 +916,13 @@ static unsigned int ip_sabotage_in(void *priv,
+ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
+ {
+       struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
++      struct net_device *br_indev;
++
++      br_indev = nf_bridge_get_physindev(skb, dev_net(skb->dev));
++      if (!br_indev) {
++              kfree_skb(skb);
++              return;
++      }
+       skb_pull(skb, ETH_HLEN);
+       nf_bridge->bridged_dnat = 0;
+@@ -906,7 +932,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
+       skb_copy_to_linear_data_offset(skb, -(ETH_HLEN - ETH_ALEN),
+                                      nf_bridge->neigh_header,
+                                      ETH_HLEN - ETH_ALEN);
+-      skb->dev = nf_bridge->physindev;
++      skb->dev = br_indev;
+       nf_bridge->physoutdev = NULL;
+       br_handle_frame_finish(dev_net(skb->dev), NULL, skb);
+diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c
+index 550039dfc31a..ad268bd19d5b 100644
+--- a/net/bridge/br_netfilter_ipv6.c
++++ b/net/bridge/br_netfilter_ipv6.c
+@@ -102,9 +102,15 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc
+ {
+       struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+       struct rtable *rt;
+-      struct net_device *dev = skb->dev;
++      struct net_device *dev = skb->dev, *br_indev;
+       const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
++      br_indev = nf_bridge_get_physindev(skb, net);
++      if (!br_indev) {
++              kfree_skb(skb);
++              return 0;
++      }
++
+       nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size;
+       if (nf_bridge->pkt_otherhost) {
+@@ -122,7 +128,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc
+               }
+               if (skb_dst(skb)->dev == dev) {
+-                      skb->dev = nf_bridge->physindev;
++                      skb->dev = br_indev;
+                       nf_bridge_update_protocol(skb);
+                       nf_bridge_push_encap_header(skb);
+                       br_nf_hook_thresh(NF_BR_PRE_ROUTING,
+@@ -133,7 +139,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc
+               ether_addr_copy(eth_hdr(skb)->h_dest, dev->dev_addr);
+               skb->pkt_type = PACKET_HOST;
+       } else {
+-              rt = bridge_parent_rtable(nf_bridge->physindev);
++              rt = bridge_parent_rtable(br_indev);
+               if (!rt) {
+                       kfree_skb(skb);
+                       return 0;
+@@ -142,7 +148,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc
+               skb_dst_set_noref(skb, &rt->dst);
+       }
+-      skb->dev = nf_bridge->physindev;
++      skb->dev = br_indev;
+       nf_bridge_update_protocol(skb);
+       nf_bridge_push_encap_header(skb);
+       br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb,
+diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
+index 297000b05f18..fc761915c5f6 100644
+--- a/net/ipv4/netfilter/nf_reject_ipv4.c
++++ b/net/ipv4/netfilter/nf_reject_ipv4.c
+@@ -239,7 +239,6 @@ static int nf_reject_fill_skb_dst(struct sk_buff *skb_in)
+ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+                  int hook)
+ {
+-      struct net_device *br_indev __maybe_unused;
+       struct sk_buff *nskb;
+       struct iphdr *niph;
+       const struct tcphdr *oth;
+@@ -289,9 +288,13 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+        * build the eth header using the original destination's MAC as the
+        * source, and send the RST packet directly.
+        */
+-      br_indev = nf_bridge_get_physindev(oldskb, net);
+-      if (br_indev) {
++      if (nf_bridge_info_exists(oldskb)) {
+               struct ethhdr *oeth = eth_hdr(oldskb);
++              struct net_device *br_indev;
++
++              br_indev = nf_bridge_get_physindev(oldskb, net);
++              if (!br_indev)
++                      goto free_nskb;
+               nskb->dev = br_indev;
+               niph->tot_len = htons(nskb->len);
+diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
+index 0a5ef7abf583..71d692728230 100644
+--- a/net/ipv6/netfilter/nf_reject_ipv6.c
++++ b/net/ipv6/netfilter/nf_reject_ipv6.c
+@@ -278,7 +278,6 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in)
+ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+                   int hook)
+ {
+-      struct net_device *br_indev __maybe_unused;
+       struct sk_buff *nskb;
+       struct tcphdr _otcph;
+       const struct tcphdr *otcph;
+@@ -354,9 +353,15 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+        * build the eth header using the original destination's MAC as the
+        * source, and send the RST packet directly.
+        */
+-      br_indev = nf_bridge_get_physindev(oldskb, net);
+-      if (br_indev) {
++      if (nf_bridge_info_exists(oldskb)) {
+               struct ethhdr *oeth = eth_hdr(oldskb);
++              struct net_device *br_indev;
++
++              br_indev = nf_bridge_get_physindev(oldskb, net);
++              if (!br_indev) {
++                      kfree_skb(nskb);
++                      return;
++              }
+               nskb->dev = br_indev;
+               nskb->protocol = htons(ETH_P_IPV6);
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nf_queue-remove-excess-nf_bridge-variable.patch b/queue-6.6/netfilter-nf_queue-remove-excess-nf_bridge-variable.patch
new file mode 100644 (file)
index 0000000..3f58edf
--- /dev/null
@@ -0,0 +1,41 @@
+From 7ef74eb56c083baf5f951b79f913159e97ddabc4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 23:06:38 +0800
+Subject: netfilter: nf_queue: remove excess nf_bridge variable
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+[ Upstream commit aeaa44075f8e49e2e0ad4507d925e690b7950145 ]
+
+We don't really need nf_bridge variable here. And nf_bridge_info_exists
+is better replacement for nf_bridge_info_get in case we are only
+checking for existence.
+
+Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 9874808878d9 ("netfilter: bridge: replace physindev with physinif in nf_bridge_info")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_queue.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
+index 63d1516816b1..3dfcb3ac5cb4 100644
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -82,10 +82,8 @@ static void __nf_queue_entry_init_physdevs(struct nf_queue_entry *entry)
+ {
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+       const struct sk_buff *skb = entry->skb;
+-      struct nf_bridge_info *nf_bridge;
+-      nf_bridge = nf_bridge_info_get(skb);
+-      if (nf_bridge) {
++      if (nf_bridge_info_exists(skb)) {
+               entry->physin = nf_bridge_get_physindev(skb);
+               entry->physout = nf_bridge_get_physoutdev(skb);
+       } else {
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nf_tables-do-not-allow-mismatch-field-size.patch b/queue-6.6/netfilter-nf_tables-do-not-allow-mismatch-field-size.patch
new file mode 100644 (file)
index 0000000..83ea264
--- /dev/null
@@ -0,0 +1,51 @@
+From 727778816d82a7ab39bf0bb433b6fae2c79a0298 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Jan 2024 23:53:39 +0100
+Subject: netfilter: nf_tables: do not allow mismatch field size and set key
+ length
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 3ce67e3793f48c1b9635beb9bb71116ca1e51b58 ]
+
+The set description provides the size of each field in the set whose sum
+should not mismatch the set key length, bail out otherwise.
+
+I did not manage to crash nft_set_pipapo with mismatch fields and set key
+length so far, but this is UB which must be disallowed.
+
+Fixes: f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 55cd82190888..5730f9a1f47d 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4753,8 +4753,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
+ static int nft_set_desc_concat(struct nft_set_desc *desc,
+                              const struct nlattr *nla)
+ {
++      u32 num_regs = 0, key_num_regs = 0;
+       struct nlattr *attr;
+-      u32 num_regs = 0;
+       int rem, err, i;
+       nla_for_each_nested(attr, nla, rem) {
+@@ -4769,6 +4769,10 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
+       for (i = 0; i < desc->field_count; i++)
+               num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32));
++      key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32));
++      if (key_num_regs != num_regs)
++              return -EINVAL;
++
+       if (num_regs > NFT_REG32_COUNT)
+               return -E2BIG;
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nf_tables-reject-invalid-set-policy.patch b/queue-6.6/netfilter-nf_tables-reject-invalid-set-policy.patch
new file mode 100644 (file)
index 0000000..cca96ec
--- /dev/null
@@ -0,0 +1,44 @@
+From e754bf02a89651102a3cb0a9c70ab160baada3a0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 23:34:58 +0100
+Subject: netfilter: nf_tables: reject invalid set policy
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 0617c3de9b4026b87be12b0cb5c35f42c7c66fcb ]
+
+Report -EINVAL in case userspace provides a unsupported set backend
+policy.
+
+Fixes: c50b960ccc59 ("netfilter: nf_tables: implement proper set selection")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 5200bd804954..55cd82190888 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4990,8 +4990,16 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+       }
+       desc.policy = NFT_SET_POL_PERFORMANCE;
+-      if (nla[NFTA_SET_POLICY] != NULL)
++      if (nla[NFTA_SET_POLICY] != NULL) {
+               desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY]));
++              switch (desc.policy) {
++              case NFT_SET_POL_PERFORMANCE:
++              case NFT_SET_POL_MEMORY:
++                      break;
++              default:
++                      return -EOPNOTSUPP;
++              }
++      }
+       if (nla[NFTA_SET_DESC] != NULL) {
+               err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]);
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch b/queue-6.6/netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch
new file mode 100644 (file)
index 0000000..cd2b9f0
--- /dev/null
@@ -0,0 +1,41 @@
+From 593039b403de7c5f39a2aff650d4d6a63edc1a2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 12:50:29 +0100
+Subject: netfilter: nf_tables: reject NFT_SET_CONCAT with not field length
+ description
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 113661e07460a6604aacc8ae1b23695a89e7d4b3 ]
+
+It is still possible to set on the NFT_SET_CONCAT flag by specifying a
+set size and no field description, report EINVAL in such case.
+
+Fixes: 1b6345d4160e ("netfilter: nf_tables: check NFT_SET_CONCAT flag if field_count is specified")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 1f6d5ffbe34a..b28fbcb86e94 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5010,8 +5010,12 @@ static int nf_tables_newset(struct sk_buff *skb, const struct nfnl_info *info,
+               if (err < 0)
+                       return err;
+-              if (desc.field_count > 1 && !(flags & NFT_SET_CONCAT))
++              if (desc.field_count > 1) {
++                      if (!(flags & NFT_SET_CONCAT))
++                              return -EINVAL;
++              } else if (flags & NFT_SET_CONCAT) {
+                       return -EINVAL;
++              }
+       } else if (flags & NFT_SET_CONCAT) {
+               return -EINVAL;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch b/queue-6.6/netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch
new file mode 100644 (file)
index 0000000..c974674
--- /dev/null
@@ -0,0 +1,47 @@
+From d80f9270eed65535aafab5c19f77392f00643ca9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jan 2024 00:14:38 +0100
+Subject: netfilter: nf_tables: skip dead set elements in netlink dump
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 6b1ca88e4bb63673dc9f9c7f23c899f22c3cb17a ]
+
+Delete from packet path relies on the garbage collector to purge
+elements with NFT_SET_ELEM_DEAD_BIT on.
+
+Skip these dead elements from nf_tables_dump_setelem() path, I very
+rarely see tests/shell/testcases/maps/typeof_maps_add_delete reports
+[DUMP FAILED] showing a mismatch in the expected output with an element
+that should not be there.
+
+If the netlink dump happens before GC worker run, it might show dead
+elements in the ruleset listing.
+
+nft_rhash_get() already skips dead elements in nft_rhash_cmp(),
+therefore, it already does not show the element when getting a single
+element via netlink control plane.
+
+Fixes: 5f68718b34a5 ("netfilter: nf_tables: GC transaction API to avoid race with control plane")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 5730f9a1f47d..1f6d5ffbe34a 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5662,7 +5662,7 @@ static int nf_tables_dump_setelem(const struct nft_ctx *ctx,
+       const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv);
+       struct nft_set_dump_args *args;
+-      if (nft_set_elem_expired(ext))
++      if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext))
+               return 0;
+       args = container_of(iter, struct nft_set_dump_args, iter);
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nfnetlink_log-use-proper-helper-for-fetchi.patch b/queue-6.6/netfilter-nfnetlink_log-use-proper-helper-for-fetchi.patch
new file mode 100644 (file)
index 0000000..b1b5399
--- /dev/null
@@ -0,0 +1,52 @@
+From 176a1945cbd6afc587d597aa03d60e1ac50059ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 23:06:37 +0800
+Subject: netfilter: nfnetlink_log: use proper helper for fetching physinif
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+[ Upstream commit c3f9fd54cd87233f53bdf0e191a86b3a5e960e02 ]
+
+We don't use physindev in __build_packet_message except for getting
+physinif from it. So let's switch to nf_bridge_get_physinif to get what
+we want directly.
+
+Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 9874808878d9 ("netfilter: bridge: replace physindev with physinif in nf_bridge_info")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nfnetlink_log.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
+index f03f4d4d7d88..134e05d31061 100644
+--- a/net/netfilter/nfnetlink_log.c
++++ b/net/netfilter/nfnetlink_log.c
+@@ -508,7 +508,7 @@ __build_packet_message(struct nfnl_log_net *log,
+                                        htonl(br_port_get_rcu(indev)->br->dev->ifindex)))
+                               goto nla_put_failure;
+               } else {
+-                      struct net_device *physindev;
++                      int physinif;
+                       /* Case 2: indev is bridge group, we need to look for
+                        * physical device (when called from ipv4) */
+@@ -516,10 +516,10 @@ __build_packet_message(struct nfnl_log_net *log,
+                                        htonl(indev->ifindex)))
+                               goto nla_put_failure;
+-                      physindev = nf_bridge_get_physindev(skb);
+-                      if (physindev &&
++                      physinif = nf_bridge_get_physinif(skb);
++                      if (physinif &&
+                           nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV,
+-                                       htonl(physindev->ifindex)))
++                                       htonl(physinif)))
+                               goto nla_put_failure;
+               }
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-nft_limit-do-not-ignore-unsupported-flags.patch b/queue-6.6/netfilter-nft_limit-do-not-ignore-unsupported-flags.patch
new file mode 100644 (file)
index 0000000..b9de28f
--- /dev/null
@@ -0,0 +1,66 @@
+From 6c3e89618f373233b716643184f666b913b20dc5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 00:42:37 +0100
+Subject: netfilter: nft_limit: do not ignore unsupported flags
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+[ Upstream commit 91a139cee1202a4599a380810d93c69b5bac6197 ]
+
+Bail out if userspace provides unsupported flags, otherwise future
+extensions to the limit expression will be silently ignored by the
+kernel.
+
+Fixes: c7862a5f0de5 ("netfilter: nft_limit: allow to invert matching criteria")
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_limit.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
+index 145dc62c6247..79039afde34e 100644
+--- a/net/netfilter/nft_limit.c
++++ b/net/netfilter/nft_limit.c
+@@ -58,6 +58,7 @@ static inline bool nft_limit_eval(struct nft_limit_priv *priv, u64 cost)
+ static int nft_limit_init(struct nft_limit_priv *priv,
+                         const struct nlattr * const tb[], bool pkts)
+ {
++      bool invert = false;
+       u64 unit, tokens;
+       if (tb[NFTA_LIMIT_RATE] == NULL ||
+@@ -90,19 +91,23 @@ static int nft_limit_init(struct nft_limit_priv *priv,
+                                priv->rate);
+       }
++      if (tb[NFTA_LIMIT_FLAGS]) {
++              u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
++
++              if (flags & ~NFT_LIMIT_F_INV)
++                      return -EOPNOTSUPP;
++
++              if (flags & NFT_LIMIT_F_INV)
++                      invert = true;
++      }
++
+       priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT);
+       if (!priv->limit)
+               return -ENOMEM;
+       priv->limit->tokens = tokens;
+       priv->tokens_max = priv->limit->tokens;
+-
+-      if (tb[NFTA_LIMIT_FLAGS]) {
+-              u32 flags = ntohl(nla_get_be32(tb[NFTA_LIMIT_FLAGS]));
+-
+-              if (flags & NFT_LIMIT_F_INV)
+-                      priv->invert = true;
+-      }
++      priv->invert = invert;
+       priv->limit->last = ktime_get_ns();
+       spin_lock_init(&priv->limit->lock);
+-- 
+2.43.0
+
diff --git a/queue-6.6/netfilter-propagate-net-to-nf_bridge_get_physindev.patch b/queue-6.6/netfilter-propagate-net-to-nf_bridge_get_physindev.patch
new file mode 100644 (file)
index 0000000..e8b6e7a
--- /dev/null
@@ -0,0 +1,189 @@
+From 326ed31d6ba5db606a5a5f0c29e19b43e0a338a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Jan 2024 23:06:39 +0800
+Subject: netfilter: propagate net to nf_bridge_get_physindev
+
+From: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+
+[ Upstream commit a54e72197037d2c9bfcd70dddaac8c8ccb5b41ba ]
+
+This is a preparation patch for replacing physindev with physinif on
+nf_bridge_info structure. We will use dev_get_by_index_rcu to resolve
+device, when needed, and it requires net to be available.
+
+Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Stable-dep-of: 9874808878d9 ("netfilter: bridge: replace physindev with physinif in nf_bridge_info")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/netfilter_bridge.h           |  2 +-
+ net/ipv4/netfilter/nf_reject_ipv4.c        |  2 +-
+ net/ipv6/netfilter/nf_reject_ipv6.c        |  2 +-
+ net/netfilter/ipset/ip_set_hash_netiface.c |  8 ++++----
+ net/netfilter/nf_log_syslog.c              | 13 +++++++------
+ net/netfilter/nf_queue.c                   |  2 +-
+ net/netfilter/xt_physdev.c                 |  2 +-
+ 7 files changed, 16 insertions(+), 15 deletions(-)
+
+diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
+index f980edfdd278..e927b9a15a55 100644
+--- a/include/linux/netfilter_bridge.h
++++ b/include/linux/netfilter_bridge.h
+@@ -56,7 +56,7 @@ static inline int nf_bridge_get_physoutif(const struct sk_buff *skb)
+ }
+ static inline struct net_device *
+-nf_bridge_get_physindev(const struct sk_buff *skb)
++nf_bridge_get_physindev(const struct sk_buff *skb, struct net *net)
+ {
+       const struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
+diff --git a/net/ipv4/netfilter/nf_reject_ipv4.c b/net/ipv4/netfilter/nf_reject_ipv4.c
+index f33aeab9424f..297000b05f18 100644
+--- a/net/ipv4/netfilter/nf_reject_ipv4.c
++++ b/net/ipv4/netfilter/nf_reject_ipv4.c
+@@ -289,7 +289,7 @@ void nf_send_reset(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+        * build the eth header using the original destination's MAC as the
+        * source, and send the RST packet directly.
+        */
+-      br_indev = nf_bridge_get_physindev(oldskb);
++      br_indev = nf_bridge_get_physindev(oldskb, net);
+       if (br_indev) {
+               struct ethhdr *oeth = eth_hdr(oldskb);
+diff --git a/net/ipv6/netfilter/nf_reject_ipv6.c b/net/ipv6/netfilter/nf_reject_ipv6.c
+index 58ccdb08c0fd..0a5ef7abf583 100644
+--- a/net/ipv6/netfilter/nf_reject_ipv6.c
++++ b/net/ipv6/netfilter/nf_reject_ipv6.c
+@@ -354,7 +354,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
+        * build the eth header using the original destination's MAC as the
+        * source, and send the RST packet directly.
+        */
+-      br_indev = nf_bridge_get_physindev(oldskb);
++      br_indev = nf_bridge_get_physindev(oldskb, net);
+       if (br_indev) {
+               struct ethhdr *oeth = eth_hdr(oldskb);
+diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
+index 95aeb31c60e0..30a655e5c4fd 100644
+--- a/net/netfilter/ipset/ip_set_hash_netiface.c
++++ b/net/netfilter/ipset/ip_set_hash_netiface.c
+@@ -138,9 +138,9 @@ hash_netiface4_data_next(struct hash_netiface4_elem *next,
+ #include "ip_set_hash_gen.h"
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+-static const char *get_physindev_name(const struct sk_buff *skb)
++static const char *get_physindev_name(const struct sk_buff *skb, struct net *net)
+ {
+-      struct net_device *dev = nf_bridge_get_physindev(skb);
++      struct net_device *dev = nf_bridge_get_physindev(skb, net);
+       return dev ? dev->name : NULL;
+ }
+@@ -177,7 +177,7 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
+       if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+-              const char *eiface = SRCDIR ? get_physindev_name(skb) :
++              const char *eiface = SRCDIR ? get_physindev_name(skb, xt_net(par)) :
+                                             get_physoutdev_name(skb);
+               if (!eiface)
+@@ -395,7 +395,7 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
+       if (opt->cmdflags & IPSET_FLAG_PHYSDEV) {
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+-              const char *eiface = SRCDIR ? get_physindev_name(skb) :
++              const char *eiface = SRCDIR ? get_physindev_name(skb, xt_net(par)) :
+                                             get_physoutdev_name(skb);
+               if (!eiface)
+diff --git a/net/netfilter/nf_log_syslog.c b/net/netfilter/nf_log_syslog.c
+index c66689ad2b49..58402226045e 100644
+--- a/net/netfilter/nf_log_syslog.c
++++ b/net/netfilter/nf_log_syslog.c
+@@ -111,7 +111,8 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u8 pf,
+                         unsigned int hooknum, const struct sk_buff *skb,
+                         const struct net_device *in,
+                         const struct net_device *out,
+-                        const struct nf_loginfo *loginfo, const char *prefix)
++                        const struct nf_loginfo *loginfo, const char *prefix,
++                        struct net *net)
+ {
+       const struct net_device *physoutdev __maybe_unused;
+       const struct net_device *physindev __maybe_unused;
+@@ -121,7 +122,7 @@ nf_log_dump_packet_common(struct nf_log_buf *m, u8 pf,
+                       in ? in->name : "",
+                       out ? out->name : "");
+ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
+-      physindev = nf_bridge_get_physindev(skb);
++      physindev = nf_bridge_get_physindev(skb, net);
+       if (physindev && in != physindev)
+               nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
+       physoutdev = nf_bridge_get_physoutdev(skb);
+@@ -148,7 +149,7 @@ static void nf_log_arp_packet(struct net *net, u_int8_t pf,
+               loginfo = &default_loginfo;
+       nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo,
+-                                prefix);
++                                prefix, net);
+       dump_arp_packet(m, loginfo, skb, skb_network_offset(skb));
+       nf_log_buf_close(m);
+@@ -845,7 +846,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf,
+               loginfo = &default_loginfo;
+       nf_log_dump_packet_common(m, pf, hooknum, skb, in,
+-                                out, loginfo, prefix);
++                                out, loginfo, prefix, net);
+       if (in)
+               dump_mac_header(m, loginfo, skb);
+@@ -880,7 +881,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
+               loginfo = &default_loginfo;
+       nf_log_dump_packet_common(m, pf, hooknum, skb, in, out,
+-                                loginfo, prefix);
++                                loginfo, prefix, net);
+       if (in)
+               dump_mac_header(m, loginfo, skb);
+@@ -916,7 +917,7 @@ static void nf_log_unknown_packet(struct net *net, u_int8_t pf,
+               loginfo = &default_loginfo;
+       nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo,
+-                                prefix);
++                                prefix, net);
+       dump_mac_header(m, loginfo, skb);
+diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
+index 3dfcb3ac5cb4..e2f334f70281 100644
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -84,7 +84,7 @@ static void __nf_queue_entry_init_physdevs(struct nf_queue_entry *entry)
+       const struct sk_buff *skb = entry->skb;
+       if (nf_bridge_info_exists(skb)) {
+-              entry->physin = nf_bridge_get_physindev(skb);
++              entry->physin = nf_bridge_get_physindev(skb, entry->state.net);
+               entry->physout = nf_bridge_get_physoutdev(skb);
+       } else {
+               entry->physin = NULL;
+diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
+index ec6ed6fda96c..343e65f377d4 100644
+--- a/net/netfilter/xt_physdev.c
++++ b/net/netfilter/xt_physdev.c
+@@ -59,7 +59,7 @@ physdev_mt(const struct sk_buff *skb, struct xt_action_param *par)
+           (!!outdev ^ !(info->invert & XT_PHYSDEV_OP_BRIDGED)))
+               return false;
+-      physdev = nf_bridge_get_physindev(skb);
++      physdev = nf_bridge_get_physindev(skb, xt_net(par));
+       indev = physdev ? physdev->name : NULL;
+       if ((info->bitmask & XT_PHYSDEV_OP_ISIN &&
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvme-trace-avoid-memcpy-overflow-warning.patch b/queue-6.6/nvme-trace-avoid-memcpy-overflow-warning.patch
new file mode 100644 (file)
index 0000000..4ca88d0
--- /dev/null
@@ -0,0 +1,45 @@
+From 708993bebb76b43a3a3f35b51e8624b69575ad63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 16:56:56 +0100
+Subject: nvme: trace: avoid memcpy overflow warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit a7de1dea76cd6a3707707af4ea2f8bc3cdeaeb11 ]
+
+A previous patch introduced a struct_group() in nvme_common_command to help
+stringop fortification figure out the length of the fields, but one function
+is not currently using them:
+
+In file included from drivers/nvme/target/core.c:7:
+In file included from include/linux/string.h:254:
+include/linux/fortify-string.h:592:4: error: call to '__read_overflow2_field' declared with 'warning' attribute: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Werror,-Wattribute-warning]
+                        __read_overflow2_field(q_size_field, size);
+                        ^
+
+Change this one to use the correct field name to avoid the warning.
+
+Fixes: 5c629dc9609dc ("nvme: use struct group for generic command dwords")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/trace.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h
+index 155334ddc13f..974d99d47f51 100644
+--- a/drivers/nvme/target/trace.h
++++ b/drivers/nvme/target/trace.h
+@@ -84,7 +84,7 @@ TRACE_EVENT(nvmet_req_init,
+               __entry->flags = cmd->common.flags;
+               __entry->nsid = le32_to_cpu(cmd->common.nsid);
+               __entry->metadata = le64_to_cpu(cmd->common.metadata);
+-              memcpy(__entry->cdw10, &cmd->common.cdw10,
++              memcpy(__entry->cdw10, &cmd->common.cdws,
+                       sizeof(__entry->cdw10));
+       ),
+       TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, "
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvmet-re-fix-tracing-strncpy-warning.patch b/queue-6.6/nvmet-re-fix-tracing-strncpy-warning.patch
new file mode 100644 (file)
index 0000000..0329359
--- /dev/null
@@ -0,0 +1,51 @@
+From 0c8676c59b03f6eff06e474d240bef30267f1ebf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Jan 2024 16:56:55 +0100
+Subject: nvmet: re-fix tracing strncpy() warning
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 4ee7ffeb4ce50c80bc4504db6f39b25a2df6bcf4 ]
+
+An earlier patch had tried to address a warning about a string copy with
+missing zero termination:
+
+drivers/nvme/target/trace.h:52:3: warning: â€˜strncpy’ specified bound 32 equals destination size [-Wstringop-truncation]
+
+The new version causes a different warning with some compiler versions, notably
+gcc-9 and gcc-10, and also misses the zero padding that was apparently done
+intentionally in the original code:
+
+drivers/nvme/target/trace.h:56:2: error: 'strncpy' specified bound depends on the length of the source argument [-Werror=stringop-overflow=]
+
+Change it to use strscpy_pad() with the original length, which will give
+a properly padded and zero-terminated string as well as avoiding the warning.
+
+Fixes: d86481e924a7 ("nvmet: use min of device_path and disk len")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/trace.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/trace.h b/drivers/nvme/target/trace.h
+index 6109b3806b12..155334ddc13f 100644
+--- a/drivers/nvme/target/trace.h
++++ b/drivers/nvme/target/trace.h
+@@ -53,8 +53,7 @@ static inline void __assign_req_name(char *name, struct nvmet_req *req)
+               return;
+       }
+-      strncpy(name, req->ns->device_path,
+-              min_t(size_t, DISK_NAME_LEN, strlen(req->ns->device_path)));
++      strscpy_pad(name, req->ns->device_path, DISK_NAME_LEN);
+ }
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch b/queue-6.6/nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch
new file mode 100644 (file)
index 0000000..b9a3681
--- /dev/null
@@ -0,0 +1,45 @@
+From 8b352fcab0e552ef97e1c622dfacb77ec6c8d627 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 16:17:49 +0100
+Subject: nvmet-tcp: fix a crash in nvmet_req_complete()
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 0849a5441358cef02586fb2d60f707c0db195628 ]
+
+in nvmet_tcp_handle_h2c_data_pdu(), if the host sends a data_offset
+different from rbytes_done, the driver ends up calling nvmet_req_complete()
+passing a status error.
+The problem is that at this point cmd->req is not yet initialized,
+the kernel will crash after dereferencing a NULL pointer.
+
+Fix the bug by replacing the call to nvmet_req_complete() with
+nvmet_tcp_fatal_error().
+
+Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver")
+Reviewed-by: Keith Busch <kbsuch@kernel.org>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index 3d171061cc0f..7f7fa78f0698 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -973,8 +973,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+                       data->ttag, le32_to_cpu(data->data_offset),
+                       cmd->rbytes_done);
+               /* FIXME: use path and transport errors */
+-              nvmet_req_complete(&cmd->req,
+-                      NVME_SC_INVALID_FIELD | NVME_SC_DNR);
++              nvmet_tcp_fatal_error(queue);
+               return -EPROTO;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch b/queue-6.6/nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch
new file mode 100644 (file)
index 0000000..a94182d
--- /dev/null
@@ -0,0 +1,84 @@
+From 29a3129183ea44e8b30fe351e8a14eb2ff99a348 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Dec 2023 16:17:48 +0100
+Subject: nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU
+ length
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit efa56305908ba20de2104f1b8508c6a7401833be ]
+
+If the host sends an H2CData command with an invalid DATAL,
+the kernel may crash in nvmet_tcp_build_pdu_iovec().
+
+Unable to handle kernel NULL pointer dereference at
+virtual address 0000000000000000
+lr : nvmet_tcp_io_work+0x6ac/0x718 [nvmet_tcp]
+Call trace:
+  process_one_work+0x174/0x3c8
+  worker_thread+0x2d0/0x3e8
+  kthread+0x104/0x110
+
+Fix the bug by raising a fatal error if DATAL isn't coherent
+with the packet size.
+Also, the PDU length should never exceed the MAXH2CDATA parameter which
+has been communicated to the host in nvmet_tcp_handle_icreq().
+
+Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index 197fc2ecb164..3d171061cc0f 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -19,6 +19,7 @@
+ #include "nvmet.h"
+ #define NVMET_TCP_DEF_INLINE_DATA_SIZE        (4 * PAGE_SIZE)
++#define NVMET_TCP_MAXH2CDATA          0x400000 /* 16M arbitrary limit */
+ static int param_store_val(const char *str, int *val, int min, int max)
+ {
+@@ -900,7 +901,7 @@ static int nvmet_tcp_handle_icreq(struct nvmet_tcp_queue *queue)
+       icresp->hdr.pdo = 0;
+       icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen);
+       icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0);
+-      icresp->maxdata = cpu_to_le32(0x400000); /* 16M arbitrary limit */
++      icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA);
+       icresp->cpda = 0;
+       if (queue->hdr_digest)
+               icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE;
+@@ -953,6 +954,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+ {
+       struct nvme_tcp_data_pdu *data = &queue->pdu.data;
+       struct nvmet_tcp_cmd *cmd;
++      unsigned int plen;
+       if (likely(queue->nr_cmds)) {
+               if (unlikely(data->ttag >= queue->nr_cmds)) {
+@@ -976,7 +978,16 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+               return -EPROTO;
+       }
++      plen = le32_to_cpu(data->hdr.plen);
+       cmd->pdu_len = le32_to_cpu(data->data_length);
++      if (unlikely(cmd->pdu_len != (plen - sizeof(*data)) ||
++                   cmd->pdu_len == 0 ||
++                   cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) {
++              pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
++              /* FIXME: use proper transport errors */
++              nvmet_tcp_fatal_error(queue);
++              return -EPROTO;
++      }
+       cmd->pdu_recv = 0;
+       nvmet_tcp_build_pdu_iovec(cmd);
+       queue->cmd = cmd;
+-- 
+2.43.0
+
diff --git a/queue-6.6/nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch b/queue-6.6/nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch
new file mode 100644 (file)
index 0000000..f70e45e
--- /dev/null
@@ -0,0 +1,55 @@
+From e7bc1bccb91f76065bbfdcc0340576bcd424f6ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 09:14:44 +0100
+Subject: nvmet-tcp: Fix the H2C expected PDU len calculation
+
+From: Maurizio Lombardi <mlombard@redhat.com>
+
+[ Upstream commit 9a1abc24850eb759e36a2f8869161c3b7254c904 ]
+
+The nvmet_tcp_handle_h2c_data_pdu() function should take into
+consideration the possibility that the header digest and/or the data
+digests are enabled when calculating the expected PDU length, before
+comparing it to the value stored in cmd->pdu_len.
+
+Fixes: efa56305908b ("nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length")
+Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
+Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
+Signed-off-by: Keith Busch <kbusch@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/tcp.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
+index 7f7fa78f0698..a4f802790ca0 100644
+--- a/drivers/nvme/target/tcp.c
++++ b/drivers/nvme/target/tcp.c
+@@ -954,7 +954,7 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+ {
+       struct nvme_tcp_data_pdu *data = &queue->pdu.data;
+       struct nvmet_tcp_cmd *cmd;
+-      unsigned int plen;
++      unsigned int exp_data_len;
+       if (likely(queue->nr_cmds)) {
+               if (unlikely(data->ttag >= queue->nr_cmds)) {
+@@ -977,9 +977,13 @@ static int nvmet_tcp_handle_h2c_data_pdu(struct nvmet_tcp_queue *queue)
+               return -EPROTO;
+       }
+-      plen = le32_to_cpu(data->hdr.plen);
++      exp_data_len = le32_to_cpu(data->hdr.plen) -
++                      nvmet_tcp_hdgst_len(queue) -
++                      nvmet_tcp_ddgst_len(queue) -
++                      sizeof(*data);
++
+       cmd->pdu_len = le32_to_cpu(data->data_length);
+-      if (unlikely(cmd->pdu_len != (plen - sizeof(*data)) ||
++      if (unlikely(cmd->pdu_len != exp_data_len ||
+                    cmd->pdu_len == 0 ||
+                    cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) {
+               pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len);
+-- 
+2.43.0
+
diff --git a/queue-6.6/octeontx2-af-cn10kb-fix-fifo-length-calculation-for-.patch b/queue-6.6/octeontx2-af-cn10kb-fix-fifo-length-calculation-for-.patch
new file mode 100644 (file)
index 0000000..b384f89
--- /dev/null
@@ -0,0 +1,53 @@
+From 6a7636e9a952faee8a2cbcacc442fc1311ef494b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 8 Jan 2024 13:00:36 +0530
+Subject: octeontx2-af: CN10KB: Fix FIFO length calculation for RPM2
+
+From: Nithin Dabilpuram <ndabilpuram@marvell.com>
+
+[ Upstream commit a0cb76a770083a22167659e64ba69af6425b1d9b ]
+
+RPM0 and RPM1 on the CN10KB SoC have 8 LMACs each, whereas RPM2
+has only 4 LMACs. Similarly, the RPM0 and RPM1 have 256KB FIFO,
+whereas RPM2 has 128KB FIFO. This patch fixes an issue with
+improper TX credit programming for the RPM2 link.
+
+Fixes: b9d0fedc6234 ("octeontx2-af: cn10kb: Add RPM_USX MAC support")
+Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
+Signed-off-by: Naveen Mamindlapalli <naveenm@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://lore.kernel.org/r/20240108073036.8766-1-naveenm@marvell.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/rpm.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+index 4728ba34b0e3..76218f1cb459 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/rpm.c
+@@ -506,6 +506,7 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id)
+       rpm_t *rpm = rpmd;
+       u8 num_lmacs;
+       u32 fifo_len;
++      u16 max_lmac;
+       lmac_info = rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS);
+       /* LMACs are divided into two groups and each group
+@@ -513,7 +514,11 @@ u32 rpm2_get_lmac_fifo_len(void *rpmd, int lmac_id)
+        * Group0 lmac_id range {0..3}
+        * Group1 lmac_id range {4..7}
+        */
+-      fifo_len = rpm->mac_ops->fifo_len / 2;
++      max_lmac = (rpm_read(rpm, 0, CGX_CONST) >> 24) & 0xFF;
++      if (max_lmac > 4)
++              fifo_len = rpm->mac_ops->fifo_len / 2;
++      else
++              fifo_len = rpm->mac_ops->fifo_len;
+       if (lmac_id < 4) {
+               num_lmacs = hweight8(lmac_info & 0xF);
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-avoid-potential-out-of-bounds-read-in-pci_dev_fo.patch b/queue-6.6/pci-avoid-potential-out-of-bounds-read-in-pci_dev_fo.patch
new file mode 100644 (file)
index 0000000..d6ac3f6
--- /dev/null
@@ -0,0 +1,61 @@
+From 77fa2cd2145ed15e3bb76a3a210fece0ff15da89 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 30 Oct 2023 13:42:18 +0200
+Subject: PCI: Avoid potential out-of-bounds read in
+ pci_dev_for_each_resource()
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 3171e46d677a668eed3086da78671f1e4f5b8405 ]
+
+Coverity complains that pointer in the pci_dev_for_each_resource() may be
+wrong, i.e., might be used for the out-of-bounds read.
+
+There is no actual issue right now because we have another check afterwards
+and the out-of-bounds read is not being performed. In any case it's better
+code with this fixed, hence the proposed change.
+
+As Jonas pointed out "It probably makes the code slightly less performant
+as res will now be checked for being not NULL (which will always be true),
+but I doubt it will be significant (or in any hot paths)."
+
+Fixes: 09cc90063240 ("PCI: Introduce pci_dev_for_each_resource()")
+Reported-by: Bjorn Helgaas <bhelgaas@google.com>
+Closes: https://lore.kernel.org/r/20230509182122.GA1259567@bhelgaas
+Suggested-by: Jonas Gorski <jonas.gorski@gmail.com>
+Link: https://lore.kernel.org/r/20231030114218.2752236-1-andriy.shevchenko@linux.intel.com
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/pci.h | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 1596b1205b8d..3af5f2998551 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -2101,14 +2101,14 @@ int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma);
+       (pci_resource_end((dev), (bar)) ?                               \
+        resource_size(pci_resource_n((dev), (bar))) : 0)
+-#define __pci_dev_for_each_res0(dev, res, ...)                                \
+-      for (unsigned int __b = 0;                                      \
+-           res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES;   \
++#define __pci_dev_for_each_res0(dev, res, ...)                                  \
++      for (unsigned int __b = 0;                                        \
++           __b < PCI_NUM_RESOURCES && (res = pci_resource_n(dev, __b)); \
+            __b++)
+-#define __pci_dev_for_each_res1(dev, res, __b)                                \
+-      for (__b = 0;                                                   \
+-           res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES;   \
++#define __pci_dev_for_each_res1(dev, res, __b)                                  \
++      for (__b = 0;                                                     \
++           __b < PCI_NUM_RESOURCES && (res = pci_resource_n(dev, __b)); \
+            __b++)
+ #define pci_dev_for_each_resource(dev, res, ...)                      \
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-epf-mhi-fix-the-dma-data-direction-of-dma_unmap_.patch b/queue-6.6/pci-epf-mhi-fix-the-dma-data-direction-of-dma_unmap_.patch
new file mode 100644 (file)
index 0000000..2388f9f
--- /dev/null
@@ -0,0 +1,41 @@
+From 4c9ab424dfeaa31cedec52c0736bd70e5662d516 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Dec 2023 12:03:28 +0530
+Subject: PCI: epf-mhi: Fix the DMA data direction of dma_unmap_single()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+[ Upstream commit 327ec5f70609cf00c6f961073c01857555c6a8eb ]
+
+In the error path of pci_epf_mhi_edma_write() function, the DMA data
+direction passed (DMA_FROM_DEVICE) doesn't match the actual direction used
+for the data transfer. Fix it by passing the correct one (DMA_TO_DEVICE).
+
+Fixes: 7b99aaaddabb ("PCI: epf-mhi: Add eDMA support")
+Reviewed-by: Krzysztof WilczyÅ„ski <kw@linux.com>
+Link: https://lore.kernel.org/r/20231214063328.40657-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/endpoint/functions/pci-epf-mhi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c
+index ec5f4a38178b..6dc918a8a023 100644
+--- a/drivers/pci/endpoint/functions/pci-epf-mhi.c
++++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c
+@@ -405,7 +405,7 @@ static int pci_epf_mhi_edma_write(struct mhi_ep_cntrl *mhi_cntrl,
+       }
+ err_unmap:
+-      dma_unmap_single(dma_dev, src_addr, buf_info->size, DMA_FROM_DEVICE);
++      dma_unmap_single(dma_dev, src_addr, buf_info->size, DMA_TO_DEVICE);
+ err_unlock:
+       mutex_unlock(&epf_mhi->lock);
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-keystone-fix-race-condition-when-initializing-ph.patch b/queue-6.6/pci-keystone-fix-race-condition-when-initializing-ph.patch
new file mode 100644 (file)
index 0000000..793488a
--- /dev/null
@@ -0,0 +1,64 @@
+From 2f1ed028a56d013fa07b492edef34f3468b3c6a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 Sep 2023 09:48:45 +0530
+Subject: PCI: keystone: Fix race condition when initializing PHYs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Siddharth Vadapalli <s-vadapalli@ti.com>
+
+[ Upstream commit c12ca110c613a81cb0f0099019c839d078cd0f38 ]
+
+The PCI driver invokes the PHY APIs using the ks_pcie_enable_phy()
+function. The PHY in this case is the Serdes. It is possible that the
+PCI instance is configured for two lane operation across two different
+Serdes instances, using one lane of each Serdes.
+
+In such a configuration, if the reference clock for one Serdes is
+provided by the other Serdes, it results in a race condition. After the
+Serdes providing the reference clock is initialized by the PCI driver by
+invoking its PHY APIs, it is not guaranteed that this Serdes remains
+powered on long enough for the PHY APIs based initialization of the
+dependent Serdes. In such cases, the PLL of the dependent Serdes fails
+to lock due to the absence of the reference clock from the former Serdes
+which has been powered off by the PM Core.
+
+Fix this by obtaining reference to the PHYs before invoking the PHY
+initialization APIs and releasing reference after the initialization is
+complete.
+
+Link: https://lore.kernel.org/linux-pci/20230927041845.1222080-1-s-vadapalli@ti.com
+Fixes: 49229238ab47 ("PCI: keystone: Cleanup PHY handling")
+Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
+Signed-off-by: Krzysztof WilczyÅ„ski <kwilczynski@kernel.org>
+Acked-by: Ravi Gunasekaran <r-gunasekaran@ti.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/dwc/pci-keystone.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c
+index 0def919f89fa..cf3836561316 100644
+--- a/drivers/pci/controller/dwc/pci-keystone.c
++++ b/drivers/pci/controller/dwc/pci-keystone.c
+@@ -1218,7 +1218,16 @@ static int ks_pcie_probe(struct platform_device *pdev)
+               goto err_link;
+       }
++      /* Obtain references to the PHYs */
++      for (i = 0; i < num_lanes; i++)
++              phy_pm_runtime_get_sync(ks_pcie->phy[i]);
++
+       ret = ks_pcie_enable_phy(ks_pcie);
++
++      /* Release references to the PHYs */
++      for (i = 0; i < num_lanes; i++)
++              phy_pm_runtime_put_sync(ks_pcie->phy[i]);
++
+       if (ret) {
+               dev_err(dev, "failed to enable phy\n");
+               goto err_link;
+-- 
+2.43.0
+
diff --git a/queue-6.6/pci-mediatek-gen3-fix-translation-window-size-calcul.patch b/queue-6.6/pci-mediatek-gen3-fix-translation-window-size-calcul.patch
new file mode 100644 (file)
index 0000000..61d12c4
--- /dev/null
@@ -0,0 +1,157 @@
+From 16657c2fd647458507c80595f06003996b6472c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 23 Oct 2023 16:14:23 +0800
+Subject: PCI: mediatek-gen3: Fix translation window size calculation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jianjun Wang <jianjun.wang@mediatek.com>
+
+[ Upstream commit 9ccc1318cf4bd90601f221268e42c3374703d681 ]
+
+When using the fls() helper, the translation table should be a power of
+two; otherwise, the resulting value will not be correct.
+
+For example, given fls(0x3e00000) - 1 = 25, the PCIe translation window
+size will be set to 0x2000000 instead of the expected size 0x3e00000.
+
+Fix the translation window by splitting the MMIO space into multiple tables
+if its size is not a power of two.
+
+[kwilczynski: commit log]
+Link: https://lore.kernel.org/linux-pci/20231023081423.18559-1-jianjun.wang@mediatek.com
+Fixes: d3bf75b579b9 ("PCI: mediatek-gen3: Add MediaTek Gen3 driver for MT8192")
+Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com>
+Signed-off-by: Krzysztof WilczyÅ„ski <kwilczynski@kernel.org>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/pci/controller/pcie-mediatek-gen3.c | 85 ++++++++++++---------
+ 1 file changed, 50 insertions(+), 35 deletions(-)
+
+diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
+index e0e27645fdf4..975b3024fb08 100644
+--- a/drivers/pci/controller/pcie-mediatek-gen3.c
++++ b/drivers/pci/controller/pcie-mediatek-gen3.c
+@@ -245,35 +245,60 @@ static int mtk_pcie_set_trans_table(struct mtk_gen3_pcie *pcie,
+                                   resource_size_t cpu_addr,
+                                   resource_size_t pci_addr,
+                                   resource_size_t size,
+-                                  unsigned long type, int num)
++                                  unsigned long type, int *num)
+ {
++      resource_size_t remaining = size;
++      resource_size_t table_size;
++      resource_size_t addr_align;
++      const char *range_type;
+       void __iomem *table;
+       u32 val;
+-      if (num >= PCIE_MAX_TRANS_TABLES) {
+-              dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n",
+-                      (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES);
+-              return -ENODEV;
+-      }
++      while (remaining && (*num < PCIE_MAX_TRANS_TABLES)) {
++              /* Table size needs to be a power of 2 */
++              table_size = BIT(fls(remaining) - 1);
++
++              if (cpu_addr > 0) {
++                      addr_align = BIT(ffs(cpu_addr) - 1);
++                      table_size = min(table_size, addr_align);
++              }
++
++              /* Minimum size of translate table is 4KiB */
++              if (table_size < 0x1000) {
++                      dev_err(pcie->dev, "illegal table size %#llx\n",
++                              (unsigned long long)table_size);
++                      return -EINVAL;
++              }
+-      table = pcie->base + PCIE_TRANS_TABLE_BASE_REG +
+-              num * PCIE_ATR_TLB_SET_OFFSET;
++              table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + *num * PCIE_ATR_TLB_SET_OFFSET;
++              writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(table_size) - 1), table);
++              writel_relaxed(upper_32_bits(cpu_addr), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET);
++              writel_relaxed(lower_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET);
++              writel_relaxed(upper_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET);
+-      writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(size) - 1),
+-                     table);
+-      writel_relaxed(upper_32_bits(cpu_addr),
+-                     table + PCIE_ATR_SRC_ADDR_MSB_OFFSET);
+-      writel_relaxed(lower_32_bits(pci_addr),
+-                     table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET);
+-      writel_relaxed(upper_32_bits(pci_addr),
+-                     table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET);
++              if (type == IORESOURCE_IO) {
++                      val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO;
++                      range_type = "IO";
++              } else {
++                      val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM;
++                      range_type = "MEM";
++              }
+-      if (type == IORESOURCE_IO)
+-              val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO;
+-      else
+-              val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM;
++              writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET);
+-      writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET);
++              dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n",
++                      range_type, *num, (unsigned long long)cpu_addr,
++                      (unsigned long long)pci_addr, (unsigned long long)table_size);
++
++              cpu_addr += table_size;
++              pci_addr += table_size;
++              remaining -= table_size;
++              (*num)++;
++      }
++
++      if (remaining)
++              dev_warn(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n",
++                       (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES);
+       return 0;
+ }
+@@ -380,30 +405,20 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
+               resource_size_t cpu_addr;
+               resource_size_t pci_addr;
+               resource_size_t size;
+-              const char *range_type;
+-              if (type == IORESOURCE_IO) {
++              if (type == IORESOURCE_IO)
+                       cpu_addr = pci_pio_to_address(res->start);
+-                      range_type = "IO";
+-              } else if (type == IORESOURCE_MEM) {
++              else if (type == IORESOURCE_MEM)
+                       cpu_addr = res->start;
+-                      range_type = "MEM";
+-              } else {
++              else
+                       continue;
+-              }
+               pci_addr = res->start - entry->offset;
+               size = resource_size(res);
+               err = mtk_pcie_set_trans_table(pcie, cpu_addr, pci_addr, size,
+-                                             type, table_index);
++                                             type, &table_index);
+               if (err)
+                       return err;
+-
+-              dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n",
+-                      range_type, table_index, (unsigned long long)cpu_addr,
+-                      (unsigned long long)pci_addr, (unsigned long long)size);
+-
+-              table_index++;
+       }
+       return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-db-export-fix-missing-reference-count-get-in-ca.patch b/queue-6.6/perf-db-export-fix-missing-reference-count-get-in-ca.patch
new file mode 100644 (file)
index 0000000..d908749
--- /dev/null
@@ -0,0 +1,74 @@
+From 69949416bf66e9aa01e2233e79341d2a0050af11 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 14:09:11 +0000
+Subject: perf db-export: Fix missing reference count get in
+ call_path_from_sample()
+
+From: Ben Gainey <ben.gainey@arm.com>
+
+[ Upstream commit 1e24ce402c97dc3c0ab050593f1d5f6fde524564 ]
+
+The addr_location map and maps fields in the inner loop were missing
+calls to map__get()/maps__get(). The subsequent addr_location__exit()
+call in each loop puts the map/maps fields causing use-after-free
+aborts.
+
+This issue reproduces on at least arm64 and x86_64 with something
+simple like `perf record -g ls` followed by `perf script -s script.py`
+with the following script:
+
+    perf_db_export_mode = True
+    perf_db_export_calls = False
+    perf_db_export_callchains = True
+
+    def sample_table(*args):
+        print(f'sample_table({args})')
+
+    def call_path_table(*args):
+        print(f'call_path_table({args}')
+
+Committer testing:
+
+This test, just introduced by Ian Rogers, now passes, not segfaulting
+anymore:
+
+  # perf test "perf script tests"
+   95: perf script tests                                               : Ok
+  #
+
+Fixes: 0dd5041c9a0eaf8c ("perf addr_location: Add init/exit/copy functions")
+Signed-off-by: Ben Gainey <ben.gainey@arm.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Tested-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231207140911.3240408-1-ben.gainey@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/db-export.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c
+index b9fb71ab7a73..106429155c2e 100644
+--- a/tools/perf/util/db-export.c
++++ b/tools/perf/util/db-export.c
+@@ -253,8 +253,8 @@ static struct call_path *call_path_from_sample(struct db_export *dbe,
+                */
+               addr_location__init(&al);
+               al.sym = node->ms.sym;
+-              al.map = node->ms.map;
+-              al.maps = thread__maps(thread);
++              al.map = map__get(node->ms.map);
++              al.maps = maps__get(thread__maps(thread));
+               al.addr = node->ip;
+               if (al.map && !al.sym)
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch b/queue-6.6/perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch
new file mode 100644 (file)
index 0000000..4544028
--- /dev/null
@@ -0,0 +1,276 @@
+From 4a78984287aa07dfbb0383052a0b14d9381753c8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 17:46:55 -0800
+Subject: perf env: Avoid recursively taking env->bpf_progs.lock
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 9c51f8788b5d4e9f46afbcf563255cfd355690b3 ]
+
+Add variants of perf_env__insert_bpf_prog_info(), perf_env__insert_btf()
+and perf_env__find_btf prefixed with __ to indicate the
+env->bpf_progs.lock is assumed held.
+
+Call these variants when the lock is held to avoid recursively taking it
+and potentially having a thread deadlock with itself.
+
+Fixes: f8dfeae009effc0b ("perf bpf: Show more BPF program info in print_bpf_prog_info()")
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Jiri Olsa <jolsa@kernel.org>
+Acked-by: Song Liu <song@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Huacai Chen <chenhuacai@kernel.org>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: K Prateek Nayak <kprateek.nayak@amd.com>
+Cc: Kan Liang <kan.liang@linux.intel.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Ming Wang <wangming01@loongson.cn>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Link: https://lore.kernel.org/r/20231207014655.1252484-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/bpf-event.c |  8 +++---
+ tools/perf/util/bpf-event.h | 12 ++++-----
+ tools/perf/util/env.c       | 50 ++++++++++++++++++++++++-------------
+ tools/perf/util/env.h       |  4 +++
+ tools/perf/util/header.c    |  8 +++---
+ 5 files changed, 50 insertions(+), 32 deletions(-)
+
+diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c
+index 38fcf3ba5749..b00b5a2634c3 100644
+--- a/tools/perf/util/bpf-event.c
++++ b/tools/perf/util/bpf-event.c
+@@ -542,9 +542,9 @@ int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env)
+       return evlist__add_sb_event(evlist, &attr, bpf_event__sb_cb, env);
+ }
+-void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
+-                                  struct perf_env *env,
+-                                  FILE *fp)
++void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
++                                    struct perf_env *env,
++                                    FILE *fp)
+ {
+       __u32 *prog_lens = (__u32 *)(uintptr_t)(info->jited_func_lens);
+       __u64 *prog_addrs = (__u64 *)(uintptr_t)(info->jited_ksyms);
+@@ -560,7 +560,7 @@ void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
+       if (info->btf_id) {
+               struct btf_node *node;
+-              node = perf_env__find_btf(env, info->btf_id);
++              node = __perf_env__find_btf(env, info->btf_id);
+               if (node)
+                       btf = btf__new((__u8 *)(node->data),
+                                      node->data_size);
+diff --git a/tools/perf/util/bpf-event.h b/tools/perf/util/bpf-event.h
+index 1bcbd4fb6c66..e2f0420905f5 100644
+--- a/tools/perf/util/bpf-event.h
++++ b/tools/perf/util/bpf-event.h
+@@ -33,9 +33,9 @@ struct btf_node {
+ int machine__process_bpf(struct machine *machine, union perf_event *event,
+                        struct perf_sample *sample);
+ int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env);
+-void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
+-                                  struct perf_env *env,
+-                                  FILE *fp);
++void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info,
++                                    struct perf_env *env,
++                                    FILE *fp);
+ #else
+ static inline int machine__process_bpf(struct machine *machine __maybe_unused,
+                                      union perf_event *event __maybe_unused,
+@@ -50,9 +50,9 @@ static inline int evlist__add_bpf_sb_event(struct evlist *evlist __maybe_unused,
+       return 0;
+ }
+-static inline void bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused,
+-                                                struct perf_env *env __maybe_unused,
+-                                                FILE *fp __maybe_unused)
++static inline void __bpf_event__print_bpf_prog_info(struct bpf_prog_info *info __maybe_unused,
++                                                  struct perf_env *env __maybe_unused,
++                                                  FILE *fp __maybe_unused)
+ {
+ }
+diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c
+index a164164001fb..d2c7b6e6eae5 100644
+--- a/tools/perf/util/env.c
++++ b/tools/perf/util/env.c
+@@ -22,13 +22,19 @@ struct perf_env perf_env;
+ void perf_env__insert_bpf_prog_info(struct perf_env *env,
+                                   struct bpf_prog_info_node *info_node)
++{
++      down_write(&env->bpf_progs.lock);
++      __perf_env__insert_bpf_prog_info(env, info_node);
++      up_write(&env->bpf_progs.lock);
++}
++
++void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node)
+ {
+       __u32 prog_id = info_node->info_linear->info.id;
+       struct bpf_prog_info_node *node;
+       struct rb_node *parent = NULL;
+       struct rb_node **p;
+-      down_write(&env->bpf_progs.lock);
+       p = &env->bpf_progs.infos.rb_node;
+       while (*p != NULL) {
+@@ -40,15 +46,13 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env,
+                       p = &(*p)->rb_right;
+               } else {
+                       pr_debug("duplicated bpf prog info %u\n", prog_id);
+-                      goto out;
++                      return;
+               }
+       }
+       rb_link_node(&info_node->rb_node, parent, p);
+       rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos);
+       env->bpf_progs.infos_cnt++;
+-out:
+-      up_write(&env->bpf_progs.lock);
+ }
+ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
+@@ -77,14 +81,22 @@ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
+ }
+ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
++{
++      bool ret;
++
++      down_write(&env->bpf_progs.lock);
++      ret = __perf_env__insert_btf(env, btf_node);
++      up_write(&env->bpf_progs.lock);
++      return ret;
++}
++
++bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
+ {
+       struct rb_node *parent = NULL;
+       __u32 btf_id = btf_node->id;
+       struct btf_node *node;
+       struct rb_node **p;
+-      bool ret = true;
+-      down_write(&env->bpf_progs.lock);
+       p = &env->bpf_progs.btfs.rb_node;
+       while (*p != NULL) {
+@@ -96,25 +108,31 @@ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node)
+                       p = &(*p)->rb_right;
+               } else {
+                       pr_debug("duplicated btf %u\n", btf_id);
+-                      ret = false;
+-                      goto out;
++                      return false;
+               }
+       }
+       rb_link_node(&btf_node->rb_node, parent, p);
+       rb_insert_color(&btf_node->rb_node, &env->bpf_progs.btfs);
+       env->bpf_progs.btfs_cnt++;
+-out:
+-      up_write(&env->bpf_progs.lock);
+-      return ret;
++      return true;
+ }
+ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id)
++{
++      struct btf_node *res;
++
++      down_read(&env->bpf_progs.lock);
++      res = __perf_env__find_btf(env, btf_id);
++      up_read(&env->bpf_progs.lock);
++      return res;
++}
++
++struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id)
+ {
+       struct btf_node *node = NULL;
+       struct rb_node *n;
+-      down_read(&env->bpf_progs.lock);
+       n = env->bpf_progs.btfs.rb_node;
+       while (n) {
+@@ -124,13 +142,9 @@ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id)
+               else if (btf_id > node->id)
+                       n = n->rb_right;
+               else
+-                      goto out;
++                      return node;
+       }
+-      node = NULL;
+-
+-out:
+-      up_read(&env->bpf_progs.lock);
+-      return node;
++      return NULL;
+ }
+ /* purge data in bpf_progs.infos tree */
+diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h
+index 4566c51f2fd9..359eff51cb85 100644
+--- a/tools/perf/util/env.h
++++ b/tools/perf/util/env.h
+@@ -164,12 +164,16 @@ const char *perf_env__raw_arch(struct perf_env *env);
+ int perf_env__nr_cpus_avail(struct perf_env *env);
+ void perf_env__init(struct perf_env *env);
++void __perf_env__insert_bpf_prog_info(struct perf_env *env,
++                                    struct bpf_prog_info_node *info_node);
+ void perf_env__insert_bpf_prog_info(struct perf_env *env,
+                                   struct bpf_prog_info_node *info_node);
+ struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env,
+                                                       __u32 prog_id);
+ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
++bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node);
+ struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id);
++struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id);
+ int perf_env__numa_node(struct perf_env *env, struct perf_cpu cpu);
+ char *perf_env__find_pmu_cap(struct perf_env *env, const char *pmu_name,
+diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
+index f6035c219b41..1482567e5ac1 100644
+--- a/tools/perf/util/header.c
++++ b/tools/perf/util/header.c
+@@ -1849,8 +1849,8 @@ static void print_bpf_prog_info(struct feat_fd *ff, FILE *fp)
+               node = rb_entry(next, struct bpf_prog_info_node, rb_node);
+               next = rb_next(&node->rb_node);
+-              bpf_event__print_bpf_prog_info(&node->info_linear->info,
+-                                             env, fp);
++              __bpf_event__print_bpf_prog_info(&node->info_linear->info,
++                                               env, fp);
+       }
+       up_read(&env->bpf_progs.lock);
+@@ -3177,7 +3177,7 @@ static int process_bpf_prog_info(struct feat_fd *ff, void *data __maybe_unused)
+               /* after reading from file, translate offset to address */
+               bpil_offs_to_addr(info_linear);
+               info_node->info_linear = info_linear;
+-              perf_env__insert_bpf_prog_info(env, info_node);
++              __perf_env__insert_bpf_prog_info(env, info_node);
+       }
+       up_write(&env->bpf_progs.lock);
+@@ -3224,7 +3224,7 @@ static int process_bpf_btf(struct feat_fd *ff, void *data __maybe_unused)
+               if (__do_read(ff, node->data, data_size))
+                       goto out;
+-              perf_env__insert_btf(env, node);
++              __perf_env__insert_btf(env, node);
+               node = NULL;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-genelf-set-elf-program-header-addresses-properl.patch b/queue-6.6/perf-genelf-set-elf-program-header-addresses-properl.patch
new file mode 100644 (file)
index 0000000..b959e65
--- /dev/null
@@ -0,0 +1,50 @@
+From 08287f055cc616fcee5fe507130109946ffccf1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 23:05:44 -0800
+Subject: perf genelf: Set ELF program header addresses properly
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 1af478903fc48c1409a8dd6b698383b62387adf1 ]
+
+The text section starts after the ELF headers so PHDR.p_vaddr and
+others should have the correct addresses.
+
+Fixes: babd04386b1df8c3 ("perf jit: Include program header in ELF files")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Fangrui Song <maskray@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Lieven Hey <lieven.hey@kdab.com>
+Cc: Milian Wolff <milian.wolff@kdab.com>
+Cc: Pablo Galindo <pablogsal@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231212070547.612536-2-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/genelf.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c
+index fefc72066c4e..ac17a3cb59dc 100644
+--- a/tools/perf/util/genelf.c
++++ b/tools/perf/util/genelf.c
+@@ -293,9 +293,9 @@ jit_write_elf(int fd, uint64_t load_addr, const char *sym,
+        */
+       phdr = elf_newphdr(e, 1);
+       phdr[0].p_type = PT_LOAD;
+-      phdr[0].p_offset = 0;
+-      phdr[0].p_vaddr = 0;
+-      phdr[0].p_paddr = 0;
++      phdr[0].p_offset = GEN_ELF_TEXT_OFFSET;
++      phdr[0].p_vaddr = GEN_ELF_TEXT_OFFSET;
++      phdr[0].p_paddr = GEN_ELF_TEXT_OFFSET;
+       phdr[0].p_filesz = csize;
+       phdr[0].p_memsz = csize;
+       phdr[0].p_flags = PF_X | PF_R;
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-header-fix-one-memory-leakage-in-perf_event__fp.patch b/queue-6.6/perf-header-fix-one-memory-leakage-in-perf_event__fp.patch
new file mode 100644 (file)
index 0000000..a3d9eeb
--- /dev/null
@@ -0,0 +1,57 @@
+From 58bc1ed02b9991395092c2a918981de93c494082 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 16:16:34 +0800
+Subject: perf header: Fix one memory leakage in
+ perf_event__fprintf_event_update()
+
+From: Yicong Yang <yangyicong@hisilicon.com>
+
+[ Upstream commit 813900d19b923fc1b241c1ce292472f68066092b ]
+
+When dump the raw trace by `perf report -D` ASan reports a memory
+leakage in perf_event__fprintf_event_update().
+
+It shows that we allocated a temporary cpumap for dumping the CPUs but
+doesn't release it and it's not used elsewhere. Fix this by free the
+cpumap after the dumping.
+
+Fixes: c853f9394b7bc189 ("perf tools: Add perf_event__fprintf_event_update function")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Jonathan Cameron <jonathan.cameron@huawei.com>
+Cc: Junhao He <hejunhao3@huawei.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: linuxarm@huawei.com
+Link: https://lore.kernel.org/r/20231207081635.8427-2-yangyicong@huawei.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/header.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
+index 41032243774e..f6035c219b41 100644
+--- a/tools/perf/util/header.c
++++ b/tools/perf/util/header.c
+@@ -4363,9 +4363,10 @@ size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp)
+               ret += fprintf(fp, "... ");
+               map = cpu_map__new_data(&ev->cpus.cpus);
+-              if (map)
++              if (map) {
+                       ret += cpu_map__fprintf(map, fp);
+-              else
++                      perf_cpu_map__put(map);
++              } else
+                       ret += fprintf(fp, "failed to get cpus\n");
+               break;
+       default:
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-header-fix-segfault-on-build_mem_topology-error.patch b/queue-6.6/perf-header-fix-segfault-on-build_mem_topology-error.patch
new file mode 100644 (file)
index 0000000..40d9916
--- /dev/null
@@ -0,0 +1,84 @@
+From e1ea4b1f51cea423772557f1a240633f340567b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 23 Nov 2023 09:58:41 +0200
+Subject: perf header: Fix segfault on build_mem_topology() error path
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit 70df07838fc1c0acfab3325ae79014e241a88bdf ]
+
+Do not increase the node count unless a node has been successfully read,
+because it can lead to a segfault if an error occurs.
+
+For example, if perf exceeds the open file limit in memory_node__read(),
+which, on a test system, could be made to happen by setting the file limit
+to exactly 32:
+
+ Before:
+
+  $ ulimit -n 32
+  $ perf mem record --all-user -- sleep 1
+  [ perf record: Woken up 1 times to write data ]
+  failed: can't open memory sysfs data
+  perf: Segmentation fault
+  Obtained 14 stack frames.
+  perf(sighandler_dump_stack+0x48) [0x55f4b1f59558]
+  /lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7f4ba1c42520]
+  /lib/x86_64-linux-gnu/libc.so.6(free+0x1e) [0x7f4ba1ca53fe]
+  perf(+0x178ff4) [0x55f4b1f48ff4]
+  perf(+0x179a70) [0x55f4b1f49a70]
+  perf(+0x17ef5d) [0x55f4b1f4ef5d]
+  perf(+0x85c0b) [0x55f4b1e55c0b]
+  perf(cmd_record+0xe1d) [0x55f4b1e5920d]
+  perf(cmd_mem+0xc96) [0x55f4b1e80e56]
+  perf(+0x130460) [0x55f4b1f00460]
+  perf(main+0x689) [0x55f4b1e427d9]
+  /lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7f4ba1c29d90]
+  /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7f4ba1c29e40]
+  perf(_start+0x25) [0x55f4b1e42a25]
+  Segmentation fault (core dumped)
+  $
+
+After:
+
+  $ ulimit -n 32
+  $ perf mem record --all-user -- sleep 1
+  [ perf record: Woken up 1 times to write data ]
+  failed: can't open memory sysfs data
+  [ perf record: Captured and wrote 0.005 MB perf.data (11 samples) ]
+  $
+
+Fixes: f8e502b9d1b3b197 ("perf header: Ensure bitmaps are freed")
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Acked-by: Ian Rogers <irogers@google.com>
+Cc: German Gomez <german.gomez@arm.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20231123075848.9652-2-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/header.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
+index d812e1e371a7..41032243774e 100644
+--- a/tools/perf/util/header.c
++++ b/tools/perf/util/header.c
+@@ -1444,7 +1444,9 @@ static int build_mem_topology(struct memory_node **nodesp, u64 *cntp)
+                       nodes = new_nodes;
+                       size += 4;
+               }
+-              ret = memory_node__read(&nodes[cnt++], idx);
++              ret = memory_node__read(&nodes[cnt], idx);
++              if (!ret)
++                      cnt += 1;
+       }
+ out:
+       closedir(dir);
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-hisi-ptt-fix-one-memory-leakage-in-hisi_ptt_pro.patch b/queue-6.6/perf-hisi-ptt-fix-one-memory-leakage-in-hisi_ptt_pro.patch
new file mode 100644 (file)
index 0000000..780c5bf
--- /dev/null
@@ -0,0 +1,50 @@
+From 29342313c71a2ae469f86cac738ad7582c68f479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 16:16:35 +0800
+Subject: perf hisi-ptt: Fix one memory leakage in
+ hisi_ptt_process_auxtrace_event()
+
+From: Yicong Yang <yangyicong@hisilicon.com>
+
+[ Upstream commit 1bc479d665bc25a9a4e8168d5b400a47491511f9 ]
+
+ASan complains a memory leakage in hisi_ptt_process_auxtrace_event()
+that the data buffer is not freed. Since currently we only support the
+raw dump trace mode, the data buffer is used only within this function.
+So fix this by freeing the data buffer before going out.
+
+Fixes: 5e91e57e68090c0e ("perf auxtrace arm64: Add support for parsing HiSilicon PCIe Trace packet")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
+Acked-by: Namhyung Kim <Namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Jonathan Cameron <jonathan.cameron@huawei.com>
+Cc: Junhao He <hejunhao3@huawei.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Qi Liu <liuqi115@huawei.com>
+Link: https://lore.kernel.org/r/20231207081635.8427-3-yangyicong@huawei.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/hisi-ptt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/tools/perf/util/hisi-ptt.c b/tools/perf/util/hisi-ptt.c
+index 45b614bb73bf..764d660d30e2 100644
+--- a/tools/perf/util/hisi-ptt.c
++++ b/tools/perf/util/hisi-ptt.c
+@@ -121,6 +121,7 @@ static int hisi_ptt_process_auxtrace_event(struct perf_session *session,
+       if (dump_trace)
+               hisi_ptt_dump_event(ptt, data, size);
++      free(data);
+       return 0;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-mem-fix-error-on-hybrid-related-to-availability.patch b/queue-6.6/perf-mem-fix-error-on-hybrid-related-to-availability.patch
new file mode 100644 (file)
index 0000000..dcc5c2f
--- /dev/null
@@ -0,0 +1,131 @@
+From 6e4ef589dd788551ee9f2b8090697d855077375a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Nov 2023 12:39:40 -0800
+Subject: perf mem: Fix error on hybrid related to availability of mem event in
+ a PMU
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+[ Upstream commit a4320085a6c694326dd8db46f563d52d1a826f07 ]
+
+The below error can be triggered on a hybrid machine.
+
+ $ perf mem record -t load sleep 1
+ event syntax error: 'breakpoint/mem-loads,ldlat=30/P'
+                                \___ Bad event or PMU
+
+ Unable to find PMU or event on a PMU of 'breakpoint'
+
+In the perf_mem_events__record_args(), the current perf never checks the
+availability of a mem event on a given PMU. All the PMUs will be added
+to the perf mem event list. Perf errors out for the unsupported PMU.
+
+Extend perf_mem_event__supported() and take a PMU into account. Check
+the mem event for each PMU before adding it to the perf mem event list.
+
+Optimize the perf_mem_events__init() a little bit. The function is to
+check whether the mem events are supported in the system. It doesn't
+need to scan all PMUs. Just return with the first supported PMU is good
+enough.
+
+Fixes: 5752c20f3787c9bc ("perf mem: Scan all PMUs instead of just core ones")
+Reported-by: Ammy Yi <ammy.yi@intel.com>
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Tested-by: Ammy Yi <ammy.yi@intel.com>
+Acked-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Ravi Bangoria <ravi.bangoria@amd.com>
+Link: https://lore.kernel.org/r/20231128203940.3964287-1-kan.liang@linux.intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/mem-events.c | 25 ++++++++++++++-----------
+ 1 file changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/tools/perf/util/mem-events.c b/tools/perf/util/mem-events.c
+index 954b235e12e5..3a2e3687878c 100644
+--- a/tools/perf/util/mem-events.c
++++ b/tools/perf/util/mem-events.c
+@@ -100,11 +100,14 @@ int perf_mem_events__parse(const char *str)
+       return -1;
+ }
+-static bool perf_mem_event__supported(const char *mnt, char *sysfs_name)
++static bool perf_mem_event__supported(const char *mnt, struct perf_pmu *pmu,
++                                    struct perf_mem_event *e)
+ {
++      char sysfs_name[100];
+       char path[PATH_MAX];
+       struct stat st;
++      scnprintf(sysfs_name, sizeof(sysfs_name), e->sysfs_name, pmu->name);
+       scnprintf(path, PATH_MAX, "%s/devices/%s", mnt, sysfs_name);
+       return !stat(path, &st);
+ }
+@@ -120,7 +123,6 @@ int perf_mem_events__init(void)
+       for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
+               struct perf_mem_event *e = perf_mem_events__ptr(j);
+-              char sysfs_name[100];
+               struct perf_pmu *pmu = NULL;
+               /*
+@@ -136,12 +138,12 @@ int perf_mem_events__init(void)
+                * of core PMU.
+                */
+               while ((pmu = perf_pmus__scan(pmu)) != NULL) {
+-                      scnprintf(sysfs_name, sizeof(sysfs_name), e->sysfs_name, pmu->name);
+-                      e->supported |= perf_mem_event__supported(mnt, sysfs_name);
++                      e->supported |= perf_mem_event__supported(mnt, pmu, e);
++                      if (e->supported) {
++                              found = true;
++                              break;
++                      }
+               }
+-
+-              if (e->supported)
+-                      found = true;
+       }
+       return found ? 0 : -ENOENT;
+@@ -167,13 +169,10 @@ static void perf_mem_events__print_unsupport_hybrid(struct perf_mem_event *e,
+                                                   int idx)
+ {
+       const char *mnt = sysfs__mount();
+-      char sysfs_name[100];
+       struct perf_pmu *pmu = NULL;
+       while ((pmu = perf_pmus__scan(pmu)) != NULL) {
+-              scnprintf(sysfs_name, sizeof(sysfs_name), e->sysfs_name,
+-                        pmu->name);
+-              if (!perf_mem_event__supported(mnt, sysfs_name)) {
++              if (!perf_mem_event__supported(mnt, pmu, e)) {
+                       pr_err("failed: event '%s' not supported\n",
+                              perf_mem_events__name(idx, pmu->name));
+               }
+@@ -183,6 +182,7 @@ static void perf_mem_events__print_unsupport_hybrid(struct perf_mem_event *e,
+ int perf_mem_events__record_args(const char **rec_argv, int *argv_nr,
+                                char **rec_tmp, int *tmp_nr)
+ {
++      const char *mnt = sysfs__mount();
+       int i = *argv_nr, k = 0;
+       struct perf_mem_event *e;
+@@ -211,6 +211,9 @@ int perf_mem_events__record_args(const char **rec_argv, int *argv_nr,
+                       while ((pmu = perf_pmus__scan(pmu)) != NULL) {
+                               const char *s = perf_mem_events__name(j, pmu->name);
++                              if (!perf_mem_event__supported(mnt, pmu, e))
++                                      continue;
++
+                               rec_argv[i++] = "-e";
+                               if (s) {
+                                       char *copy = strdup(s);
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-stat-exit-perf-stat-if-parse-groups-fails.patch b/queue-6.6/perf-stat-exit-perf-stat-if-parse-groups-fails.patch
new file mode 100644 (file)
index 0000000..5ddcf1b
--- /dev/null
@@ -0,0 +1,72 @@
+From 4d6a9741e74dafb018014cd1e4d8105b7b22687e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 10:35:33 -0800
+Subject: perf stat: Exit perf stat if parse groups fails
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit 0713ab3bd169da82c35eefd012b07b715e4ebcf7 ]
+
+Metrics were added by a callback but commit a4b8cfcabb1d90ec ("perf
+stat: Delay metric parsing") postponed this to allow optimizations based
+on the CPU configuration.
+
+In doing so it stopped errors in metric parsing from causing 'perf stat'
+termination.
+
+This change adds the termination for bad metric names back in.
+
+Fixes: a4b8cfcabb1d90ec ("perf stat: Delay metric parsing")
+Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Closes: https://lore.kernel.org/lkml/ZXByT1K6enTh2EHT@kernel.org/
+Link: https://lore.kernel.org/r/20231206183533.972028-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/builtin-stat.c | 18 +++++++++++-------
+ 1 file changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
+index a3af805a1d57..78c104922181 100644
+--- a/tools/perf/builtin-stat.c
++++ b/tools/perf/builtin-stat.c
+@@ -2695,15 +2695,19 @@ int cmd_stat(int argc, const char **argv)
+        */
+       if (metrics) {
+               const char *pmu = parse_events_option_args.pmu_filter ?: "all";
++              int ret = metricgroup__parse_groups(evsel_list, pmu, metrics,
++                                              stat_config.metric_no_group,
++                                              stat_config.metric_no_merge,
++                                              stat_config.metric_no_threshold,
++                                              stat_config.user_requested_cpu_list,
++                                              stat_config.system_wide,
++                                              &stat_config.metric_events);
+-              metricgroup__parse_groups(evsel_list, pmu, metrics,
+-                                      stat_config.metric_no_group,
+-                                      stat_config.metric_no_merge,
+-                                      stat_config.metric_no_threshold,
+-                                      stat_config.user_requested_cpu_list,
+-                                      stat_config.system_wide,
+-                                      &stat_config.metric_events);
+               zfree(&metrics);
++              if (ret) {
++                      status = ret;
++                      goto out;
++              }
+       }
+       if (add_default_attributes())
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-stat-fix-hard-coded-ll-miss-units.patch b/queue-6.6/perf-stat-fix-hard-coded-ll-miss-units.patch
new file mode 100644 (file)
index 0000000..4c8c832
--- /dev/null
@@ -0,0 +1,47 @@
+From dc01dc8b493a8d421e932fb1648c428a7e1f425d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 10:12:41 -0800
+Subject: perf stat: Fix hard coded LL miss units
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit f2567e12a090f0eb22553a4468d4c4fe04aad906 ]
+
+Copy-paste error where LL cache misses are reported as l1i.
+
+Fixes: 0a57b910807ad163 ("perf stat: Use counts rather than saved_value")
+Suggested-by: Guillaume Endignoux <guillaumee@google.com>
+Reviewed-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Ian Rogers <irogers@google.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231211181242.1721059-1-irogers@google.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/stat-shadow.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c
+index 1c5c3eeba4cf..e31426167852 100644
+--- a/tools/perf/util/stat-shadow.c
++++ b/tools/perf/util/stat-shadow.c
+@@ -264,7 +264,7 @@ static void print_ll_miss(struct perf_stat_config *config,
+       static const double color_ratios[3] = {20.0, 10.0, 5.0};
+       print_ratio(config, evsel, aggr_idx, misses, out, STAT_LL_CACHE, color_ratios,
+-                  "of all L1-icache accesses");
++                  "of all LL-cache accesses");
+ }
+ static void print_dtlb_miss(struct perf_stat_config *config,
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-test-record-user-regs-fix-mask-for-vg-register.patch b/queue-6.6/perf-test-record-user-regs-fix-mask-for-vg-register.patch
new file mode 100644 (file)
index 0000000..788f73e
--- /dev/null
@@ -0,0 +1,68 @@
+From 8ce6f1e46954eb80efccfb8896e763f7ab6d9432 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 20:46:17 +0100
+Subject: perf test record user-regs: Fix mask for vg register
+
+From: Veronika Molnarova <vmolnaro@redhat.com>
+
+[ Upstream commit 28b01743ca752cea5ab182297d8b912b22f2a2d1 ]
+
+The 'vg' register for arm64 shows up in --user_regs as available when
+masking the variable AT_HWCAP with 1 << 22 returns '1' as done in
+perf_regs.c.
+
+However, in subtests for support of SVE, the check for the 'vg' register
+is done by masking the variable AT_HWCAP with the value 0x200000 which
+is equals to 1 << 21 instead of 1 << 22.
+
+This results in inconsistencies on certain systems where the test
+expects that the 'vg' register is not operational when it is, and
+vice-versa.
+
+During the testing on a machine that the test expected not to have the
+'vg' register available, 'perf record' with the option --user-regs
+showed records for the 'vg' register together with all of the others,
+which means that the mask for the subtest of perf_event_attr is off by
+one.
+
+Change the value of the mask from 0x200000 to 0x400000 to correct it.
+
+Fixes: 9440ebdc333dd12e ("perf test arm64: Add attr tests for new VG register")
+Reviewed-by: Leo Yan <leo.yan@linaro.org>
+Signed-off-by: Veronika Molnarova <vmolnaro@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Michael Petlan <mpetlan@redhat.com>
+Link: https://lore.kernel.org/r/20231201194617.13012-1-vmolnaro@redhat.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/attr/test-record-user-regs-no-sve-aarch64 | 2 +-
+ tools/perf/tests/attr/test-record-user-regs-sve-aarch64    | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/perf/tests/attr/test-record-user-regs-no-sve-aarch64 b/tools/perf/tests/attr/test-record-user-regs-no-sve-aarch64
+index fbb065842880..bed765450ca9 100644
+--- a/tools/perf/tests/attr/test-record-user-regs-no-sve-aarch64
++++ b/tools/perf/tests/attr/test-record-user-regs-no-sve-aarch64
+@@ -6,4 +6,4 @@ args    = --no-bpf-event --user-regs=vg kill >/dev/null 2>&1
+ ret     = 129
+ test_ret = true
+ arch    = aarch64
+-auxv    = auxv["AT_HWCAP"] & 0x200000 == 0
++auxv    = auxv["AT_HWCAP"] & 0x400000 == 0
+diff --git a/tools/perf/tests/attr/test-record-user-regs-sve-aarch64 b/tools/perf/tests/attr/test-record-user-regs-sve-aarch64
+index c598c803221d..a65113cd7311 100644
+--- a/tools/perf/tests/attr/test-record-user-regs-sve-aarch64
++++ b/tools/perf/tests/attr/test-record-user-regs-sve-aarch64
+@@ -6,7 +6,7 @@ args    = --no-bpf-event --user-regs=vg kill >/dev/null 2>&1
+ ret     = 1
+ test_ret = true
+ arch    = aarch64
+-auxv    = auxv["AT_HWCAP"] & 0x200000 == 0x200000
++auxv    = auxv["AT_HWCAP"] & 0x400000 == 0x400000
+ kernel_since = 6.1
+ [event:base-record]
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-test-remove-atomics-from-test_loop-to-avoid-tes.patch b/queue-6.6/perf-test-remove-atomics-from-test_loop-to-avoid-tes.patch
new file mode 100644 (file)
index 0000000..a2e8b59
--- /dev/null
@@ -0,0 +1,58 @@
+From ac5a1760cbd37ca74bc1e3082c272b9ef277a551 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 2 Nov 2023 16:22:24 +0000
+Subject: perf test: Remove atomics from test_loop to avoid test failures
+
+From: Nick Forrington <nick.forrington@arm.com>
+
+[ Upstream commit 72b4ca7e993e94f09bcf6d19fc385a2e8060c71f ]
+
+The current use of atomics can lead to test failures, as tests (such as
+tests/shell/record.sh) search for samples with "test_loop" as the
+top-most stack frame, but find frames related to the atomic operation
+(e.g. __aarch64_ldadd4_relax).
+
+This change simply removes the "count" variable, as it is not necessary.
+
+Fixes: 1962ab6f6e0b39e4 ("perf test workload thloop: Make count increments atomic")
+Reviewed-by: James Clark <james.clark@arm.com>
+Signed-off-by: Nick Forrington <nick.forrington@arm.com>
+Acked-by: Leo Yan <leo.yan@linaro.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20231102162225.50028-1-nick.forrington@arm.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/tests/workloads/thloop.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/tools/perf/tests/workloads/thloop.c b/tools/perf/tests/workloads/thloop.c
+index af05269c2eb8..457b29f91c3e 100644
+--- a/tools/perf/tests/workloads/thloop.c
++++ b/tools/perf/tests/workloads/thloop.c
+@@ -7,7 +7,6 @@
+ #include "../tests.h"
+ static volatile sig_atomic_t done;
+-static volatile unsigned count;
+ /* We want to check this symbol in perf report */
+ noinline void test_loop(void);
+@@ -19,8 +18,7 @@ static void sighandler(int sig __maybe_unused)
+ noinline void test_loop(void)
+ {
+-      while (!done)
+-              __atomic_fetch_add(&count, 1, __ATOMIC_RELAXED);
++      while (!done);
+ }
+ static void *thfunc(void *arg)
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-unwind-libdw-handle-jit-generated-dsos-properly.patch b/queue-6.6/perf-unwind-libdw-handle-jit-generated-dsos-properly.patch
new file mode 100644 (file)
index 0000000..f1fcdeb
--- /dev/null
@@ -0,0 +1,94 @@
+From ce8c4012225519806613a8470e85c43c01aa8436 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 23:05:45 -0800
+Subject: perf unwind-libdw: Handle JIT-generated DSOs properly
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit c966d23a351a33f8a977fd7efbb6f467132f7383 ]
+
+Usually DSOs are mapped from the beginning of the file, so the base
+address of the DSO can be calculated by map->start - map->pgoff.
+
+However, JIT DSOs which are generated by `perf inject -j`, are mapped
+only the code segment.  This makes unwind-libdw code confusing and
+rejects processing unwinds in the JIT DSOs.  It should use the map
+start address as base for them to fix the confusion.
+
+Fixes: 1fe627da30331024 ("perf unwind: Take pgoff into account when reporting elf to libdwfl")
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Fangrui Song <maskray@google.com>
+Cc: Ian Rogers <irogers@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Milian Wolff <milian.wolff@kdab.com>
+Cc: Pablo Galindo <pablogsal@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231212070547.612536-3-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/unwind-libdw.c | 21 +++++++++++++++++----
+ 1 file changed, 17 insertions(+), 4 deletions(-)
+
+diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c
+index 8554db3fc0d7..6013335a8dae 100644
+--- a/tools/perf/util/unwind-libdw.c
++++ b/tools/perf/util/unwind-libdw.c
+@@ -46,6 +46,7 @@ static int __report_module(struct addr_location *al, u64 ip,
+ {
+       Dwfl_Module *mod;
+       struct dso *dso = NULL;
++      Dwarf_Addr base;
+       /*
+        * Some callers will use al->sym, so we can't just use the
+        * cheaper thread__find_map() here.
+@@ -58,13 +59,25 @@ static int __report_module(struct addr_location *al, u64 ip,
+       if (!dso)
+               return 0;
++      /*
++       * The generated JIT DSO files only map the code segment without
++       * ELF headers.  Since JIT codes used to be packed in a memory
++       * segment, calculating the base address using pgoff falls into
++       * a different code in another DSO.  So just use the map->start
++       * directly to pick the correct one.
++       */
++      if (!strncmp(dso->long_name, "/tmp/jitted-", 12))
++              base = map__start(al->map);
++      else
++              base = map__start(al->map) - map__pgoff(al->map);
++
+       mod = dwfl_addrmodule(ui->dwfl, ip);
+       if (mod) {
+               Dwarf_Addr s;
+               dwfl_module_info(mod, NULL, &s, NULL, NULL, NULL, NULL, NULL);
+-              if (s != map__start(al->map) - map__pgoff(al->map))
+-                      mod = 0;
++              if (s != base)
++                      mod = NULL;
+       }
+       if (!mod) {
+@@ -72,14 +85,14 @@ static int __report_module(struct addr_location *al, u64 ip,
+               __symbol__join_symfs(filename, sizeof(filename), dso->long_name);
+               mod = dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1,
+-                                    map__start(al->map) - map__pgoff(al->map), false);
++                                    base, false);
+       }
+       if (!mod) {
+               char filename[PATH_MAX];
+               if (dso__build_id_filename(dso, filename, sizeof(filename), false))
+                       mod = dwfl_report_elf(ui->dwfl, dso->short_name, filename, -1,
+-                                            map__start(al->map) - map__pgoff(al->map), false);
++                                            base, false);
+       }
+       if (mod) {
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-unwind-libunwind-fix-base-address-for-.eh_frame.patch b/queue-6.6/perf-unwind-libunwind-fix-base-address-for-.eh_frame.patch
new file mode 100644 (file)
index 0000000..a3de13c
--- /dev/null
@@ -0,0 +1,49 @@
+From ed6f95cdb9b9a90c73855d336fe47b834d9ade4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 23:05:46 -0800
+Subject: perf unwind-libunwind: Fix base address for .eh_frame
+
+From: Namhyung Kim <namhyung@kernel.org>
+
+[ Upstream commit 4fb54994b2360ab5029ee3a959161f6fe6bbb349 ]
+
+The base address of a DSO mapping should start at the start of the file.
+Usually DSOs are mapped from the pgoff 0 so it doesn't matter when it
+uses the start of the map address.
+
+But generated DSOs for JIT codes doesn't start from the 0 so it should
+subtract the offset to calculate the .eh_frame table offsets correctly.
+
+Fixes: dc2cf4ca866f5715 ("perf unwind: Fix segbase for ld.lld linked objects")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Fangrui Song <maskray@google.com>
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: Milian Wolff <milian.wolff@kdab.com>
+Cc: Pablo Galindo <pablogsal@gmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Link: https://lore.kernel.org/r/20231212070547.612536-4-namhyung@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/unwind-libunwind-local.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c
+index c0641882fd2f..5e5c3395a499 100644
+--- a/tools/perf/util/unwind-libunwind-local.c
++++ b/tools/perf/util/unwind-libunwind-local.c
+@@ -327,7 +327,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct unwind_info *ui,
+       maps__for_each_entry(thread__maps(ui->thread), map_node) {
+               struct map *map = map_node->map;
+-              u64 start = map__start(map);
++              u64 start = map__start(map) - map__pgoff(map);
+               if (map__dso(map) == dso && start < base_addr)
+                       base_addr = start;
+-- 
+2.43.0
+
diff --git a/queue-6.6/perf-vendor-events-arm64-ampereone-rename-bpu_flush_.patch b/queue-6.6/perf-vendor-events-arm64-ampereone-rename-bpu_flush_.patch
new file mode 100644 (file)
index 0000000..7a3a5e5
--- /dev/null
@@ -0,0 +1,53 @@
+From e549a963f136695b0ec09674d2965cc0ba2b407e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 18:15:49 -0800
+Subject: perf vendor events arm64 AmpereOne: Rename BPU_FLUSH_MEM_FAULT to
+ GPC_FLUSH_MEM_FAULT
+
+From: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+
+[ Upstream commit 10a149e4b4a9187940adbfff0f216ccb5a15aa41 ]
+
+The documentation wrongly called the event as BPU_FLUSH_MEM_FAULT and now
+has been fixed. Correct the name in the perf tool as well.
+
+Fixes: a9650b7f6fc09d16 ("perf vendor events arm64: Add AmpereOne core PMU events")
+Reviewed-by: Ian Rogers <irogers@google.com>
+Signed-off-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Cc: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Ilkka Koskinen <ilkka@os.amperecomputing.com>
+Cc: Ingo Molnar <mingo@redhat.com>
+Cc: James Clark <james.clark@arm.com>
+Cc: Jiri Olsa <jolsa@kernel.org>
+Cc: John Garry <john.g.garry@oracle.com>
+Cc: Leo Yan <leo.yan@linaro.org>
+Cc: linux-arm-kernel@lists.infradead.org
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mike Leach <mike.leach@linaro.org>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Will Deacon <will@kernel.org>
+Link: https://lore.kernel.org/r/20231201021550.1109196-3-ilkka@os.amperecomputing.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../pmu-events/arch/arm64/ampere/ampereone/core-imp-def.json    | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/perf/pmu-events/arch/arm64/ampere/ampereone/core-imp-def.json b/tools/perf/pmu-events/arch/arm64/ampere/ampereone/core-imp-def.json
+index 88b23b85e33c..879ff21e0b17 100644
+--- a/tools/perf/pmu-events/arch/arm64/ampere/ampereone/core-imp-def.json
++++ b/tools/perf/pmu-events/arch/arm64/ampere/ampereone/core-imp-def.json
+@@ -110,7 +110,7 @@
+     {
+         "PublicDescription": "Flushes due to memory hazards",
+         "EventCode": "0x121",
+-        "EventName": "BPU_FLUSH_MEM_FAULT",
++        "EventName": "GPC_FLUSH_MEM_FAULT",
+         "BriefDescription": "Flushes due to memory hazards"
+     },
+     {
+-- 
+2.43.0
+
diff --git a/queue-6.6/power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch b/queue-6.6/power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch
new file mode 100644 (file)
index 0000000..6989f21
--- /dev/null
@@ -0,0 +1,55 @@
+From 87be035ee44685ba10060045191cbebe410b956c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 12:18:23 +0800
+Subject: power: supply: bq256xx: fix some problem in bq256xx_hw_init
+
+From: Su Hui <suhui@nfschina.com>
+
+[ Upstream commit b55d073e6501dc6077edaa945a6dad8ac5c8bbab ]
+
+smatch complains that there is a buffer overflow and clang complains
+'ret' is never read.
+
+Smatch error:
+drivers/power/supply/bq256xx_charger.c:1578 bq256xx_hw_init() error:
+buffer overflow 'bq256xx_watchdog_time' 4 <= 4
+
+Clang static checker:
+Value stored to 'ret' is never read.
+
+Add check for buffer overflow and error code from regmap_update_bits().
+
+Fixes: 32e4978bb920 ("power: supply: bq256xx: Introduce the BQ256XX charger driver")
+Signed-off-by: Su Hui <suhui@nfschina.com>
+Link: https://lore.kernel.org/r/20231116041822.1378758-1-suhui@nfschina.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/bq256xx_charger.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/bq256xx_charger.c b/drivers/power/supply/bq256xx_charger.c
+index 82d3cd5ee2f9..c8368dae69c7 100644
+--- a/drivers/power/supply/bq256xx_charger.c
++++ b/drivers/power/supply/bq256xx_charger.c
+@@ -1574,13 +1574,16 @@ static int bq256xx_hw_init(struct bq256xx_device *bq)
+                       wd_reg_val = i;
+                       break;
+               }
+-              if (bq->watchdog_timer > bq256xx_watchdog_time[i] &&
++              if (i + 1 < BQ256XX_NUM_WD_VAL &&
++                  bq->watchdog_timer > bq256xx_watchdog_time[i] &&
+                   bq->watchdog_timer < bq256xx_watchdog_time[i + 1])
+                       wd_reg_val = i;
+       }
+       ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1,
+                                BQ256XX_WATCHDOG_MASK, wd_reg_val <<
+                                               BQ256XX_WDT_BIT_SHIFT);
++      if (ret)
++              return ret;
+       ret = power_supply_get_battery_info(bq->charger, &bat_info);
+       if (ret == -ENOMEM)
+-- 
+2.43.0
+
diff --git a/queue-6.6/power-supply-cw2015-correct-time_to_empty-units-in-s.patch b/queue-6.6/power-supply-cw2015-correct-time_to_empty-units-in-s.patch
new file mode 100644 (file)
index 0000000..e87b426
--- /dev/null
@@ -0,0 +1,38 @@
+From 9017c0b800ec73e4bf2bdc4fd513bbadb13a95d2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 11 Nov 2023 23:17:04 +0100
+Subject: power: supply: cw2015: correct time_to_empty units in sysfs
+
+From: Jan Palus <jpalus@fastmail.com>
+
+[ Upstream commit f37669119423ca852ca855b24732f25c0737aa57 ]
+
+RRT_ALRT register holds remaining battery time in minutes therefore it
+needs to be scaled accordingly when exposing TIME_TO_EMPTY via sysfs
+expressed in seconds
+
+Fixes: b4c7715c10c1 ("power: supply: add CellWise cw2015 fuel gauge driver")
+Signed-off-by: Jan Palus <jpalus@fastmail.com>
+Link: https://lore.kernel.org/r/20231111221704.5579-1-jpalus@fastmail.com
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/cw2015_battery.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c
+index bb29e9ebd24a..99f3ccdc30a6 100644
+--- a/drivers/power/supply/cw2015_battery.c
++++ b/drivers/power/supply/cw2015_battery.c
+@@ -491,7 +491,7 @@ static int cw_battery_get_property(struct power_supply *psy,
+       case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+               if (cw_battery_valid_time_to_empty(cw_bat))
+-                      val->intval = cw_bat->time_to_empty;
++                      val->intval = cw_bat->time_to_empty * 60;
+               else
+                       val->intval = 0;
+               break;
+-- 
+2.43.0
+
diff --git a/queue-6.6/power-supply-fix-null-pointer-dereference-in-smb2_pr.patch b/queue-6.6/power-supply-fix-null-pointer-dereference-in-smb2_pr.patch
new file mode 100644 (file)
index 0000000..28872f5
--- /dev/null
@@ -0,0 +1,43 @@
+From 4298197e1f737d21a27e7fcd05ff201e174e3713 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Nov 2023 15:50:21 +0800
+Subject: power: supply: Fix null pointer dereference in smb2_probe
+
+From: Kunwu Chan <chentao@kylinos.cn>
+
+[ Upstream commit 88f04bc3e737155e13caddf0ba8ed19db87f0212 ]
+
+devm_kasprintf and devm_kzalloc return a pointer to dynamically
+allocated memory which can be NULL upon failure.
+
+Fixes: 8648aeb5d7b7 ("power: supply: add Qualcomm PMI8998 SMB2 Charger driver")
+Signed-off-by: Kunwu Chan <chentao@kylinos.cn>
+Link: https://lore.kernel.org/r/20231124075021.1335289-1-chentao@kylinos.cn
+Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/power/supply/qcom_pmi8998_charger.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/drivers/power/supply/qcom_pmi8998_charger.c b/drivers/power/supply/qcom_pmi8998_charger.c
+index 10f4dd0caca1..22c7c0e7c522 100644
+--- a/drivers/power/supply/qcom_pmi8998_charger.c
++++ b/drivers/power/supply/qcom_pmi8998_charger.c
+@@ -973,10 +973,14 @@ static int smb2_probe(struct platform_device *pdev)
+       supply_config.of_node = pdev->dev.of_node;
+       desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL);
++      if (!desc)
++              return -ENOMEM;
+       memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc));
+       desc->name =
+               devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger",
+                              (const char *)device_get_match_data(chip->dev));
++      if (!desc->name)
++              return -ENOMEM;
+       chip->chg_psy =
+               devm_power_supply_register(chip->dev, desc, &supply_config);
+-- 
+2.43.0
+
diff --git a/queue-6.6/r8152-choose-our-usb-config-with-choose_configuratio.patch b/queue-6.6/r8152-choose-our-usb-config-with-choose_configuratio.patch
new file mode 100644 (file)
index 0000000..c24a95a
--- /dev/null
@@ -0,0 +1,80 @@
+From 0b0dd4e71eeae2e0e3ef2f70ef98708f586769c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 10:29:52 -0800
+Subject: r8152: Choose our USB config with choose_configuration() rather than
+ probe()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit aa4f2b3e418e8673e55145de8b8016a7a9920306 ]
+
+If you deauthorize the r8152 device (by writing 0 to the "authorized"
+field in sysfs) and then reauthorize it (by writing a 1) then it no
+longer works. This is because when you do the above we lose the
+special configuration that we set in rtl8152_cfgselector_probe().
+Deauthorizing causes the config to be set to -1 and then reauthorizing
+runs the default logic for choosing the best config.
+
+I made an attempt to fix it so that the config is kept across
+deauthorizing / reauthorizing [1] but it was a bit ugly.
+
+Let's instead use the new USB core feature to override
+choose_configuration().
+
+This patch relies upon the patches ("usb: core: Don't force USB
+generic_subclass drivers to define probe()") and ("usb: core: Allow
+subclassed USB drivers to override usb_choose_configuration()")
+
+[1] https://lore.kernel.org/r/20231130154337.1.Ie00e07f07f87149c9ce0b27ae4e26991d307e14b@changeid
+
+Fixes: ec51fbd1b8a2 ("r8152: add USB device driver for config selection")
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Grant Grundler <grundler@chromium.org>
+Link: https://lore.kernel.org/r/20231201102946.v2.3.Ie00e07f07f87149c9ce0b27ae4e26991d307e14b@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/usb/r8152.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
+index 127b34dcc5b3..cca5b81c8b18 100644
+--- a/drivers/net/usb/r8152.c
++++ b/drivers/net/usb/r8152.c
+@@ -10036,7 +10036,7 @@ static struct usb_driver rtl8152_driver = {
+       .disable_hub_initiated_lpm = 1,
+ };
+-static int rtl8152_cfgselector_probe(struct usb_device *udev)
++static int rtl8152_cfgselector_choose_configuration(struct usb_device *udev)
+ {
+       struct usb_host_config *c;
+       int i, num_configs;
+@@ -10063,19 +10063,13 @@ static int rtl8152_cfgselector_probe(struct usb_device *udev)
+       if (i == num_configs)
+               return -ENODEV;
+-      if (usb_set_configuration(udev, c->desc.bConfigurationValue)) {
+-              dev_err(&udev->dev, "Failed to set configuration %d\n",
+-                      c->desc.bConfigurationValue);
+-              return -ENODEV;
+-      }
+-
+-      return 0;
++      return c->desc.bConfigurationValue;
+ }
+ static struct usb_device_driver rtl8152_cfgselector_driver = {
+-      .name =         MODULENAME "-cfgselector",
+-      .probe =        rtl8152_cfgselector_probe,
+-      .id_table =     rtl8152_table,
++      .name = MODULENAME "-cfgselector",
++      .choose_configuration = rtl8152_cfgselector_choose_configuration,
++      .id_table = rtl8152_table,
+       .generic_subclass = 1,
+       .supports_autosuspend = 1,
+ };
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch b/queue-6.6/riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch
new file mode 100644 (file)
index 0000000..47f4e7c
--- /dev/null
@@ -0,0 +1,110 @@
+From ef1b697623a1099747e04f512c018771a06cd026 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 Dec 2023 10:19:26 +0100
+Subject: riscv: Check if the code to patch lies in the exit section
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 420370f3ae3d3b883813fd3051a38805160b2b9f ]
+
+Otherwise we fall through to vmalloc_to_page() which panics since the
+address does not lie in the vmalloc region.
+
+Fixes: 043cb41a85de ("riscv: introduce interfaces to patch kernel code")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Link: https://lore.kernel.org/r/20231214091926.203439-1-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/sections.h   |  1 +
+ arch/riscv/kernel/patch.c           | 11 ++++++++++-
+ arch/riscv/kernel/vmlinux-xip.lds.S |  2 ++
+ arch/riscv/kernel/vmlinux.lds.S     |  2 ++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
+index 32336e8a17cb..a393d5035c54 100644
+--- a/arch/riscv/include/asm/sections.h
++++ b/arch/riscv/include/asm/sections.h
+@@ -13,6 +13,7 @@ extern char _start_kernel[];
+ extern char __init_data_begin[], __init_data_end[];
+ extern char __init_text_begin[], __init_text_end[];
+ extern char __alt_start[], __alt_end[];
++extern char __exittext_begin[], __exittext_end[];
+ static inline bool is_va_kernel_text(uintptr_t va)
+ {
+diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c
+index 13ee7bf589a1..37e87fdcf6a0 100644
+--- a/arch/riscv/kernel/patch.c
++++ b/arch/riscv/kernel/patch.c
+@@ -14,6 +14,7 @@
+ #include <asm/fixmap.h>
+ #include <asm/ftrace.h>
+ #include <asm/patch.h>
++#include <asm/sections.h>
+ struct patch_insn {
+       void *addr;
+@@ -25,6 +26,14 @@ struct patch_insn {
+ int riscv_patch_in_stop_machine = false;
+ #ifdef CONFIG_MMU
++
++static inline bool is_kernel_exittext(uintptr_t addr)
++{
++      return system_state < SYSTEM_RUNNING &&
++              addr >= (uintptr_t)__exittext_begin &&
++              addr < (uintptr_t)__exittext_end;
++}
++
+ /*
+  * The fix_to_virt(, idx) needs a const value (not a dynamic variable of
+  * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses".
+@@ -35,7 +44,7 @@ static __always_inline void *patch_map(void *addr, const unsigned int fixmap)
+       uintptr_t uintaddr = (uintptr_t) addr;
+       struct page *page;
+-      if (core_kernel_text(uintaddr))
++      if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr))
+               page = phys_to_page(__pa_symbol(addr));
+       else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
+               page = vmalloc_to_page(addr);
+diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S
+index 50767647fbc6..8c3daa1b0531 100644
+--- a/arch/riscv/kernel/vmlinux-xip.lds.S
++++ b/arch/riscv/kernel/vmlinux-xip.lds.S
+@@ -29,10 +29,12 @@ SECTIONS
+       HEAD_TEXT_SECTION
+       INIT_TEXT_SECTION(PAGE_SIZE)
+       /* we have to discard exit text and such at runtime, not link time */
++      __exittext_begin = .;
+       .exit.text :
+       {
+               EXIT_TEXT
+       }
++      __exittext_end = .;
+       .text : {
+               _text = .;
+diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
+index 492dd4b8f3d6..002ca58dd998 100644
+--- a/arch/riscv/kernel/vmlinux.lds.S
++++ b/arch/riscv/kernel/vmlinux.lds.S
+@@ -69,10 +69,12 @@ SECTIONS
+               __soc_builtin_dtb_table_end = .;
+       }
+       /* we have to discard exit text and such at runtime, not link time */
++      __exittext_begin = .;
+       .exit.text :
+       {
+               EXIT_TEXT
+       }
++      __exittext_end = .;
+       __init_text_end = .;
+       . = ALIGN(SECTION_ALIGN);
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-fix-module_alloc-that-did-not-reset-the-linear.patch b/queue-6.6/riscv-fix-module_alloc-that-did-not-reset-the-linear.patch
new file mode 100644 (file)
index 0000000..23c4c13
--- /dev/null
@@ -0,0 +1,56 @@
+From efe42cb2a89a928eaead8f54f28e8867d5ff65d5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 14:40:26 +0100
+Subject: riscv: Fix module_alloc() that did not reset the linear mapping
+ permissions
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 749b94b08005929bbc636df21a23322733166e35 ]
+
+After unloading a module, we must reset the linear mapping permissions,
+see the example below:
+
+Before unloading a module:
+
+0xffffaf809d65d000-0xffffaf809d6dc000    0x000000011d65d000       508K PTE .   ..     ..   D A G . . W R V
+0xffffaf809d6dc000-0xffffaf809d6dd000    0x000000011d6dc000         4K PTE .   ..     ..   D A G . . . R V
+0xffffaf809d6dd000-0xffffaf809d6e1000    0x000000011d6dd000        16K PTE .   ..     ..   D A G . . W R V
+0xffffaf809d6e1000-0xffffaf809d6e7000    0x000000011d6e1000        24K PTE .   ..     ..   D A G . X . R V
+
+After unloading a module:
+
+0xffffaf809d65d000-0xffffaf809d6e1000    0x000000011d65d000       528K PTE .   ..     ..   D A G . . W R V
+0xffffaf809d6e1000-0xffffaf809d6e7000    0x000000011d6e1000        24K PTE .   ..     ..   D A G . X W R V
+
+The last mapping is not reset and we end up with WX mappings in the linear
+mapping.
+
+So add VM_FLUSH_RESET_PERMS to our module_alloc() definition.
+
+Fixes: 0cff8bff7af8 ("riscv: avoid the PIC offset of static percpu data in module beyond 2G limits")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20231213134027.155327-2-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/module.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c
+index 7c651d55fcbd..df4f6fec5d17 100644
+--- a/arch/riscv/kernel/module.c
++++ b/arch/riscv/kernel/module.c
+@@ -440,7 +440,8 @@ void *module_alloc(unsigned long size)
+ {
+       return __vmalloc_node_range(size, 1, MODULES_VADDR,
+                                   MODULES_END, GFP_KERNEL,
+-                                  PAGE_KERNEL, 0, NUMA_NO_NODE,
++                                  PAGE_KERNEL, VM_FLUSH_RESET_PERMS,
++                                  NUMA_NO_NODE,
+                                   __builtin_return_address(0));
+ }
+ #endif
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-fix-set_direct_map_default_noflush-to-reset-_p.patch b/queue-6.6/riscv-fix-set_direct_map_default_noflush-to-reset-_p.patch
new file mode 100644 (file)
index 0000000..0f3290c
--- /dev/null
@@ -0,0 +1,38 @@
+From 88962f25c539f7d12baf4dbf618682cc0016f8ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 Dec 2023 14:40:27 +0100
+Subject: riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit b8b2711336f03ece539de61479d6ffc44fb603d3 ]
+
+When resetting the linear mapping permissions, we must make sure that we
+clear the X bit so that do not end up with WX mappings (since we set
+PAGE_KERNEL).
+
+Fixes: 395a21ff859c ("riscv: add ARCH_HAS_SET_DIRECT_MAP support")
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20231213134027.155327-3-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/mm/pageattr.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
+index fc5fc4f785c4..e703a9b59fc3 100644
+--- a/arch/riscv/mm/pageattr.c
++++ b/arch/riscv/mm/pageattr.c
+@@ -378,7 +378,7 @@ int set_direct_map_invalid_noflush(struct page *page)
+ int set_direct_map_default_noflush(struct page *page)
+ {
+       return __set_memory((unsigned long)page_address(page), 1,
+-                          PAGE_KERNEL, __pgprot(0));
++                          PAGE_KERNEL, __pgprot(_PAGE_EXEC));
+ }
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-fix-set_memory_xx-and-set_direct_map_xx-by-spl.patch b/queue-6.6/riscv-fix-set_memory_xx-and-set_direct_map_xx-by-spl.patch
new file mode 100644 (file)
index 0000000..3ab6609
--- /dev/null
@@ -0,0 +1,449 @@
+From 707f1abec564e07c8417600c45d61ddda831d8df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 8 Nov 2023 08:59:30 +0100
+Subject: riscv: Fix set_memory_XX() and set_direct_map_XX() by splitting huge
+ linear mappings
+
+From: Alexandre Ghiti <alexghiti@rivosinc.com>
+
+[ Upstream commit 311cd2f6e25380cff0abc2884dc6a3d33bc9b5c3 ]
+
+When STRICT_KERNEL_RWX is set, any change of permissions on any kernel
+mapping (vmalloc/modules/kernel text...etc) should be applied on its
+linear mapping alias. The problem is that the riscv kernel uses huge
+mappings for the linear mapping and walk_page_range_novma() does not
+split those huge mappings.
+
+So this patchset implements such split in order to apply fine-grained
+permissions on the linear mapping.
+
+Below is the difference before and after (the first PUD mapping is split
+into PTE/PMD mappings):
+
+Before:
+
+---[ Linear mapping ]---
+0xffffaf8000080000-0xffffaf8000200000    0x0000000080080000      1536K PTE     D A G . . W R V
+0xffffaf8000200000-0xffffaf8077c00000    0x0000000080200000      1914M PMD     D A G . . W R V
+0xffffaf8077c00000-0xffffaf8078800000    0x00000000f7c00000        12M PMD     D A G . . . R V
+0xffffaf8078800000-0xffffaf8078c00000    0x00000000f8800000         4M PMD     D A G . . W R V
+0xffffaf8078c00000-0xffffaf8079200000    0x00000000f8c00000         6M PMD     D A G . . . R V
+0xffffaf8079200000-0xffffaf807e600000    0x00000000f9200000        84M PMD     D A G . . W R V
+0xffffaf807e600000-0xffffaf807e716000    0x00000000fe600000      1112K PTE     D A G . . W R V
+0xffffaf807e717000-0xffffaf807e71a000    0x00000000fe717000        12K PTE     D A G . . W R V
+0xffffaf807e71d000-0xffffaf807e71e000    0x00000000fe71d000         4K PTE     D A G . . W R V
+0xffffaf807e722000-0xffffaf807e800000    0x00000000fe722000       888K PTE     D A G . . W R V
+0xffffaf807e800000-0xffffaf807fe00000    0x00000000fe800000        22M PMD     D A G . . W R V
+0xffffaf807fe00000-0xffffaf807ff54000    0x00000000ffe00000      1360K PTE     D A G . . W R V
+0xffffaf807ff55000-0xffffaf8080000000    0x00000000fff55000       684K PTE     D A G . . W R V
+0xffffaf8080000000-0xffffaf8400000000    0x0000000100000000        14G PUD     D A G . . W R V
+
+After:
+
+---[ Linear mapping ]---
+0xffffaf8000080000-0xffffaf8000200000    0x0000000080080000      1536K PTE     D A G . . W R V
+0xffffaf8000200000-0xffffaf8077c00000    0x0000000080200000      1914M PMD     D A G . . W R V
+0xffffaf8077c00000-0xffffaf8078800000    0x00000000f7c00000        12M PMD     D A G . . . R V
+0xffffaf8078800000-0xffffaf8078a00000    0x00000000f8800000         2M PMD     D A G . . W R V
+0xffffaf8078a00000-0xffffaf8078c00000    0x00000000f8a00000         2M PTE     D A G . . W R V
+0xffffaf8078c00000-0xffffaf8079200000    0x00000000f8c00000         6M PMD     D A G . . . R V
+0xffffaf8079200000-0xffffaf807e600000    0x00000000f9200000        84M PMD     D A G . . W R V
+0xffffaf807e600000-0xffffaf807e716000    0x00000000fe600000      1112K PTE     D A G . . W R V
+0xffffaf807e717000-0xffffaf807e71a000    0x00000000fe717000        12K PTE     D A G . . W R V
+0xffffaf807e71d000-0xffffaf807e71e000    0x00000000fe71d000         4K PTE     D A G . . W R V
+0xffffaf807e722000-0xffffaf807e800000    0x00000000fe722000       888K PTE     D A G . . W R V
+0xffffaf807e800000-0xffffaf807fe00000    0x00000000fe800000        22M PMD     D A G . . W R V
+0xffffaf807fe00000-0xffffaf807ff54000    0x00000000ffe00000      1360K PTE     D A G . . W R V
+0xffffaf807ff55000-0xffffaf8080000000    0x00000000fff55000       684K PTE     D A G . . W R V
+0xffffaf8080000000-0xffffaf8080800000    0x0000000100000000         8M PMD     D A G . . W R V
+0xffffaf8080800000-0xffffaf8080af6000    0x0000000100800000      3032K PTE     D A G . . W R V
+0xffffaf8080af6000-0xffffaf8080af8000    0x0000000100af6000         8K PTE     D A G . X . R V
+0xffffaf8080af8000-0xffffaf8080c00000    0x0000000100af8000      1056K PTE     D A G . . W R V
+0xffffaf8080c00000-0xffffaf8081a00000    0x0000000100c00000        14M PMD     D A G . . W R V
+0xffffaf8081a00000-0xffffaf8081a40000    0x0000000101a00000       256K PTE     D A G . . W R V
+0xffffaf8081a40000-0xffffaf8081a44000    0x0000000101a40000        16K PTE     D A G . X . R V
+0xffffaf8081a44000-0xffffaf8081a52000    0x0000000101a44000        56K PTE     D A G . . W R V
+0xffffaf8081a52000-0xffffaf8081a54000    0x0000000101a52000         8K PTE     D A G . X . R V
+...
+0xffffaf809e800000-0xffffaf80c0000000    0x000000011e800000       536M PMD     D A G . . W R V
+0xffffaf80c0000000-0xffffaf8400000000    0x0000000140000000        13G PUD     D A G . . W R V
+
+Note that this also fixes memfd_secret() syscall which uses
+set_direct_map_invalid_noflush() and set_direct_map_default_noflush() to
+remove the pages from the linear mapping. Below is the kernel page table
+while a memfd_secret() syscall is running, you can see all the !valid
+page table entries in the linear mapping:
+
+...
+0xffffaf8082240000-0xffffaf8082241000    0x0000000102240000         4K PTE     D A G . . W R .
+0xffffaf8082241000-0xffffaf8082250000    0x0000000102241000        60K PTE     D A G . . W R V
+0xffffaf8082250000-0xffffaf8082252000    0x0000000102250000         8K PTE     D A G . . W R .
+0xffffaf8082252000-0xffffaf8082256000    0x0000000102252000        16K PTE     D A G . . W R V
+0xffffaf8082256000-0xffffaf8082257000    0x0000000102256000         4K PTE     D A G . . W R .
+0xffffaf8082257000-0xffffaf8082258000    0x0000000102257000         4K PTE     D A G . . W R V
+0xffffaf8082258000-0xffffaf8082259000    0x0000000102258000         4K PTE     D A G . . W R .
+0xffffaf8082259000-0xffffaf808225a000    0x0000000102259000         4K PTE     D A G . . W R V
+0xffffaf808225a000-0xffffaf808225c000    0x000000010225a000         8K PTE     D A G . . W R .
+0xffffaf808225c000-0xffffaf8082266000    0x000000010225c000        40K PTE     D A G . . W R V
+0xffffaf8082266000-0xffffaf8082268000    0x0000000102266000         8K PTE     D A G . . W R .
+0xffffaf8082268000-0xffffaf8082284000    0x0000000102268000       112K PTE     D A G . . W R V
+0xffffaf8082284000-0xffffaf8082288000    0x0000000102284000        16K PTE     D A G . . W R .
+0xffffaf8082288000-0xffffaf808229c000    0x0000000102288000        80K PTE     D A G . . W R V
+0xffffaf808229c000-0xffffaf80822a0000    0x000000010229c000        16K PTE     D A G . . W R .
+0xffffaf80822a0000-0xffffaf80822a5000    0x00000001022a0000        20K PTE     D A G . . W R V
+0xffffaf80822a5000-0xffffaf80822a6000    0x00000001022a5000         4K PTE     D A G . . . R V
+0xffffaf80822a6000-0xffffaf80822ab000    0x00000001022a6000        20K PTE     D A G . . W R V
+...
+
+And when the memfd_secret() fd is released, the linear mapping is
+correctly reset:
+
+...
+0xffffaf8082240000-0xffffaf80822a5000    0x0000000102240000       404K PTE     D A G . . W R V
+0xffffaf80822a5000-0xffffaf80822a6000    0x00000001022a5000         4K PTE     D A G . . . R V
+0xffffaf80822a6000-0xffffaf80822af000    0x00000001022a6000        36K PTE     D A G . . W R V
+...
+
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Link: https://lore.kernel.org/r/20231108075930.7157-3-alexghiti@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Stable-dep-of: b8b2711336f0 ("riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/mm/pageattr.c | 270 +++++++++++++++++++++++++++++++++------
+ 1 file changed, 230 insertions(+), 40 deletions(-)
+
+diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c
+index 161d0b34c2cb..fc5fc4f785c4 100644
+--- a/arch/riscv/mm/pageattr.c
++++ b/arch/riscv/mm/pageattr.c
+@@ -5,6 +5,7 @@
+ #include <linux/pagewalk.h>
+ #include <linux/pgtable.h>
++#include <linux/vmalloc.h>
+ #include <asm/tlbflush.h>
+ #include <asm/bitops.h>
+ #include <asm/set_memory.h>
+@@ -25,19 +26,6 @@ static unsigned long set_pageattr_masks(unsigned long val, struct mm_walk *walk)
+       return new_val;
+ }
+-static int pageattr_pgd_entry(pgd_t *pgd, unsigned long addr,
+-                            unsigned long next, struct mm_walk *walk)
+-{
+-      pgd_t val = READ_ONCE(*pgd);
+-
+-      if (pgd_leaf(val)) {
+-              val = __pgd(set_pageattr_masks(pgd_val(val), walk));
+-              set_pgd(pgd, val);
+-      }
+-
+-      return 0;
+-}
+-
+ static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr,
+                             unsigned long next, struct mm_walk *walk)
+ {
+@@ -96,7 +84,6 @@ static int pageattr_pte_hole(unsigned long addr, unsigned long next,
+ }
+ static const struct mm_walk_ops pageattr_ops = {
+-      .pgd_entry = pageattr_pgd_entry,
+       .p4d_entry = pageattr_p4d_entry,
+       .pud_entry = pageattr_pud_entry,
+       .pmd_entry = pageattr_pmd_entry,
+@@ -105,12 +92,181 @@ static const struct mm_walk_ops pageattr_ops = {
+       .walk_lock = PGWALK_RDLOCK,
+ };
++#ifdef CONFIG_64BIT
++static int __split_linear_mapping_pmd(pud_t *pudp,
++                                    unsigned long vaddr, unsigned long end)
++{
++      pmd_t *pmdp;
++      unsigned long next;
++
++      pmdp = pmd_offset(pudp, vaddr);
++
++      do {
++              next = pmd_addr_end(vaddr, end);
++
++              if (next - vaddr >= PMD_SIZE &&
++                  vaddr <= (vaddr & PMD_MASK) && end >= next)
++                      continue;
++
++              if (pmd_leaf(*pmdp)) {
++                      struct page *pte_page;
++                      unsigned long pfn = _pmd_pfn(*pmdp);
++                      pgprot_t prot = __pgprot(pmd_val(*pmdp) & ~_PAGE_PFN_MASK);
++                      pte_t *ptep_new;
++                      int i;
++
++                      pte_page = alloc_page(GFP_KERNEL);
++                      if (!pte_page)
++                              return -ENOMEM;
++
++                      ptep_new = (pte_t *)page_address(pte_page);
++                      for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new)
++                              set_pte(ptep_new, pfn_pte(pfn + i, prot));
++
++                      smp_wmb();
++
++                      set_pmd(pmdp, pfn_pmd(page_to_pfn(pte_page), PAGE_TABLE));
++              }
++      } while (pmdp++, vaddr = next, vaddr != end);
++
++      return 0;
++}
++
++static int __split_linear_mapping_pud(p4d_t *p4dp,
++                                    unsigned long vaddr, unsigned long end)
++{
++      pud_t *pudp;
++      unsigned long next;
++      int ret;
++
++      pudp = pud_offset(p4dp, vaddr);
++
++      do {
++              next = pud_addr_end(vaddr, end);
++
++              if (next - vaddr >= PUD_SIZE &&
++                  vaddr <= (vaddr & PUD_MASK) && end >= next)
++                      continue;
++
++              if (pud_leaf(*pudp)) {
++                      struct page *pmd_page;
++                      unsigned long pfn = _pud_pfn(*pudp);
++                      pgprot_t prot = __pgprot(pud_val(*pudp) & ~_PAGE_PFN_MASK);
++                      pmd_t *pmdp_new;
++                      int i;
++
++                      pmd_page = alloc_page(GFP_KERNEL);
++                      if (!pmd_page)
++                              return -ENOMEM;
++
++                      pmdp_new = (pmd_t *)page_address(pmd_page);
++                      for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new)
++                              set_pmd(pmdp_new,
++                                      pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot));
++
++                      smp_wmb();
++
++                      set_pud(pudp, pfn_pud(page_to_pfn(pmd_page), PAGE_TABLE));
++              }
++
++              ret = __split_linear_mapping_pmd(pudp, vaddr, next);
++              if (ret)
++                      return ret;
++      } while (pudp++, vaddr = next, vaddr != end);
++
++      return 0;
++}
++
++static int __split_linear_mapping_p4d(pgd_t *pgdp,
++                                    unsigned long vaddr, unsigned long end)
++{
++      p4d_t *p4dp;
++      unsigned long next;
++      int ret;
++
++      p4dp = p4d_offset(pgdp, vaddr);
++
++      do {
++              next = p4d_addr_end(vaddr, end);
++
++              /*
++               * If [vaddr; end] contains [vaddr & P4D_MASK; next], we don't
++               * need to split, we'll change the protections on the whole P4D.
++               */
++              if (next - vaddr >= P4D_SIZE &&
++                  vaddr <= (vaddr & P4D_MASK) && end >= next)
++                      continue;
++
++              if (p4d_leaf(*p4dp)) {
++                      struct page *pud_page;
++                      unsigned long pfn = _p4d_pfn(*p4dp);
++                      pgprot_t prot = __pgprot(p4d_val(*p4dp) & ~_PAGE_PFN_MASK);
++                      pud_t *pudp_new;
++                      int i;
++
++                      pud_page = alloc_page(GFP_KERNEL);
++                      if (!pud_page)
++                              return -ENOMEM;
++
++                      /*
++                       * Fill the pud level with leaf puds that have the same
++                       * protections as the leaf p4d.
++                       */
++                      pudp_new = (pud_t *)page_address(pud_page);
++                      for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new)
++                              set_pud(pudp_new,
++                                      pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot));
++
++                      /*
++                       * Make sure the pud filling is not reordered with the
++                       * p4d store which could result in seeing a partially
++                       * filled pud level.
++                       */
++                      smp_wmb();
++
++                      set_p4d(p4dp, pfn_p4d(page_to_pfn(pud_page), PAGE_TABLE));
++              }
++
++              ret = __split_linear_mapping_pud(p4dp, vaddr, next);
++              if (ret)
++                      return ret;
++      } while (p4dp++, vaddr = next, vaddr != end);
++
++      return 0;
++}
++
++static int __split_linear_mapping_pgd(pgd_t *pgdp,
++                                    unsigned long vaddr,
++                                    unsigned long end)
++{
++      unsigned long next;
++      int ret;
++
++      do {
++              next = pgd_addr_end(vaddr, end);
++              /* We never use PGD mappings for the linear mapping */
++              ret = __split_linear_mapping_p4d(pgdp, vaddr, next);
++              if (ret)
++                      return ret;
++      } while (pgdp++, vaddr = next, vaddr != end);
++
++      return 0;
++}
++
++static int split_linear_mapping(unsigned long start, unsigned long end)
++{
++      return __split_linear_mapping_pgd(pgd_offset_k(start), start, end);
++}
++#endif        /* CONFIG_64BIT */
++
+ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,
+                       pgprot_t clear_mask)
+ {
+       int ret;
+       unsigned long start = addr;
+       unsigned long end = start + PAGE_SIZE * numpages;
++      unsigned long __maybe_unused lm_start;
++      unsigned long __maybe_unused lm_end;
+       struct pageattr_masks masks = {
+               .set_mask = set_mask,
+               .clear_mask = clear_mask
+@@ -120,11 +276,67 @@ static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask,
+               return 0;
+       mmap_write_lock(&init_mm);
++
++#ifdef CONFIG_64BIT
++      /*
++       * We are about to change the permissions of a kernel mapping, we must
++       * apply the same changes to its linear mapping alias, which may imply
++       * splitting a huge mapping.
++       */
++
++      if (is_vmalloc_or_module_addr((void *)start)) {
++              struct vm_struct *area = NULL;
++              int i, page_start;
++
++              area = find_vm_area((void *)start);
++              page_start = (start - (unsigned long)area->addr) >> PAGE_SHIFT;
++
++              for (i = page_start; i < page_start + numpages; ++i) {
++                      lm_start = (unsigned long)page_address(area->pages[i]);
++                      lm_end = lm_start + PAGE_SIZE;
++
++                      ret = split_linear_mapping(lm_start, lm_end);
++                      if (ret)
++                              goto unlock;
++
++                      ret = walk_page_range_novma(&init_mm, lm_start, lm_end,
++                                                  &pageattr_ops, NULL, &masks);
++                      if (ret)
++                              goto unlock;
++              }
++      } else if (is_kernel_mapping(start) || is_linear_mapping(start)) {
++              lm_start = (unsigned long)lm_alias(start);
++              lm_end = (unsigned long)lm_alias(end);
++
++              ret = split_linear_mapping(lm_start, lm_end);
++              if (ret)
++                      goto unlock;
++
++              ret = walk_page_range_novma(&init_mm, lm_start, lm_end,
++                                          &pageattr_ops, NULL, &masks);
++              if (ret)
++                      goto unlock;
++      }
++
+       ret =  walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL,
+                                    &masks);
++
++unlock:
++      mmap_write_unlock(&init_mm);
++
++      /*
++       * We can't use flush_tlb_kernel_range() here as we may have split a
++       * hugepage that is larger than that, so let's flush everything.
++       */
++      flush_tlb_all();
++#else
++      ret =  walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL,
++                                   &masks);
++
+       mmap_write_unlock(&init_mm);
+       flush_tlb_kernel_range(start, end);
++#endif
+       return ret;
+ }
+@@ -159,36 +371,14 @@ int set_memory_nx(unsigned long addr, int numpages)
+ int set_direct_map_invalid_noflush(struct page *page)
+ {
+-      int ret;
+-      unsigned long start = (unsigned long)page_address(page);
+-      unsigned long end = start + PAGE_SIZE;
+-      struct pageattr_masks masks = {
+-              .set_mask = __pgprot(0),
+-              .clear_mask = __pgprot(_PAGE_PRESENT)
+-      };
+-
+-      mmap_read_lock(&init_mm);
+-      ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
+-      mmap_read_unlock(&init_mm);
+-
+-      return ret;
++      return __set_memory((unsigned long)page_address(page), 1,
++                          __pgprot(0), __pgprot(_PAGE_PRESENT));
+ }
+ int set_direct_map_default_noflush(struct page *page)
+ {
+-      int ret;
+-      unsigned long start = (unsigned long)page_address(page);
+-      unsigned long end = start + PAGE_SIZE;
+-      struct pageattr_masks masks = {
+-              .set_mask = PAGE_KERNEL,
+-              .clear_mask = __pgprot(0)
+-      };
+-
+-      mmap_read_lock(&init_mm);
+-      ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks);
+-      mmap_read_unlock(&init_mm);
+-
+-      return ret;
++      return __set_memory((unsigned long)page_address(page), 1,
++                          PAGE_KERNEL, __pgprot(0));
+ }
+ #ifdef CONFIG_DEBUG_PAGEALLOC
+-- 
+2.43.0
+
diff --git a/queue-6.6/riscv-fixed-wrong-register-in-xip_fixup_flash_offset.patch b/queue-6.6/riscv-fixed-wrong-register-in-xip_fixup_flash_offset.patch
new file mode 100644 (file)
index 0000000..6b564d5
--- /dev/null
@@ -0,0 +1,39 @@
+From c9a053ac5625d6868ee78751f40c4bd818f7c081 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 12 Dec 2023 14:01:13 +0100
+Subject: riscv: Fixed wrong register in XIP_FIXUP_FLASH_OFFSET macro
+
+From: Frederik Haxel <haxel@fzi.de>
+
+[ Upstream commit 5daa3726410288075ba73c336bb2e80d6b06aa4d ]
+
+During the refactoring, a bug was introduced in the rarly used
+XIP_FIXUP_FLASH_OFFSET macro.
+
+Fixes: bee7fbc38579 ("RISC-V CPU Idle Support")
+Fixes: e7681beba992 ("RISC-V: Split out the XIP fixups into their own file")
+
+Signed-off-by: Frederik Haxel <haxel@fzi.de>
+Link: https://lore.kernel.org/r/20231212130116.848530-3-haxel@fzi.de
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/include/asm/xip_fixup.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/include/asm/xip_fixup.h b/arch/riscv/include/asm/xip_fixup.h
+index d4ffc3c37649..b65bf6306f69 100644
+--- a/arch/riscv/include/asm/xip_fixup.h
++++ b/arch/riscv/include/asm/xip_fixup.h
+@@ -13,7 +13,7 @@
+         add \reg, \reg, t0
+ .endm
+ .macro XIP_FIXUP_FLASH_OFFSET reg
+-      la t1, __data_loc
++      la t0, __data_loc
+       REG_L t1, _xip_phys_offset
+       sub \reg, \reg, t1
+       add \reg, \reg, t0
+-- 
+2.43.0
+
diff --git a/queue-6.6/rxrpc-fix-use-of-don-t-fragment-flag.patch b/queue-6.6/rxrpc-fix-use-of-don-t-fragment-flag.patch
new file mode 100644 (file)
index 0000000..c656648
--- /dev/null
@@ -0,0 +1,121 @@
+From 15627542dda4ca8204ed3f58f8ebe255642acf9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 9 Jan 2024 15:10:48 +0000
+Subject: rxrpc: Fix use of Don't Fragment flag
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 8722014311e613244f33952354956a82fa4b0472 ]
+
+rxrpc normally has the Don't Fragment flag set on the UDP packets it
+transmits, except when it has decided that DATA packets aren't getting
+through - in which case it turns it off just for the DATA transmissions.
+This can be a problem, however, for RESPONSE packets that convey
+authentication and crypto data from the client to the server as ticket may
+be larger than can fit in the MTU.
+
+In such a case, rxrpc gets itself into an infinite loop as the sendmsg
+returns an error (EMSGSIZE), which causes rxkad_send_response() to return
+-EAGAIN - and the CHALLENGE packet is put back on the Rx queue to retry,
+leading to the I/O thread endlessly attempting to perform the transmission.
+
+Fix this by disabling DF on RESPONSE packets for now.  The use of DF and
+best data MTU determination needs reconsidering at some point in the
+future.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Reported-by: Marc Dionne <marc.dionne@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: linux-afs@lists.infradead.org
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/1581852.1704813048@warthog.procyon.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/ar-internal.h  |  1 +
+ net/rxrpc/local_object.c | 13 ++++++++++++-
+ net/rxrpc/output.c       |  6 ++----
+ net/rxrpc/rxkad.c        |  2 ++
+ 4 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
+index e8e14c6f904d..e8b43408136a 100644
+--- a/net/rxrpc/ar-internal.h
++++ b/net/rxrpc/ar-internal.h
+@@ -1076,6 +1076,7 @@ void rxrpc_send_version_request(struct rxrpc_local *local,
+ /*
+  * local_object.c
+  */
++void rxrpc_local_dont_fragment(const struct rxrpc_local *local, bool set);
+ struct rxrpc_local *rxrpc_lookup_local(struct net *, const struct sockaddr_rxrpc *);
+ struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *, enum rxrpc_local_trace);
+ struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *, enum rxrpc_local_trace);
+diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
+index c553a30e9c83..34d307368135 100644
+--- a/net/rxrpc/local_object.c
++++ b/net/rxrpc/local_object.c
+@@ -36,6 +36,17 @@ static void rxrpc_encap_err_rcv(struct sock *sk, struct sk_buff *skb, int err,
+               return ipv6_icmp_error(sk, skb, err, port, info, payload);
+ }
++/*
++ * Set or clear the Don't Fragment flag on a socket.
++ */
++void rxrpc_local_dont_fragment(const struct rxrpc_local *local, bool set)
++{
++      if (set)
++              ip_sock_set_mtu_discover(local->socket->sk, IP_PMTUDISC_DO);
++      else
++              ip_sock_set_mtu_discover(local->socket->sk, IP_PMTUDISC_DONT);
++}
++
+ /*
+  * Compare a local to an address.  Return -ve, 0 or +ve to indicate less than,
+  * same or greater than.
+@@ -203,7 +214,7 @@ static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
+               ip_sock_set_recverr(usk);
+               /* we want to set the don't fragment bit */
+-              ip_sock_set_mtu_discover(usk, IP_PMTUDISC_DO);
++              rxrpc_local_dont_fragment(local, true);
+               /* We want receive timestamps. */
+               sock_enable_timestamps(usk);
+diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
+index 5e53429c6922..a0906145e829 100644
+--- a/net/rxrpc/output.c
++++ b/net/rxrpc/output.c
+@@ -494,14 +494,12 @@ int rxrpc_send_data_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb)
+       switch (conn->local->srx.transport.family) {
+       case AF_INET6:
+       case AF_INET:
+-              ip_sock_set_mtu_discover(conn->local->socket->sk,
+-                                       IP_PMTUDISC_DONT);
++              rxrpc_local_dont_fragment(conn->local, false);
+               rxrpc_inc_stat(call->rxnet, stat_tx_data_send_frag);
+               ret = do_udp_sendmsg(conn->local->socket, &msg, len);
+               conn->peer->last_tx_at = ktime_get_seconds();
+-              ip_sock_set_mtu_discover(conn->local->socket->sk,
+-                                       IP_PMTUDISC_DO);
++              rxrpc_local_dont_fragment(conn->local, true);
+               break;
+       default:
+diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
+index 1bf571a66e02..b52dedcebce0 100644
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -724,7 +724,9 @@ static int rxkad_send_response(struct rxrpc_connection *conn,
+       serial = atomic_inc_return(&conn->serial);
+       whdr.serial = htonl(serial);
++      rxrpc_local_dont_fragment(conn->local, false);
+       ret = kernel_sendmsg(conn->local->socket, &msg, iov, 3, len);
++      rxrpc_local_dont_fragment(conn->local, true);
+       if (ret < 0) {
+               trace_rxrpc_tx_fail(conn->debug_id, serial, ret,
+                                   rxrpc_tx_point_rxkad_response);
+-- 
+2.43.0
+
diff --git a/queue-6.6/s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch b/queue-6.6/s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch
new file mode 100644 (file)
index 0000000..a23161f
--- /dev/null
@@ -0,0 +1,145 @@
+From 5881de45cc90a1bbbc6822d5e02a195cb9287dea Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 28 Nov 2023 16:22:49 +0100
+Subject: s390/pci: fix max size calculation in zpci_memcpy_toio()
+
+From: Niklas Schnelle <schnelle@linux.ibm.com>
+
+[ Upstream commit 80df7d6af7f6d229b34cf237b2cc9024c07111cd ]
+
+The zpci_get_max_write_size() helper is used to determine the maximum
+size a PCI store or load can use at a given __iomem address.
+
+For the PCI block store the following restrictions apply:
+
+1. The dst + len must not cross a 4K boundary in the (pseudo-)MMIO space
+2. len must not exceed ZPCI_MAX_WRITE_SIZE
+3. len must be a multiple of 8 bytes
+4. The src address must be double word (8 byte) aligned
+5. The dst address must be double word (8 byte) aligned
+
+Otherwise only a normal PCI store which takes its src value from
+a register can be used. For these PCI store restriction 1 still applies.
+Similarly 1 also applies to PCI loads.
+
+It turns out zpci_max_write_size() instead implements stricter
+conditions which prevents PCI block stores from being used where they
+can and should be used. In particular instead of conditions 4 and 5 it
+wrongly enforces both dst and src to be size aligned. This indirectly
+covers condition 1 but also prevents many legal PCI block stores.
+
+On top of the functional shortcomings the zpci_get_max_write_size() is
+misnamed as it is used for both read and write size calculations. Rename
+it to zpci_get_max_io_size() and implement the listed conditions
+explicitly.
+
+Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
+Fixes: cd24834130ac ("s390/pci: base support")
+Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
+[agordeev@linux.ibm.com replaced spaces with tabs]
+Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/include/asm/pci_io.h | 32 ++++++++++++++++++--------------
+ arch/s390/pci/pci_mmio.c       | 12 ++++++------
+ 2 files changed, 24 insertions(+), 20 deletions(-)
+
+diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h
+index 287bb88f7698..2686bee800e3 100644
+--- a/arch/s390/include/asm/pci_io.h
++++ b/arch/s390/include/asm/pci_io.h
+@@ -11,6 +11,8 @@
+ /* I/O size constraints */
+ #define ZPCI_MAX_READ_SIZE    8
+ #define ZPCI_MAX_WRITE_SIZE   128
++#define ZPCI_BOUNDARY_SIZE    (1 << 12)
++#define ZPCI_BOUNDARY_MASK    (ZPCI_BOUNDARY_SIZE - 1)
+ /* I/O Map */
+ #define ZPCI_IOMAP_SHIFT              48
+@@ -125,16 +127,18 @@ static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
+ int zpci_write_block(volatile void __iomem *dst, const void *src,
+                    unsigned long len);
+-static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max)
++static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max)
+ {
+-      int count = len > max ? max : len, size = 1;
++      int offset = dst & ZPCI_BOUNDARY_MASK;
++      int size;
+-      while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) {
+-              dst = dst >> 1;
+-              src = src >> 1;
+-              size = size << 1;
+-      }
+-      return size;
++      size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max);
++      if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8))
++              return size;
++
++      if (size >= 8)
++              return 8;
++      return rounddown_pow_of_two(size);
+ }
+ static inline int zpci_memcpy_fromio(void *dst,
+@@ -144,9 +148,9 @@ static inline int zpci_memcpy_fromio(void *dst,
+       int size, rc = 0;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) src,
+-                                             (u64) dst, n,
+-                                             ZPCI_MAX_READ_SIZE);
++              size = zpci_get_max_io_size((u64 __force) src,
++                                          (u64) dst, n,
++                                          ZPCI_MAX_READ_SIZE);
+               rc = zpci_read_single(dst, src, size);
+               if (rc)
+                       break;
+@@ -166,9 +170,9 @@ static inline int zpci_memcpy_toio(volatile void __iomem *dst,
+               return -EINVAL;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) dst,
+-                                             (u64) src, n,
+-                                             ZPCI_MAX_WRITE_SIZE);
++              size = zpci_get_max_io_size((u64 __force) dst,
++                                          (u64) src, n,
++                                          ZPCI_MAX_WRITE_SIZE);
+               if (size > 8) /* main path */
+                       rc = zpci_write_block(dst, src, size);
+               else
+diff --git a/arch/s390/pci/pci_mmio.c b/arch/s390/pci/pci_mmio.c
+index 588089332931..a90499c087f0 100644
+--- a/arch/s390/pci/pci_mmio.c
++++ b/arch/s390/pci/pci_mmio.c
+@@ -97,9 +97,9 @@ static inline int __memcpy_toio_inuser(void __iomem *dst,
+               return -EINVAL;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) dst,
+-                                             (u64 __force) src, n,
+-                                             ZPCI_MAX_WRITE_SIZE);
++              size = zpci_get_max_io_size((u64 __force) dst,
++                                          (u64 __force) src, n,
++                                          ZPCI_MAX_WRITE_SIZE);
+               if (size > 8) /* main path */
+                       rc = __pcistb_mio_inuser(dst, src, size, &status);
+               else
+@@ -242,9 +242,9 @@ static inline int __memcpy_fromio_inuser(void __user *dst,
+       u8 status;
+       while (n > 0) {
+-              size = zpci_get_max_write_size((u64 __force) src,
+-                                             (u64 __force) dst, n,
+-                                             ZPCI_MAX_READ_SIZE);
++              size = zpci_get_max_io_size((u64 __force) src,
++                                          (u64 __force) dst, n,
++                                          ZPCI_MAX_READ_SIZE);
+               rc = __pcilg_mio_inuser(dst, src, size, &status);
+               if (rc)
+                       break;
+-- 
+2.43.0
+
diff --git a/queue-6.6/selftests-bonding-change-script-interpreter.patch b/queue-6.6/selftests-bonding-change-script-interpreter.patch
new file mode 100644 (file)
index 0000000..4e59a75
--- /dev/null
@@ -0,0 +1,50 @@
+From 60b2ce2d405e79a8d77a87015079277d36e4e416 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Jan 2024 09:14:35 -0500
+Subject: selftests: bonding: Change script interpreter
+
+From: Benjamin Poirier <bpoirier@nvidia.com>
+
+[ Upstream commit c2518da8e6b0e248cfff1d4b6682e14020bd4d3f ]
+
+The tests changed by this patch, as well as the scripts they source, use
+features which are not part of POSIX sh (ex. 'source' and 'local'). As a
+result, these tests fail when /bin/sh is dash such as on Debian. Change the
+interpreter to bash so that these tests can run successfully.
+
+Fixes: d43eff0b85ae ("selftests: bonding: up/down delay w/ slave link flapping")
+Tested-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Benjamin Poirier <bpoirier@nvidia.com>
+Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/drivers/net/bonding/mode-1-recovery-updelay.sh    | 2 +-
+ .../selftests/drivers/net/bonding/mode-2-recovery-updelay.sh    | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/drivers/net/bonding/mode-1-recovery-updelay.sh b/tools/testing/selftests/drivers/net/bonding/mode-1-recovery-updelay.sh
+index ad4c845a4ac7..b76bf5030952 100755
+--- a/tools/testing/selftests/drivers/net/bonding/mode-1-recovery-updelay.sh
++++ b/tools/testing/selftests/drivers/net/bonding/mode-1-recovery-updelay.sh
+@@ -1,4 +1,4 @@
+-#!/bin/sh
++#!/bin/bash
+ # SPDX-License-Identifier: GPL-2.0
+ # Regression Test:
+diff --git a/tools/testing/selftests/drivers/net/bonding/mode-2-recovery-updelay.sh b/tools/testing/selftests/drivers/net/bonding/mode-2-recovery-updelay.sh
+index 2330d37453f9..8c2619002147 100755
+--- a/tools/testing/selftests/drivers/net/bonding/mode-2-recovery-updelay.sh
++++ b/tools/testing/selftests/drivers/net/bonding/mode-2-recovery-updelay.sh
+@@ -1,4 +1,4 @@
+-#!/bin/sh
++#!/bin/bash
+ # SPDX-License-Identifier: GPL-2.0
+ # Regression Test:
+-- 
+2.43.0
+
diff --git a/queue-6.6/selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch b/queue-6.6/selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch
new file mode 100644 (file)
index 0000000..607577a
--- /dev/null
@@ -0,0 +1,88 @@
+From 4119199d5fd1d4a08a4f868f1d360b0337a65633 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 17 Jan 2024 16:04:21 +0100
+Subject: selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit b34f4de6d30cbaa8fed905a5080b6eace8c84dc7 ]
+
+'qos_pfc' test checks PFC behavior. The idea is to limit the traffic
+using a shaper somewhere in the flow of the packets. In this area, the
+buffer is smaller than the buffer at the beginning of the flow, so it fills
+up until there is no more space left. The test configures there PFC
+which is supposed to notice that the headroom is filling up and send PFC
+Xoff to indicate the transmitter to stop sending traffic for the priorities
+sharing this PG.
+
+The Xon/Xoff threshold is auto-configured and always equal to
+2*(MTU rounded up to cell size). Even after sending the PFC Xoff packet,
+traffic will keep arriving until the transmitter receives and processes
+the PFC packet. This amount of traffic is known as the PFC delay allowance.
+
+Currently the buffer for the delay traffic is configured as 100KB. The
+MTU in the test is 10KB, therefore the threshold for Xoff is about 20KB.
+This allows 80KB extra to be stored in this buffer.
+
+8-lane ports use two buffers among which the configured buffer is split,
+the Xoff threshold then applies to each buffer in parallel.
+
+The test does not take into account the behavior of 8-lane ports, when the
+ports are configured to 400Gbps with 8 lanes or 800Gbps with 8 lanes,
+packets are dropped and the test fails.
+
+Check if the relevant ports use 8 lanes, in such case double the size of
+the buffer, as the headroom is split half-half.
+
+Cc: Shuah Khan <shuah@kernel.org>
+Fixes: bfa804784e32 ("selftests: mlxsw: Add a PFC test")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Petr Machata <petrm@nvidia.com>
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Link: https://lore.kernel.org/r/23ff11b7dff031eb04a41c0f5254a2b636cd8ebb.1705502064.git.petrm@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/drivers/net/mlxsw/qos_pfc.sh     | 18 +++++++++++++++++-
+ 1 file changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh
+index 42ce602d8d49..e71d811656bb 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/qos_pfc.sh
+@@ -120,6 +120,9 @@ h2_destroy()
+ switch_create()
+ {
++      local lanes_swp4
++      local pg1_size
++
+       # pools
+       # -----
+@@ -229,7 +232,20 @@ switch_create()
+       dcb pfc set dev $swp4 prio-pfc all:off 1:on
+       # PG0 will get autoconfigured to Xoff, give PG1 arbitrarily 100K, which
+       # is (-2*MTU) about 80K of delay provision.
+-      dcb buffer set dev $swp4 buffer-size all:0 1:$_100KB
++      pg1_size=$_100KB
++
++      setup_wait_dev_with_timeout $swp4
++
++      lanes_swp4=$(ethtool $swp4 | grep 'Lanes:')
++      lanes_swp4=${lanes_swp4#*"Lanes: "}
++
++      # 8-lane ports use two buffers among which the configured buffer
++      # is split, so double the size to get twice (20K + 80K).
++      if [[ $lanes_swp4 -eq 8 ]]; then
++              pg1_size=$((pg1_size * 2))
++      fi
++
++      dcb buffer set dev $swp4 buffer-size all:0 1:$pg1_size
+       # bridges
+       # -------
+-- 
+2.43.0
+
diff --git a/queue-6.6/selftests-sgx-fix-uninitialized-pointer-dereference-.patch b/queue-6.6/selftests-sgx-fix-uninitialized-pointer-dereference-.patch
new file mode 100644 (file)
index 0000000..03aa754
--- /dev/null
@@ -0,0 +1,52 @@
+From ff01f3e00b4ce6f293296f2d3ad9cf1988d0b3db Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Oct 2023 17:38:42 +0200
+Subject: selftests/sgx: Fix uninitialized pointer dereference in error path
+
+From: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+
+[ Upstream commit 79eba8c924f7decfa71ddf187d38cb9f5f2cd7b3 ]
+
+Ensure ctx is zero-initialized, such that the encl_measure function will
+not call EVP_MD_CTX_destroy with an uninitialized ctx pointer in case of an
+early error during key generation.
+
+Fixes: 2adcba79e69d ("selftests/x86: Add a selftest for SGX")
+Signed-off-by: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Acked-by: Kai Huang <kai.huang@intel.com>
+Link: https://lore.kernel.org/all/20231005153854.25566-2-jo.vanbulck%40cs.kuleuven.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/sigstruct.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/tools/testing/selftests/sgx/sigstruct.c b/tools/testing/selftests/sgx/sigstruct.c
+index a07896a46364..d73b29becf5b 100644
+--- a/tools/testing/selftests/sgx/sigstruct.c
++++ b/tools/testing/selftests/sgx/sigstruct.c
+@@ -318,9 +318,9 @@ bool encl_measure(struct encl *encl)
+       struct sgx_sigstruct *sigstruct = &encl->sigstruct;
+       struct sgx_sigstruct_payload payload;
+       uint8_t digest[SHA256_DIGEST_LENGTH];
++      EVP_MD_CTX *ctx = NULL;
+       unsigned int siglen;
+       RSA *key = NULL;
+-      EVP_MD_CTX *ctx;
+       int i;
+       memset(sigstruct, 0, sizeof(*sigstruct));
+@@ -384,7 +384,8 @@ bool encl_measure(struct encl *encl)
+       return true;
+ err:
+-      EVP_MD_CTX_destroy(ctx);
++      if (ctx)
++              EVP_MD_CTX_destroy(ctx);
+       RSA_free(key);
+       return false;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/selftests-sgx-fix-uninitialized-pointer-dereferences.patch b/queue-6.6/selftests-sgx-fix-uninitialized-pointer-dereferences.patch
new file mode 100644 (file)
index 0000000..abc237f
--- /dev/null
@@ -0,0 +1,58 @@
+From 0c18672c12dc7152b05aa202f1493be99389c4a7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Oct 2023 17:38:43 +0200
+Subject: selftests/sgx: Fix uninitialized pointer dereferences in
+ encl_get_entry
+
+From: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+
+[ Upstream commit b84fc2e0139ba4b23b8039bd7cfd242894fe8f8b ]
+
+Ensure sym_tab and sym_names are zero-initialized and add an early-out
+condition in the unlikely (erroneous) case that the enclave ELF file would
+not contain a symbol table.
+
+This addresses -Werror=maybe-uninitialized compiler warnings for gcc -O2.
+
+Fixes: 33c5aac3bf32 ("selftests/sgx: Test complete changing of page type flow")
+Signed-off-by: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Link: https://lore.kernel.org/all/20231005153854.25566-3-jo.vanbulck%40cs.kuleuven.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/load.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c
+index 94bdeac1cf04..c9f658e44de6 100644
+--- a/tools/testing/selftests/sgx/load.c
++++ b/tools/testing/selftests/sgx/load.c
+@@ -136,11 +136,11 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg)
+  */
+ uint64_t encl_get_entry(struct encl *encl, const char *symbol)
+ {
++      Elf64_Sym *symtab = NULL;
++      char *sym_names = NULL;
+       Elf64_Shdr *sections;
+-      Elf64_Sym *symtab;
+       Elf64_Ehdr *ehdr;
+-      char *sym_names;
+-      int num_sym;
++      int num_sym = 0;
+       int i;
+       ehdr = encl->bin;
+@@ -161,6 +161,9 @@ uint64_t encl_get_entry(struct encl *encl, const char *symbol)
+               }
+       }
++      if (!symtab || !sym_names)
++              return 0;
++
+       for (i = 0; i < num_sym; i++) {
+               Elf64_Sym *sym = &symtab[i];
+-- 
+2.43.0
+
diff --git a/queue-6.6/selftests-sgx-include-memory-clobber-for-inline-asm-.patch b/queue-6.6/selftests-sgx-include-memory-clobber-for-inline-asm-.patch
new file mode 100644 (file)
index 0000000..7d4891f
--- /dev/null
@@ -0,0 +1,56 @@
+From 5e142b46e33475f8ddb42cf9408432b9914c4e10 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Oct 2023 17:38:44 +0200
+Subject: selftests/sgx: Include memory clobber for inline asm in test enclave
+
+From: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+
+[ Upstream commit 853a57a43ebdb8c024160c1a0990bae85f4bcc2f ]
+
+Add the "memory" clobber to the EMODPE and EACCEPT asm blocks to tell the
+compiler the assembly code accesses to the secinfo struct. This ensures
+the compiler treats the asm block as a memory barrier and the write to
+secinfo will be visible to ENCLU.
+
+Fixes: 20404a808593 ("selftests/sgx: Add test for EPCM permission changes")
+Signed-off-by: Jo Van Bulck <jo.vanbulck@cs.kuleuven.be>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Kai Huang <kai.huang@intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Link: https://lore.kernel.org/all/20231005153854.25566-4-jo.vanbulck%40cs.kuleuven.be
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/test_encl.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/tools/testing/selftests/sgx/test_encl.c b/tools/testing/selftests/sgx/test_encl.c
+index c0d6397295e3..ae791df3e5a5 100644
+--- a/tools/testing/selftests/sgx/test_encl.c
++++ b/tools/testing/selftests/sgx/test_encl.c
+@@ -24,10 +24,11 @@ static void do_encl_emodpe(void *_op)
+       secinfo.flags = op->flags;
+       asm volatile(".byte 0x0f, 0x01, 0xd7"
+-                              :
++                              : /* no outputs */
+                               : "a" (EMODPE),
+                                 "b" (&secinfo),
+-                                "c" (op->epc_addr));
++                                "c" (op->epc_addr)
++                              : "memory" /* read from secinfo pointer */);
+ }
+ static void do_encl_eaccept(void *_op)
+@@ -42,7 +43,8 @@ static void do_encl_eaccept(void *_op)
+                               : "=a" (rax)
+                               : "a" (EACCEPT),
+                                 "b" (&secinfo),
+-                                "c" (op->epc_addr));
++                                "c" (op->epc_addr)
++                              : "memory" /* read from secinfo pointer */);
+       op->ret = rax;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/selftests-sgx-skip-non-x86_64-platform.patch b/queue-6.6/selftests-sgx-skip-non-x86_64-platform.patch
new file mode 100644 (file)
index 0000000..797ca2f
--- /dev/null
@@ -0,0 +1,49 @@
+From 39885b557ebf32b60d44616525dc7015ad6281b8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 21:56:05 -0500
+Subject: selftests/sgx: Skip non X86_64 platform
+
+From: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
+
+[ Upstream commit 981cf568a8644161c2f15c02278ebc2834b51ba6 ]
+
+When building whole selftests on arm64, rsync gives an erorr about sgx:
+
+rsync: [sender] link_stat "/root/linux-next/tools/testing/selftests/sgx/test_encl.elf" failed: No such file or directory (2)
+rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1327) [sender=3.2.5]
+
+The root casue is sgx only used on X86_64, and shall be skipped on other
+platforms.
+
+Fix this by moving TEST_CUSTOM_PROGS and TEST_FILES inside the if check,
+then the build result will be "Skipping non-existent dir: sgx".
+
+Fixes: 2adcba79e69d ("selftests/x86: Add a selftest for SGX")
+Signed-off-by: Zhao Mengmeng <zhaomengmeng@kylinos.cn>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Link: https://lore.kernel.org/all/20231206025605.3965302-1-zhaomzhao%40126.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/testing/selftests/sgx/Makefile | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/sgx/Makefile b/tools/testing/selftests/sgx/Makefile
+index 50aab6b57da3..01abe4969b0f 100644
+--- a/tools/testing/selftests/sgx/Makefile
++++ b/tools/testing/selftests/sgx/Makefile
+@@ -16,10 +16,10 @@ HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC -z noexecstack
+ ENCL_CFLAGS := -Wall -Werror -static -nostdlib -nostartfiles -fPIC \
+              -fno-stack-protector -mrdrnd $(INCLUDES)
++ifeq ($(CAN_BUILD_X86_64), 1)
+ TEST_CUSTOM_PROGS := $(OUTPUT)/test_sgx
+ TEST_FILES := $(OUTPUT)/test_encl.elf
+-ifeq ($(CAN_BUILD_X86_64), 1)
+ all: $(TEST_CUSTOM_PROGS) $(OUTPUT)/test_encl.elf
+ endif
+-- 
+2.43.0
+
diff --git a/queue-6.6/serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch b/queue-6.6/serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch
new file mode 100644 (file)
index 0000000..bc04ac2
--- /dev/null
@@ -0,0 +1,51 @@
+From c021f0c6731bc246f6a61e7fa16c662a57b60c61 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 10 Nov 2023 16:29:29 +0100
+Subject: serial: 8250: omap: Don't skip resource freeing if
+ pm_runtime_resume_and_get() failed
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit ad90d0358bd3b4554f243a425168fc7cebe7d04e ]
+
+Returning an error code from .remove() makes the driver core emit the
+little helpful error message:
+
+       remove callback returned a non-zero value. This will be ignored.
+
+and then remove the device anyhow. So all resources that were not freed
+are leaked in this case. Skipping serial8250_unregister_port() has the
+potential to keep enough of the UART around to trigger a use-after-free.
+
+So replace the error return (and with it the little helpful error
+message) by a more useful error message and continue to cleanup.
+
+Fixes: e3f0c638f428 ("serial: 8250: omap: Fix unpaired pm_runtime_put_sync() in omap8250_remove()")
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Tony Lindgren <tony@atomide.com>
+Link: https://lore.kernel.org/r/20231110152927.70601-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/8250/8250_omap.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c
+index 1122f37fe744..346167afe9e1 100644
+--- a/drivers/tty/serial/8250/8250_omap.c
++++ b/drivers/tty/serial/8250/8250_omap.c
+@@ -1581,7 +1581,7 @@ static int omap8250_remove(struct platform_device *pdev)
+       err = pm_runtime_resume_and_get(&pdev->dev);
+       if (err)
+-              return err;
++              dev_err(&pdev->dev, "Failed to resume hardware\n");
+       up = serial8250_get_port(priv->line);
+       omap_8250_shutdown(&up->port);
+-- 
+2.43.0
+
diff --git a/queue-6.6/serial-apbuart-fix-console-prompt-on-qemu.patch b/queue-6.6/serial-apbuart-fix-console-prompt-on-qemu.patch
new file mode 100644 (file)
index 0000000..6425530
--- /dev/null
@@ -0,0 +1,60 @@
+From 6ad23666d6e3d78562d15d1b3be3b897446651b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Dec 2023 13:16:07 +0100
+Subject: serial: apbuart: fix console prompt on qemu
+
+From: Sam Ravnborg <sam@ravnborg.org>
+
+[ Upstream commit c6dcd8050fb7c2efec6946ae9c49bc186b0a7475 ]
+
+When using a leon kernel with qemu there where no console prompt.
+The root cause is the handling of the fifo size in the tx part of the
+apbuart driver.
+
+The qemu uart driver only have a very rudimentary status handling and do
+not report the number of chars queued in the tx fifo in the status register.
+So the driver ends up with a fifo size of 1.
+
+In the tx path the fifo size is divided by 2 - resulting in a fifo
+size of zero.
+
+The original implementation would always try to send one char, but
+after the introduction of uart_port_tx_limited() the fifo size is
+respected even for the first char.
+
+There seems to be no good reason to divide the fifo size with two - so
+remove this. It looks like something copied from the original amba driver.
+
+With qemu we now have a minimum fifo size of one char, so we show
+the prompt.
+
+Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
+Fixes: d11cc8c3c4b6 ("tty: serial: use uart_port_tx_limited()")
+Cc: Andreas Larsson <andreas@gaisler.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: Jiri Slaby <jirislaby@kernel.org>
+Cc:  <linux-serial@vger.kernel.org>
+Cc:  <sparclinux@vger.kernel.org>
+Link: https://lore.kernel.org/r/20231226121607.GA2622970@ravnborg.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/apbuart.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
+index d7658f380838..d3cb341f2c55 100644
+--- a/drivers/tty/serial/apbuart.c
++++ b/drivers/tty/serial/apbuart.c
+@@ -122,7 +122,7 @@ static void apbuart_tx_chars(struct uart_port *port)
+ {
+       u8 ch;
+-      uart_port_tx_limited(port, ch, port->fifosize >> 1,
++      uart_port_tx_limited(port, ch, port->fifosize,
+               true,
+               UART_PUT_CHAR(port, ch),
+               ({}));
+-- 
+2.43.0
+
diff --git a/queue-6.6/serial-imx-correct-clock-error-message-in-function-p.patch b/queue-6.6/serial-imx-correct-clock-error-message-in-function-p.patch
new file mode 100644 (file)
index 0000000..3476548
--- /dev/null
@@ -0,0 +1,40 @@
+From f824fbefe270f6352b47031fd4364d37f5b6e5d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Dec 2023 10:32:09 +0100
+Subject: serial: imx: Correct clock error message in function probe()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+
+[ Upstream commit 3e189470cad27d41a3a9dc02649f965b7ed1c90f ]
+
+Correct the clock error message by changing the clock name.
+
+Fixes: 1e512d45332b ("serial: imx: add error messages when .probe fails")
+Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com>
+Reviewed-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20231224093209.2612-1-cniedermaier@dh-electronics.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/imx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index c084ac3bb441..cd36251ba1c0 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -2323,7 +2323,7 @@ static int imx_uart_probe(struct platform_device *pdev)
+       /* For register access, we only need to enable the ipg clock. */
+       ret = clk_prepare_enable(sport->clk_ipg);
+       if (ret) {
+-              dev_err(&pdev->dev, "failed to enable per clk: %d\n", ret);
++              dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret);
+               return ret;
+       }
+-- 
+2.43.0
+
diff --git a/queue-6.6/serial-imx-fix-tx-statemachine-deadlock.patch b/queue-6.6/serial-imx-fix-tx-statemachine-deadlock.patch
new file mode 100644 (file)
index 0000000..7076adf
--- /dev/null
@@ -0,0 +1,58 @@
+From 06a60b19795203064281636a3e1872a842653c5d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Nov 2023 14:11:10 +0100
+Subject: serial: imx: fix tx statemachine deadlock
+
+From: Paul Geurts <paul_geurts@live.nl>
+
+[ Upstream commit 78d60dae9a0c9f09aa3d6477c94047df2fe6f7b0 ]
+
+When using the serial port as RS485 port, the tx statemachine is used to
+control the RTS pin to drive the RS485 transceiver TX_EN pin. When the
+TTY port is closed in the middle of a transmission (for instance during
+userland application crash), imx_uart_shutdown disables the interface
+and disables the Transmission Complete interrupt. afer that,
+imx_uart_stop_tx bails on an incomplete transmission, to be retriggered
+by the TC interrupt. This interrupt is disabled and therefore the tx
+statemachine never transitions out of SEND. The statemachine is in
+deadlock now, and the TX_EN remains low, making the interface useless.
+
+imx_uart_stop_tx now checks for incomplete transmission AND whether TC
+interrupts are enabled before bailing to be retriggered. This makes sure
+the state machine handling is reached, and is properly set to
+WAIT_AFTER_SEND.
+
+Fixes: cb1a60923609 ("serial: imx: implement rts delaying for rs485")
+Signed-off-by: Paul Geurts <paul_geurts@live.nl>
+Tested-by: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
+Tested-by: Eberhard Stoll <eberhard.stoll@gmx.de>
+Link: https://lore.kernel.org/r/AM0PR09MB26758F651BC1B742EB45775995B8A@AM0PR09MB2675.eurprd09.prod.outlook.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/serial/imx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 2e85c77e7c0d..c084ac3bb441 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -421,13 +421,13 @@ static void imx_uart_stop_tx(struct uart_port *port)
+       ucr1 = imx_uart_readl(sport, UCR1);
+       imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1);
++      ucr4 = imx_uart_readl(sport, UCR4);
+       usr2 = imx_uart_readl(sport, USR2);
+-      if (!(usr2 & USR2_TXDC)) {
++      if ((!(usr2 & USR2_TXDC)) && (ucr4 & UCR4_TCEN)) {
+               /* The shifter is still busy, so retry once TC triggers */
+               return;
+       }
+-      ucr4 = imx_uart_readl(sport, UCR4);
+       ucr4 &= ~UCR4_TCEN;
+       imx_uart_writel(sport, ucr4, UCR4);
+-- 
+2.43.0
+
index 7bf57b068c8a1e7398f2bb16bcc3c765103bed22..5f1060302711593b11103f7e4910737b002b8edd 100644 (file)
@@ -434,3 +434,150 @@ hid-sensor-hub-enable-hid-core-report-processing-for-all-devices.patch
 hid-wacom-correct-behavior-when-processing-some-confidence-false-touches.patch
 serial-sc16is7xx-add-check-for-unsupported-spi-modes-during-probe.patch
 serial-sc16is7xx-set-safe-default-spi-clock-frequency.patch
+arm-9330-1-davinci-also-select-pinctrl.patch
+mfd-rk8xx-fixup-devices-registration-with-platform_d.patch
+mfd-cs42l43-correct-soundwire-port-list.patch
+mfd-syscon-fix-null-pointer-dereference-in-of_syscon.patch
+leds-aw2013-select-missing-dependency-regmap_i2c.patch
+leds-aw200xx-fix-write-to-dim-parameter.patch
+mfd-tps6594-add-null-pointer-check-to-tps6594_device.patch
+mfd-intel-lpss-fix-the-fractional-clock-divider-flag.patch
+srcu-use-try-lock-lockdep-annotation-for-nmi-safe-ac.patch
+mips-dmi-fix-early-remap-on-mips32.patch
+mips-fix-incorrect-max_low_pfn-adjustment.patch
+um-virt-pci-fix-platform-map-offset.patch
+riscv-check-if-the-code-to-patch-lies-in-the-exit-se.patch
+riscv-fix-module_alloc-that-did-not-reset-the-linear.patch
+riscv-fix-set_memory_xx-and-set_direct_map_xx-by-spl.patch
+riscv-fix-set_direct_map_default_noflush-to-reset-_p.patch
+riscv-fixed-wrong-register-in-xip_fixup_flash_offset.patch
+mips-alchemy-fix-an-out-of-bound-access-in-db1200_de.patch
+mips-alchemy-fix-an-out-of-bound-access-in-db1550_de.patch
+power-supply-cw2015-correct-time_to_empty-units-in-s.patch
+power-supply-bq256xx-fix-some-problem-in-bq256xx_hw_.patch
+pci-avoid-potential-out-of-bounds-read-in-pci_dev_fo.patch
+serial-8250-omap-don-t-skip-resource-freeing-if-pm_r.patch
+iommu-map-reserved-memory-as-cacheable-if-device-is-.patch
+perf-test-remove-atomics-from-test_loop-to-avoid-tes.patch
+perf-header-fix-segfault-on-build_mem_topology-error.patch
+libapi-add-missing-linux-types.h-header-to-get-the-_.patch
+usb-core-allow-subclassed-usb-drivers-to-override-us.patch
+r8152-choose-our-usb-config-with-choose_configuratio.patch
+perf-test-record-user-regs-fix-mask-for-vg-register.patch
+vfio-pds-fix-calculations-in-pds_vfio_dirty_sync.patch
+perf-vendor-events-arm64-ampereone-rename-bpu_flush_.patch
+perf-mem-fix-error-on-hybrid-related-to-availability.patch
+perf-stat-exit-perf-stat-if-parse-groups-fails.patch
+base-node.c-initialize-the-accessor-list-before-regi.patch
+acpi-property-let-args-be-null-in-__acpi_node_get_pr.patch
+software-node-let-args-be-null-in-software_node_get_.patch
+serial-imx-fix-tx-statemachine-deadlock.patch
+selftests-sgx-fix-uninitialized-pointer-dereference-.patch
+selftests-sgx-fix-uninitialized-pointer-dereferences.patch
+selftests-sgx-include-memory-clobber-for-inline-asm-.patch
+selftests-sgx-skip-non-x86_64-platform.patch
+iio-adc-ad9467-fix-reset-gpio-handling.patch
+iio-adc-ad9467-don-t-ignore-error-codes.patch
+iio-adc-ad9467-add-mutex-to-struct-ad9467_state.patch
+iio-adc-ad9467-fix-scale-setting.patch
+perf-header-fix-one-memory-leakage-in-perf_event__fp.patch
+perf-hisi-ptt-fix-one-memory-leakage-in-hisi_ptt_pro.patch
+perf-genelf-set-elf-program-header-addresses-properl.patch
+perf-unwind-libdw-handle-jit-generated-dsos-properly.patch
+perf-unwind-libunwind-fix-base-address-for-.eh_frame.patch
+bus-mhi-ep-do-not-allocate-event-ring-element-on-sta.patch
+bus-mhi-ep-use-slab-allocator-where-applicable.patch
+bus-mhi-ep-pass-mhi_ep_buf_info-struct-to-read-write.patch
+pci-epf-mhi-fix-the-dma-data-direction-of-dma_unmap_.patch
+tty-early-return-from-send_break-on-tty_driver_hardw.patch
+tty-don-t-check-for-signal_pending-in-send_break.patch
+tty-use-if-in-send_break-instead-of-goto.patch
+usb-cdc-acm-return-correct-error-code-on-unsupported.patch
+usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch
+spmi-mtk-pmif-serialize-pmif-status-check-and-comman.patch
+usb-gadget-webcam-make-g_webcam-loadable-again.patch
+iommu-don-t-reserve-0-length-iova-region.patch
+power-supply-fix-null-pointer-dereference-in-smb2_pr.patch
+vdpa-fix-an-error-handling-path-in-eni_vdpa_probe.patch
+apparmor-fix-ref-count-leak-in-task_kill.patch
+nvmet-tcp-fix-a-kernel-panic-when-host-sends-an-inva.patch
+nvmet-tcp-fix-a-crash-in-nvmet_req_complete.patch
+perf-env-avoid-recursively-taking-env-bpf_progs.lock.patch
+perf-stat-fix-hard-coded-ll-miss-units.patch
+cxl-region-fix-x9-interleave-typo.patch
+apparmor-fix-possible-memory-leak-in-unpack_trans_ta.patch
+apparmor-avoid-crash-when-parsed-profile-name-is-emp.patch
+usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch
+serial-imx-correct-clock-error-message-in-function-p.patch
+serial-apbuart-fix-console-prompt-on-qemu.patch
+perf-db-export-fix-missing-reference-count-get-in-ca.patch
+cxl-port-fix-missing-target-list-lock.patch
+spi-coldfire-qspi-remove-an-erroneous-clk_disable_un.patch
+hisi_acc_vfio_pci-update-migration-data-pointer-corr.patch
+nvmet-re-fix-tracing-strncpy-warning.patch
+nvme-trace-avoid-memcpy-overflow-warning.patch
+nvmet-tcp-fix-the-h2c-expected-pdu-len-calculation.patch
+pci-keystone-fix-race-condition-when-initializing-ph.patch
+pci-mediatek-gen3-fix-translation-window-size-calcul.patch
+asoc-mediatek-sof-common-add-null-check-for-normal_l.patch
+s390-pci-fix-max-size-calculation-in-zpci_memcpy_toi.patch
+net-qualcomm-rmnet-fix-global-oob-in-rmnet_policy.patch
+rxrpc-fix-use-of-don-t-fragment-flag.patch
+octeontx2-af-cn10kb-fix-fifo-length-calculation-for-.patch
+net-ethernet-ti-am65-cpsw-fix-max-mtu-to-fit-etherne.patch
+amt-do-not-use-overwrapped-cb-area.patch
+net-micrel-fix-ptp-frame-parsing-for-lan8841.patch
+net-phy-micrel-populate-.soft_reset-for-ksz9131.patch
+arm64-scs-work-around-full-lto-issue-with-dynamic-sc.patch
+alsa-hda-properly-setup-hdmi-stream.patch
+mptcp-mptcp_parse_option-fix-for-mptcpopt_mp_join.patch
+mptcp-strict-validation-before-using-mp_opt-hmac.patch
+mptcp-use-option_mptcp_mpj_synack-in-subflow_finish_.patch
+mptcp-use-option_mptcp_mpj_syn-in-subflow_check_req.patch
+mptcp-refine-opt_mp_capable-determination.patch
+block-ensure-we-hold-a-queue-reference-when-using-qu.patch
+net-stmmac-fix-ethool-link-settings-ops-for-integrat.patch
+udp-annotate-data-races-around-up-pending.patch
+erofs-simplify-compression-configuration-parser.patch
+erofs-fix-inconsistent-per-file-compression-format.patch
+net-add-more-sanity-check-in-virtio_net_hdr_to_skb.patch
+net-netdev_queue-netdev_txq_completed_mb-fix-wake-co.patch
+bpf-iter_udp-retry-with-a-larger-batch-size-without-.patch
+bpf-avoid-iter-offset-making-backward-progress-in-bp.patch
+net-tls-fix-warniing-in-__sk_msg_free.patch
+net-ravb-fix-dma_addr_t-truncation-in-error-case.patch
+dt-bindings-gpio-xilinx-fix-node-address-in-gpio.patch
+gpio-mlxbf3-add-an-error-code-check-in-mlxbf3_gpio_p.patch
+asoc-sof-ipc4-loader-remove-the-cpc-check-warnings.patch
+drm-amdkfd-fixes-for-hmm-mem-allocation.patch
+drm-amdgpu-fall-back-to-input-power-for-avg-power-vi.patch
+selftests-bonding-change-script-interpreter.patch
+net-stmmac-ethtool-fixed-calltrace-caused-by-unbalan.patch
+bpf-reject-variable-offset-alu-on-ptr_to_flow_keys.patch
+net-dsa-vsc73xx-add-null-pointer-check-to-vsc73xx_gp.patch
+loongarch-bpf-prevent-out-of-bounds-memory-access.patch
+mptcp-relax-check-on-mpc-passive-fallback.patch
+net-netdevsim-don-t-try-to-destroy-phc-on-vfs.patch
+netfilter-nf_tables-reject-invalid-set-policy.patch
+netfilter-nft_limit-do-not-ignore-unsupported-flags.patch
+netfilter-nfnetlink_log-use-proper-helper-for-fetchi.patch
+netfilter-nf_queue-remove-excess-nf_bridge-variable.patch
+netfilter-propagate-net-to-nf_bridge_get_physindev.patch
+netfilter-bridge-replace-physindev-with-physinif-in-.patch
+netfilter-nf_tables-do-not-allow-mismatch-field-size.patch
+netfilter-nf_tables-skip-dead-set-elements-in-netlin.patch
+netfilter-nf_tables-reject-nft_set_concat-with-not-f.patch
+ipvs-avoid-stat-macros-calls-from-preemptible-contex.patch
+io_uring-adjust-defer-tw-counting.patch
+kdb-fix-a-potential-buffer-overflow-in-kdb_local.patch
+arm64-ptrace-don-t-flush-za-zt-storage-when-writing-.patch
+ethtool-netlink-add-missing-ethnl_ops_begin-complete.patch
+loop-fix-the-the-direct-i-o-support-check-when-used-.patch
+mlxsw-spectrum_acl_erp-fix-error-flow-of-pool-alloca.patch
+mlxsw-spectrum_acl_tcam-fix-null-pointer-dereference.patch
+mlxsw-spectrum_acl_tcam-fix-stack-corruption.patch
+mlxsw-spectrum_router-register-netdevice-notifier-be.patch
+selftests-mlxsw-qos_pfc-adjust-the-test-to-support-8.patch
+ipv6-mcast-fix-data-race-in-ipv6_mc_down-mld_ifc_wor.patch
+i2c-s3c24xx-fix-read-transfers-in-polling-mode.patch
+i2c-s3c24xx-fix-transferring-more-than-one-message-i.patch
diff --git a/queue-6.6/software-node-let-args-be-null-in-software_node_get_.patch b/queue-6.6/software-node-let-args-be-null-in-software_node_get_.patch
new file mode 100644 (file)
index 0000000..212643a
--- /dev/null
@@ -0,0 +1,42 @@
+From 9f2a627d8043d249d42dafc7a96252ff186b5b00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Nov 2023 12:10:09 +0200
+Subject: software node: Let args be NULL in software_node_get_reference_args
+
+From: Sakari Ailus <sakari.ailus@linux.intel.com>
+
+[ Upstream commit 1eaea4b3604eb9ca7d9a1e73d88fc121bb4061f5 ]
+
+fwnode_get_property_reference_args() may not be called with args argument
+NULL and while OF already supports this. Add the missing NULL check.
+
+The purpose is to be able to count the references.
+
+Fixes: b06184acf751 ("software node: Add software_node_get_reference_args()")
+Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://lore.kernel.org/r/20231109101010.1329587-3-sakari.ailus@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/base/swnode.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c
+index 1886995a0b3a..079bd14bdedc 100644
+--- a/drivers/base/swnode.c
++++ b/drivers/base/swnode.c
+@@ -541,6 +541,9 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
+       if (nargs > NR_FWNODE_REFERENCE_ARGS)
+               return -EINVAL;
++      if (!args)
++              return 0;
++
+       args->fwnode = software_node_get(refnode);
+       args->nargs = nargs;
+-- 
+2.43.0
+
diff --git a/queue-6.6/spi-coldfire-qspi-remove-an-erroneous-clk_disable_un.patch b/queue-6.6/spi-coldfire-qspi-remove-an-erroneous-clk_disable_un.patch
new file mode 100644 (file)
index 0000000..f09af81
--- /dev/null
@@ -0,0 +1,42 @@
+From 2f82b08d7e9da774e40c6aff34b081cedf162ef5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 5 Jan 2024 15:21:00 +0100
+Subject: spi: coldfire-qspi: Remove an erroneous clk_disable_unprepare() from
+ the remove function
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit 17dc11a02d8dacc7e78968daa2a8c16281eb7d1e ]
+
+The commit in Fixes has changed a devm_clk_get()/clk_prepare_enable() into
+a devm_clk_get_enabled().
+It has updated the error handling path of the probe accordingly, but the
+remove has been left unchanged.
+
+Remove now the redundant clk_disable_unprepare() call from the remove
+function.
+
+Fixes: a90a987ebe00 ("spi: use devm_clk_get_enabled() in mcfqspi_probe()")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Link: https://msgid.link/r/6670aed303e1f7680e0911387606a8ae069e2cef.1704464447.git.christophe.jaillet@wanadoo.fr
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spi/spi-coldfire-qspi.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
+index f0b630fe16c3..b341b6908df0 100644
+--- a/drivers/spi/spi-coldfire-qspi.c
++++ b/drivers/spi/spi-coldfire-qspi.c
+@@ -441,7 +441,6 @@ static void mcfqspi_remove(struct platform_device *pdev)
+       mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
+       mcfqspi_cs_teardown(mcfqspi);
+-      clk_disable_unprepare(mcfqspi->clk);
+ }
+ #ifdef CONFIG_PM_SLEEP
+-- 
+2.43.0
+
diff --git a/queue-6.6/spmi-mtk-pmif-serialize-pmif-status-check-and-comman.patch b/queue-6.6/spmi-mtk-pmif-serialize-pmif-status-check-and-comman.patch
new file mode 100644 (file)
index 0000000..744e24a
--- /dev/null
@@ -0,0 +1,147 @@
+From c97395b77d96bd4f9f7f41db31e77f4eb51a0e42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 6 Dec 2023 15:17:24 -0800
+Subject: spmi: mtk-pmif: Serialize PMIF status check and command submission
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+
+[ Upstream commit f200fff8d019f2754f91f5d715652e3e3fdf3604 ]
+
+Before writing the read or write command to the SPMI arbiter through the
+PMIF interface, the current status of the channel is checked to ensure
+it is idle. However, since the status only changes from idle when the
+command is written, it is possible for two concurrent calls to determine
+that the channel is idle and simultaneously send their commands. At this
+point the PMIF interface hangs, with the status register no longer being
+updated, and thus causing all subsequent operations to time out.
+
+This was observed on the mt8195-cherry-tomato-r2 machine, particularly
+after commit 46600ab142f8 ("regulator: Set PROBE_PREFER_ASYNCHRONOUS for
+drivers between 5.10 and 5.15") was applied, since then the two MT6315
+devices present on the SPMI bus would probe assynchronously and
+sometimes (during probe or at a later point) read the bus
+simultaneously, breaking the PMIF interface and consequently slowing
+down the whole system.
+
+To fix the issue at its root cause, introduce locking around the channel
+status check and the command write, so that both become an atomic
+operation, preventing race conditions between two (or more) SPMI bus
+read/write operations. A spinlock is used since this is a fast bus, as
+indicated by the usage of the atomic variant of readl_poll, and
+'.fast_io = true' being used in the mt6315 driver, so spinlocks are
+already used for the regmap access.
+
+Fixes: b45b3ccef8c0 ("spmi: mediatek: Add support for MT6873/8192")
+Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
+Link: https://lore.kernel.org/r/20230724154739.493724-1-nfraprado@collabora.com
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Reviewed-by: Alexandre Mergnat <amergnat@baylibre.com>
+Signed-off-by: Stephen Boyd <sboyd@kernel.org>
+Link: https://lore.kernel.org/r/20231206231733.4031901-2-sboyd@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/spmi/spmi-mtk-pmif.c | 20 ++++++++++++++++----
+ 1 file changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c
+index b3c991e1ea40..54c35f5535cb 100644
+--- a/drivers/spmi/spmi-mtk-pmif.c
++++ b/drivers/spmi/spmi-mtk-pmif.c
+@@ -50,6 +50,7 @@ struct pmif {
+       struct clk_bulk_data clks[PMIF_MAX_CLKS];
+       size_t nclks;
+       const struct pmif_data *data;
++      raw_spinlock_t lock;
+ };
+ static const char * const pmif_clock_names[] = {
+@@ -314,6 +315,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+       struct ch_reg *inf_reg;
+       int ret;
+       u32 data, cmd;
++      unsigned long flags;
+       /* Check for argument validation. */
+       if (sid & ~0xf) {
+@@ -334,6 +336,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+       else
+               return -EINVAL;
++      raw_spin_lock_irqsave(&arb->lock, flags);
+       /* Wait for Software Interface FSM state to be IDLE. */
+       inf_reg = &arb->chan;
+       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+@@ -343,6 +346,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+               /* set channel ready if the data has transferred */
+               if (pmif_is_fsm_vldclr(arb))
+                       pmif_writel(arb, 1, inf_reg->ch_rdy);
++              raw_spin_unlock_irqrestore(&arb->lock, flags);
+               dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
+               return ret;
+       }
+@@ -350,6 +354,7 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+       /* Send the command. */
+       cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr;
+       pmif_writel(arb, cmd, inf_reg->ch_send);
++      raw_spin_unlock_irqrestore(&arb->lock, flags);
+       /*
+        * Wait for Software Interface FSM state to be WFVLDCLR,
+@@ -376,7 +381,8 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+       struct pmif *arb = spmi_controller_get_drvdata(ctrl);
+       struct ch_reg *inf_reg;
+       int ret;
+-      u32 data, cmd;
++      u32 data, wdata, cmd;
++      unsigned long flags;
+       if (len > 4) {
+               dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len);
+@@ -394,6 +400,10 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+       else
+               return -EINVAL;
++      /* Set the write data. */
++      memcpy(&wdata, buf, len);
++
++      raw_spin_lock_irqsave(&arb->lock, flags);
+       /* Wait for Software Interface FSM state to be IDLE. */
+       inf_reg = &arb->chan;
+       ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta],
+@@ -403,17 +413,17 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid,
+               /* set channel ready if the data has transferred */
+               if (pmif_is_fsm_vldclr(arb))
+                       pmif_writel(arb, 1, inf_reg->ch_rdy);
++              raw_spin_unlock_irqrestore(&arb->lock, flags);
+               dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n");
+               return ret;
+       }
+-      /* Set the write data. */
+-      memcpy(&data, buf, len);
+-      pmif_writel(arb, data, inf_reg->wdata);
++      pmif_writel(arb, wdata, inf_reg->wdata);
+       /* Send the command. */
+       cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr;
+       pmif_writel(arb, cmd, inf_reg->ch_send);
++      raw_spin_unlock_irqrestore(&arb->lock, flags);
+       return 0;
+ }
+@@ -488,6 +498,8 @@ static int mtk_spmi_probe(struct platform_device *pdev)
+       arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset;
+       arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset;
++      raw_spin_lock_init(&arb->lock);
++
+       platform_set_drvdata(pdev, ctrl);
+       err = spmi_controller_add(ctrl);
+-- 
+2.43.0
+
diff --git a/queue-6.6/srcu-use-try-lock-lockdep-annotation-for-nmi-safe-ac.patch b/queue-6.6/srcu-use-try-lock-lockdep-annotation-for-nmi-safe-ac.patch
new file mode 100644 (file)
index 0000000..c817920
--- /dev/null
@@ -0,0 +1,80 @@
+From 469d35257afc8710a025b620193ad12be23b636c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Nov 2023 14:27:29 +0100
+Subject: srcu: Use try-lock lockdep annotation for NMI-safe access.
+
+From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+
+[ Upstream commit 3c6b0c1c28184038d90dffe8eb542bedcb8ccf98 ]
+
+It is claimed that srcu_read_lock_nmisafe() NMI-safe. However it
+triggers a lockdep if used from NMI because lockdep expects a deadlock
+since nothing disables NMIs while the lock is acquired.
+
+This is because commit f0f44752f5f61 ("rcu: Annotate SRCU's update-side
+lockdep dependencies") annotates synchronize_srcu() as a write lock
+usage. This helps to detect a deadlocks such as
+       srcu_read_lock();
+       synchronize_srcu();
+       srcu_read_unlock();
+
+The side effect is that the lock srcu_struct now has a USED usage in normal
+contexts, so it conflicts with a USED_READ usage in NMI. But this shouldn't
+cause a real deadlock because the write lock usage from synchronize_srcu()
+is a fake one and only used for read/write deadlock detection.
+
+Use a try-lock annotation for srcu_read_lock_nmisafe() to avoid lockdep
+complains if used from NMI.
+
+Fixes: f0f44752f5f6 ("rcu: Annotate SRCU's update-side lockdep dependencies")
+Link: https://lore.kernel.org/r/20230927160231.XRCDDSK4@linutronix.de
+Reviewed-by: Boqun Feng <boqun.feng@gmail.com>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Neeraj Upadhyay (AMD) <neeraj.iitr10@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/rcupdate.h | 6 ++++++
+ include/linux/srcu.h     | 2 +-
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h
+index 5e5f920ade90..44aab5c0bd2c 100644
+--- a/include/linux/rcupdate.h
++++ b/include/linux/rcupdate.h
+@@ -303,6 +303,11 @@ static inline void rcu_lock_acquire(struct lockdep_map *map)
+       lock_acquire(map, 0, 0, 2, 0, NULL, _THIS_IP_);
+ }
++static inline void rcu_try_lock_acquire(struct lockdep_map *map)
++{
++      lock_acquire(map, 0, 1, 2, 0, NULL, _THIS_IP_);
++}
++
+ static inline void rcu_lock_release(struct lockdep_map *map)
+ {
+       lock_release(map, _THIS_IP_);
+@@ -317,6 +322,7 @@ int rcu_read_lock_any_held(void);
+ #else /* #ifdef CONFIG_DEBUG_LOCK_ALLOC */
+ # define rcu_lock_acquire(a)          do { } while (0)
++# define rcu_try_lock_acquire(a)      do { } while (0)
+ # define rcu_lock_release(a)          do { } while (0)
+ static inline int rcu_read_lock_held(void)
+diff --git a/include/linux/srcu.h b/include/linux/srcu.h
+index 127ef3b2e607..236610e4a8fa 100644
+--- a/include/linux/srcu.h
++++ b/include/linux/srcu.h
+@@ -229,7 +229,7 @@ static inline int srcu_read_lock_nmisafe(struct srcu_struct *ssp) __acquires(ssp
+       srcu_check_nmi_safety(ssp, true);
+       retval = __srcu_read_lock_nmisafe(ssp);
+-      rcu_lock_acquire(&ssp->dep_map);
++      rcu_try_lock_acquire(&ssp->dep_map);
+       return retval;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/tty-don-t-check-for-signal_pending-in-send_break.patch b/queue-6.6/tty-don-t-check-for-signal_pending-in-send_break.patch
new file mode 100644 (file)
index 0000000..63d843a
--- /dev/null
@@ -0,0 +1,38 @@
+From 174225978765a0c04518a9c3a6c7811844ae22e2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 10:51:55 +0200
+Subject: tty: don't check for signal_pending() in send_break()
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit fd99392b643b824813df2edbaebe26a2136d31e6 ]
+
+msleep_interruptible() will check on its own. So no need to do the check
+in send_break() before calling the above.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230919085156.1578-15-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index b6ddc1bf307b..ddcaf967f64b 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2484,8 +2484,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+       retval = tty->ops->break_ctl(tty, -1);
+       if (retval)
+               goto out;
+-      if (!signal_pending(current))
+-              msleep_interruptible(duration);
++      msleep_interruptible(duration);
+       retval = tty->ops->break_ctl(tty, 0);
+ out:
+       tty_write_unlock(tty);
+-- 
+2.43.0
+
diff --git a/queue-6.6/tty-early-return-from-send_break-on-tty_driver_hardw.patch b/queue-6.6/tty-early-return-from-send_break-on-tty_driver_hardw.patch
new file mode 100644 (file)
index 0000000..bd91aba
--- /dev/null
@@ -0,0 +1,74 @@
+From 74e68e01553d5d6610b8afa7582dc8df6804fa84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 10:51:54 +0200
+Subject: tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 66619686d187b4a6395316b7f39881e945dce4bc ]
+
+If the driver sets TTY_DRIVER_HARDWARE_BREAK, we leave ops->break_ctl()
+to the driver and return from send_break(). But we do it using a local
+variable and keep the code flowing through the end of the function.
+Instead, do 'return' immediately with the ops->break_ctl()'s return
+value.
+
+This way, we don't have to stuff the 'else' branch of the 'if' with the
+software break handling. And we can re-indent the function too.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230919085156.1578-14-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 32 +++++++++++++++++---------------
+ 1 file changed, 17 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 8a94e5a43c6d..b6ddc1bf307b 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2475,22 +2475,24 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+               return 0;
+       if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK)
+-              retval = tty->ops->break_ctl(tty, duration);
+-      else {
+-              /* Do the work ourselves */
+-              if (tty_write_lock(tty, false) < 0)
+-                      return -EINTR;
+-              retval = tty->ops->break_ctl(tty, -1);
+-              if (retval)
+-                      goto out;
+-              if (!signal_pending(current))
+-                      msleep_interruptible(duration);
+-              retval = tty->ops->break_ctl(tty, 0);
++              return tty->ops->break_ctl(tty, duration);
++
++      /* Do the work ourselves */
++      if (tty_write_lock(tty, false) < 0)
++              return -EINTR;
++
++      retval = tty->ops->break_ctl(tty, -1);
++      if (retval)
++              goto out;
++      if (!signal_pending(current))
++              msleep_interruptible(duration);
++      retval = tty->ops->break_ctl(tty, 0);
+ out:
+-              tty_write_unlock(tty);
+-              if (signal_pending(current))
+-                      retval = -EINTR;
+-      }
++      tty_write_unlock(tty);
++
++      if (signal_pending(current))
++              retval = -EINTR;
++
+       return retval;
+ }
+-- 
+2.43.0
+
diff --git a/queue-6.6/tty-use-if-in-send_break-instead-of-goto.patch b/queue-6.6/tty-use-if-in-send_break-instead-of-goto.patch
new file mode 100644 (file)
index 0000000..8877ba5
--- /dev/null
@@ -0,0 +1,44 @@
+From 1cf57680a6ad26016641f6e8d8972e2b17e7fc8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 Sep 2023 10:51:56 +0200
+Subject: tty: use 'if' in send_break() instead of 'goto'
+
+From: Jiri Slaby (SUSE) <jirislaby@kernel.org>
+
+[ Upstream commit 24f2cd019946fc2e88e632d2e24a34c2cc3f2be4 ]
+
+Now, the "jumped-over" code is simple enough to be put inside an 'if'.
+Do so to make it 'goto'-less.
+
+Signed-off-by: "Jiri Slaby (SUSE)" <jirislaby@kernel.org>
+Link: https://lore.kernel.org/r/20230919085156.1578-16-jirislaby@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 66aad7d8d3ec ("usb: cdc-acm: return correct error code on unsupported break")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index ddcaf967f64b..724ebf82f2cd 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2482,11 +2482,10 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+               return -EINTR;
+       retval = tty->ops->break_ctl(tty, -1);
+-      if (retval)
+-              goto out;
+-      msleep_interruptible(duration);
+-      retval = tty->ops->break_ctl(tty, 0);
+-out:
++      if (!retval) {
++              msleep_interruptible(duration);
++              retval = tty->ops->break_ctl(tty, 0);
++      }
+       tty_write_unlock(tty);
+       if (signal_pending(current))
+-- 
+2.43.0
+
diff --git a/queue-6.6/udp-annotate-data-races-around-up-pending.patch b/queue-6.6/udp-annotate-data-races-around-up-pending.patch
new file mode 100644 (file)
index 0000000..a215d3b
--- /dev/null
@@ -0,0 +1,194 @@
+From 554cdc88962a871e8ca64e67044b170fe41fffc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Jan 2024 10:44:27 +0000
+Subject: udp: annotate data-races around up->pending
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 482521d8e0c6520429478aa6866cd44128b33d5d ]
+
+up->pending can be read without holding the socket lock,
+as pointed out by syzbot [1]
+
+Add READ_ONCE() in lockless contexts, and WRITE_ONCE()
+on write side.
+
+[1]
+BUG: KCSAN: data-race in udpv6_sendmsg / udpv6_sendmsg
+
+write to 0xffff88814e5eadf0 of 4 bytes by task 15547 on cpu 1:
+ udpv6_sendmsg+0x1405/0x1530 net/ipv6/udp.c:1596
+ inet6_sendmsg+0x63/0x80 net/ipv6/af_inet6.c:657
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg net/socket.c:745 [inline]
+ __sys_sendto+0x257/0x310 net/socket.c:2192
+ __do_sys_sendto net/socket.c:2204 [inline]
+ __se_sys_sendto net/socket.c:2200 [inline]
+ __x64_sys_sendto+0x78/0x90 net/socket.c:2200
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+read to 0xffff88814e5eadf0 of 4 bytes by task 15551 on cpu 0:
+ udpv6_sendmsg+0x22c/0x1530 net/ipv6/udp.c:1373
+ inet6_sendmsg+0x63/0x80 net/ipv6/af_inet6.c:657
+ sock_sendmsg_nosec net/socket.c:730 [inline]
+ __sock_sendmsg net/socket.c:745 [inline]
+ ____sys_sendmsg+0x37c/0x4d0 net/socket.c:2586
+ ___sys_sendmsg net/socket.c:2640 [inline]
+ __sys_sendmmsg+0x269/0x500 net/socket.c:2726
+ __do_sys_sendmmsg net/socket.c:2755 [inline]
+ __se_sys_sendmmsg net/socket.c:2752 [inline]
+ __x64_sys_sendmmsg+0x57/0x60 net/socket.c:2752
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0x44/0x110 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x63/0x6b
+
+value changed: 0x00000000 -> 0x0000000a
+
+Reported by Kernel Concurrency Sanitizer on:
+CPU: 0 PID: 15551 Comm: syz-executor.1 Tainted: G        W          6.7.0-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/17/2023
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: syzbot+8d482d0e407f665d9d10@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/netdev/0000000000009e46c3060ebcdffd@google.com/
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/udp.c | 12 ++++++------
+ net/ipv6/udp.c | 16 ++++++++--------
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index c3ff984b6354..bd12a7658213 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -805,7 +805,7 @@ void udp_flush_pending_frames(struct sock *sk)
+       if (up->pending) {
+               up->len = 0;
+-              up->pending = 0;
++              WRITE_ONCE(up->pending, 0);
+               ip_flush_pending_frames(sk);
+       }
+ }
+@@ -993,7 +993,7 @@ int udp_push_pending_frames(struct sock *sk)
+ out:
+       up->len = 0;
+-      up->pending = 0;
++      WRITE_ONCE(up->pending, 0);
+       return err;
+ }
+ EXPORT_SYMBOL(udp_push_pending_frames);
+@@ -1069,7 +1069,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+       getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
+       fl4 = &inet->cork.fl.u.ip4;
+-      if (up->pending) {
++      if (READ_ONCE(up->pending)) {
+               /*
+                * There are pending frames.
+                * The socket lock must be held while it's corked.
+@@ -1265,7 +1265,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+       fl4->saddr = saddr;
+       fl4->fl4_dport = dport;
+       fl4->fl4_sport = inet->inet_sport;
+-      up->pending = AF_INET;
++      WRITE_ONCE(up->pending, AF_INET);
+ do_append_data:
+       up->len += ulen;
+@@ -1277,7 +1277,7 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+       else if (!corkreq)
+               err = udp_push_pending_frames(sk);
+       else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
+-              up->pending = 0;
++              WRITE_ONCE(up->pending, 0);
+       release_sock(sk);
+ out:
+@@ -1315,7 +1315,7 @@ void udp_splice_eof(struct socket *sock)
+       struct sock *sk = sock->sk;
+       struct udp_sock *up = udp_sk(sk);
+-      if (!up->pending || udp_test_bit(CORK, sk))
++      if (!READ_ONCE(up->pending) || udp_test_bit(CORK, sk))
+               return;
+       lock_sock(sk);
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index f60ba4295435..f1170dcc21d9 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -1134,7 +1134,7 @@ static void udp_v6_flush_pending_frames(struct sock *sk)
+               udp_flush_pending_frames(sk);
+       else if (up->pending) {
+               up->len = 0;
+-              up->pending = 0;
++              WRITE_ONCE(up->pending, 0);
+               ip6_flush_pending_frames(sk);
+       }
+ }
+@@ -1312,7 +1312,7 @@ static int udp_v6_push_pending_frames(struct sock *sk)
+                             &inet_sk(sk)->cork.base);
+ out:
+       up->len = 0;
+-      up->pending = 0;
++      WRITE_ONCE(up->pending, 0);
+       return err;
+ }
+@@ -1369,7 +1369,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+               default:
+                       return -EINVAL;
+               }
+-      } else if (!up->pending) {
++      } else if (!READ_ONCE(up->pending)) {
+               if (sk->sk_state != TCP_ESTABLISHED)
+                       return -EDESTADDRREQ;
+               daddr = &sk->sk_v6_daddr;
+@@ -1400,8 +1400,8 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+               return -EMSGSIZE;
+       getfrag  =  is_udplite ?  udplite_getfrag : ip_generic_getfrag;
+-      if (up->pending) {
+-              if (up->pending == AF_INET)
++      if (READ_ONCE(up->pending)) {
++              if (READ_ONCE(up->pending) == AF_INET)
+                       return udp_sendmsg(sk, msg, len);
+               /*
+                * There are pending frames.
+@@ -1591,7 +1591,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+               goto out;
+       }
+-      up->pending = AF_INET6;
++      WRITE_ONCE(up->pending, AF_INET6);
+ do_append_data:
+       if (ipc6.dontfrag < 0)
+@@ -1605,7 +1605,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+       else if (!corkreq)
+               err = udp_v6_push_pending_frames(sk);
+       else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
+-              up->pending = 0;
++              WRITE_ONCE(up->pending, 0);
+       if (err > 0)
+               err = np->recverr ? net_xmit_errno(err) : 0;
+@@ -1646,7 +1646,7 @@ static void udpv6_splice_eof(struct socket *sock)
+       struct sock *sk = sock->sk;
+       struct udp_sock *up = udp_sk(sk);
+-      if (!up->pending || udp_test_bit(CORK, sk))
++      if (!READ_ONCE(up->pending) || udp_test_bit(CORK, sk))
+               return;
+       lock_sock(sk);
+-- 
+2.43.0
+
diff --git a/queue-6.6/um-virt-pci-fix-platform-map-offset.patch b/queue-6.6/um-virt-pci-fix-platform-map-offset.patch
new file mode 100644 (file)
index 0000000..4f36121
--- /dev/null
@@ -0,0 +1,36 @@
+From 02bb8c5c811d1d8398ebb3895cfd8918134232bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Sep 2023 15:35:43 +0200
+Subject: um: virt-pci: fix platform map offset
+
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+[ Upstream commit 32253f00ac8a8073bf6db4bfe9d6511cc93c4aef ]
+
+The offset is currently always zero so the backend can't distinguish
+between accesses to different ioremapped areas.
+
+Fixes: 522c532c4fe7 ("virt-pci: add platform bus support")
+Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/um/drivers/virt-pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c
+index ffe2ee8a0246..97a37c062997 100644
+--- a/arch/um/drivers/virt-pci.c
++++ b/arch/um/drivers/virt-pci.c
+@@ -971,7 +971,7 @@ static long um_pci_map_platform(unsigned long offset, size_t size,
+       *ops = &um_pci_device_bar_ops;
+       *priv = &um_pci_platform_device->resptr[0];
+-      return 0;
++      return offset;
+ }
+ static const struct logic_iomem_region_ops um_pci_platform_ops = {
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-cdc-acm-return-correct-error-code-on-unsupported.patch b/queue-6.6/usb-cdc-acm-return-correct-error-code-on-unsupported.patch
new file mode 100644 (file)
index 0000000..e2fae3e
--- /dev/null
@@ -0,0 +1,62 @@
+From fb4779fe8c05785c2ed080eb55a628135e8da063 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Dec 2023 14:26:30 +0100
+Subject: usb: cdc-acm: return correct error code on unsupported break
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 66aad7d8d3ec5a3a8ec2023841bcec2ded5f65c9 ]
+
+In ACM support for sending breaks to devices is optional.
+If a device says that it doenot support sending breaks,
+the host must respect that.
+Given the number of optional features providing tty operations
+for each combination is not practical and errors need to be
+returned dynamically if unsupported features are requested.
+
+In case a device does not support break, we want the tty layer
+to treat that like it treats drivers that statically cannot
+support sending a break. It ignores the inability and does nothing.
+This patch uses EOPNOTSUPP to indicate that.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Fixes: 9e98966c7bb94 ("tty: rework break handling")
+Link: https://lore.kernel.org/r/20231207132639.18250-1-oneukum@suse.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/tty/tty_io.c        | 3 +++
+ drivers/usb/class/cdc-acm.c | 3 +++
+ 2 files changed, 6 insertions(+)
+
+diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
+index 724ebf82f2cd..493fc4742895 100644
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2485,6 +2485,9 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
+       if (!retval) {
+               msleep_interruptible(duration);
+               retval = tty->ops->break_ctl(tty, 0);
++      } else if (retval == -EOPNOTSUPP) {
++              /* some drivers can tell only dynamically */
++              retval = 0;
+       }
+       tty_write_unlock(tty);
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index a1f4e1ead97f..0e7439dba8fe 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -916,6 +916,9 @@ static int acm_tty_break_ctl(struct tty_struct *tty, int state)
+       struct acm *acm = tty->driver_data;
+       int retval;
++      if (!(acm->ctrl_caps & USB_CDC_CAP_BRK))
++              return -EOPNOTSUPP;
++
+       retval = acm_send_break(acm, state ? 0xffff : 0);
+       if (retval < 0)
+               dev_dbg(&acm->control->dev,
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-core-allow-subclassed-usb-drivers-to-override-us.patch b/queue-6.6/usb-core-allow-subclassed-usb-drivers-to-override-us.patch
new file mode 100644 (file)
index 0000000..62ddbac
--- /dev/null
@@ -0,0 +1,89 @@
+From e298d511909d50f1da9e63a5b5949f41a77dc2a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 1 Dec 2023 10:29:51 -0800
+Subject: usb: core: Allow subclassed USB drivers to override
+ usb_choose_configuration()
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit a87b8e3be926af0fc3b9b1af42b1127bd1ff077c ]
+
+For some USB devices we might want to do something different for
+usb_choose_configuration(). One example here is the r8152 driver where
+we want to end up using the vendor driver with the preferred
+interface.
+
+The r8152 driver tried to make things work by implementing a USB
+generic_subclass driver and then overriding the normal config
+selection after it happened. This is less than ideal and also caused
+breakage if someone deauthorized and re-authorized the USB device
+because the USB core ended up going back to it's default logic for
+choosing the best config. I made an attempt to fix this [1] but it was
+a bit ugly.
+
+Let's do this better and allow USB generic_subclass drivers to
+override usb_choose_configuration().
+
+[1] https://lore.kernel.org/r/20231130154337.1.Ie00e07f07f87149c9ce0b27ae4e26991d307e14b@changeid
+
+Suggested-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Link: https://lore.kernel.org/r/20231201102946.v2.2.Iade5fa31997f1a0ca3e1dec0591633b02471df12@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: aa4f2b3e418e ("r8152: Choose our USB config with choose_configuration() rather than probe()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/generic.c | 7 +++++++
+ include/linux/usb.h        | 6 ++++++
+ 2 files changed, 13 insertions(+)
+
+diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
+index 740342a2812a..dcb897158228 100644
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -59,10 +59,17 @@ int usb_choose_configuration(struct usb_device *udev)
+       int num_configs;
+       int insufficient_power = 0;
+       struct usb_host_config *c, *best;
++      struct usb_device_driver *udriver = to_usb_device_driver(udev->dev.driver);
+       if (usb_device_is_owned(udev))
+               return 0;
++      if (udriver->choose_configuration) {
++              i = udriver->choose_configuration(udev);
++              if (i >= 0)
++                      return i;
++      }
++
+       best = NULL;
+       c = udev->config;
+       num_configs = udev->descriptor.bNumConfigurations;
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index a21074861f91..bfd77ece0643 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -1264,6 +1264,9 @@ struct usb_driver {
+  *    module is being unloaded.
+  * @suspend: Called when the device is going to be suspended by the system.
+  * @resume: Called when the device is being resumed by the system.
++ * @choose_configuration: If non-NULL, called instead of the default
++ *    usb_choose_configuration(). If this returns an error then we'll go
++ *    on to call the normal usb_choose_configuration().
+  * @dev_groups: Attributes attached to the device that will be created once it
+  *    is bound to the driver.
+  * @drvwrap: Driver-model core structure wrapper.
+@@ -1287,6 +1290,9 @@ struct usb_device_driver {
+       int (*suspend) (struct usb_device *udev, pm_message_t message);
+       int (*resume) (struct usb_device *udev, pm_message_t message);
++
++      int (*choose_configuration) (struct usb_device *udev);
++
+       const struct attribute_group **dev_groups;
+       struct usbdrv_wrap drvwrap;
+       const struct usb_device_id *id_table;
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch b/queue-6.6/usb-core-fix-crash-w-usb_choose_configuration-if-no-.patch
new file mode 100644 (file)
index 0000000..cf34e16
--- /dev/null
@@ -0,0 +1,64 @@
+From f40a7d1b7ffa8ee851a2a3bcd4237c10c564445d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 11 Dec 2023 07:32:41 -0800
+Subject: usb: core: Fix crash w/ usb_choose_configuration() if no driver
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 44995e6f07028f798efd0c3c11a1efc78330f600 ]
+
+It's possible that usb_choose_configuration() can get called when a
+USB device has no driver. In this case the recent commit a87b8e3be926
+("usb: core: Allow subclassed USB drivers to override
+usb_choose_configuration()") can cause a crash since it dereferenced
+the driver structure without checking for NULL. Let's add a check.
+
+A USB device with no driver is an anomaly, so make
+usb_choose_configuration() return immediately if there is no driver.
+
+This was seen in the real world when usbguard got ahold of a r8152
+device at the wrong time. It can also be simulated via this on a
+computer with one r8152-based USB Ethernet adapter:
+  cd /sys/bus/usb/drivers/r8152-cfgselector
+  to_unbind="$(ls -d *-*)"
+  real_dir="$(readlink -f "${to_unbind}")"
+  echo "${to_unbind}" > unbind
+  cd "${real_dir}"
+  echo 0 > authorized
+  echo 1 > authorized
+
+Fixes: a87b8e3be926 ("usb: core: Allow subclassed USB drivers to override usb_choose_configuration()")
+Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Link: https://lore.kernel.org/r/20231211073237.v3.1.If27eb3bf7812f91ab83810f232292f032f4203e0@changeid
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/core/generic.c | 11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
+index dcb897158228..b134bff5c3fe 100644
+--- a/drivers/usb/core/generic.c
++++ b/drivers/usb/core/generic.c
+@@ -59,7 +59,16 @@ int usb_choose_configuration(struct usb_device *udev)
+       int num_configs;
+       int insufficient_power = 0;
+       struct usb_host_config *c, *best;
+-      struct usb_device_driver *udriver = to_usb_device_driver(udev->dev.driver);
++      struct usb_device_driver *udriver;
++
++      /*
++       * If a USB device (not an interface) doesn't have a driver then the
++       * kernel has no business trying to select or install a configuration
++       * for it.
++       */
++      if (!udev->dev.driver)
++              return -1;
++      udriver = to_usb_device_driver(udev->dev.driver);
+       if (usb_device_is_owned(udev))
+               return 0;
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-gadget-webcam-make-g_webcam-loadable-again.patch b/queue-6.6/usb-gadget-webcam-make-g_webcam-loadable-again.patch
new file mode 100644 (file)
index 0000000..8df1ff9
--- /dev/null
@@ -0,0 +1,553 @@
+From e0c9c4ba63fc869b7910b8f51c55444decc92c39 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 Dec 2023 14:16:14 +0100
+Subject: usb: gadget: webcam: Make g_webcam loadable again
+
+From: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+
+[ Upstream commit f1fd91a0924b6bff91ca1287461fb8e3b3b61d92 ]
+
+commit 588b9e85609b ("usb: gadget: uvc: add v4l2 enumeration api calls")
+has rendered the precomposed (aka legacy) webcam gadget unloadable.
+
+uvc_alloc() since then has depended on certain config groups being
+available in configfs tree related to the UVC function. However, legacy
+gadgets do not create anything in configfs, so uvc_alloc() must fail
+with -ENOENT no matter what.
+
+This patch mimics the required configfs hierarchy to satisfy the code which
+inspects formats and frames found in uvcg_streaming_header.
+
+This has been tested with guvcview on the host side, using vivid as a
+source of video stream on the device side and using the userspace program
+found at https://gitlab.freedesktop.org/camera/uvc-gadget.git.
+
+Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Fixes: 588b9e85609b ("usb: gadget: uvc: add v4l2 enumeration api calls")
+Link: https://lore.kernel.org/r/20231215131614.29132-1-andrzej.p@collabora.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/gadget/function/f_uvc.c |  45 ++--
+ drivers/usb/gadget/function/u_uvc.h |   6 +
+ drivers/usb/gadget/legacy/webcam.c  | 333 +++++++++++++++++++++-------
+ 3 files changed, 284 insertions(+), 100 deletions(-)
+
+diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
+index 3d5c03e1361e..2e6bafb2a554 100644
+--- a/drivers/usb/gadget/function/f_uvc.c
++++ b/drivers/usb/gadget/function/f_uvc.c
+@@ -966,7 +966,8 @@ static void uvc_free(struct usb_function *f)
+       struct uvc_device *uvc = to_uvc(f);
+       struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts,
+                                              func_inst);
+-      config_item_put(&uvc->header->item);
++      if (!opts->header)
++              config_item_put(&uvc->header->item);
+       --opts->refcnt;
+       kfree(uvc);
+ }
+@@ -1058,25 +1059,29 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi)
+       uvc->desc.hs_streaming = opts->hs_streaming;
+       uvc->desc.ss_streaming = opts->ss_streaming;
+-      streaming = config_group_find_item(&opts->func_inst.group, "streaming");
+-      if (!streaming)
+-              goto err_config;
+-
+-      header = config_group_find_item(to_config_group(streaming), "header");
+-      config_item_put(streaming);
+-      if (!header)
+-              goto err_config;
+-
+-      h = config_group_find_item(to_config_group(header), "h");
+-      config_item_put(header);
+-      if (!h)
+-              goto err_config;
+-
+-      uvc->header = to_uvcg_streaming_header(h);
+-      if (!uvc->header->linked) {
+-              mutex_unlock(&opts->lock);
+-              kfree(uvc);
+-              return ERR_PTR(-EBUSY);
++      if (opts->header) {
++              uvc->header = opts->header;
++      } else {
++              streaming = config_group_find_item(&opts->func_inst.group, "streaming");
++              if (!streaming)
++                      goto err_config;
++
++              header = config_group_find_item(to_config_group(streaming), "header");
++              config_item_put(streaming);
++              if (!header)
++                      goto err_config;
++
++              h = config_group_find_item(to_config_group(header), "h");
++              config_item_put(header);
++              if (!h)
++                      goto err_config;
++
++              uvc->header = to_uvcg_streaming_header(h);
++              if (!uvc->header->linked) {
++                      mutex_unlock(&opts->lock);
++                      kfree(uvc);
++                      return ERR_PTR(-EBUSY);
++              }
+       }
+       uvc->desc.extension_units = &opts->extension_units;
+diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h
+index 1ce58f61253c..3ac392cbb779 100644
+--- a/drivers/usb/gadget/function/u_uvc.h
++++ b/drivers/usb/gadget/function/u_uvc.h
+@@ -98,6 +98,12 @@ struct f_uvc_opts {
+        */
+       struct mutex                    lock;
+       int                             refcnt;
++
++      /*
++       * Only for legacy gadget. Shall be NULL for configfs-composed gadgets,
++       * which is guaranteed by alloc_inst implementation of f_uvc doing kzalloc.
++       */
++      struct uvcg_streaming_header    *header;
+ };
+ #endif /* U_UVC_H */
+diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c
+index c06dd1af7a0c..c395438d3978 100644
+--- a/drivers/usb/gadget/legacy/webcam.c
++++ b/drivers/usb/gadget/legacy/webcam.c
+@@ -12,6 +12,7 @@
+ #include <linux/usb/video.h>
+ #include "u_uvc.h"
++#include "uvc_configfs.h"
+ USB_GADGET_COMPOSITE_OPTIONS();
+@@ -84,8 +85,6 @@ static struct usb_device_descriptor webcam_device_descriptor = {
+       .bNumConfigurations     = 0, /* dynamic */
+ };
+-DECLARE_UVC_HEADER_DESCRIPTOR(1);
+-
+ static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = {
+       .bLength                = UVC_DT_HEADER_SIZE(1),
+       .bDescriptorType        = USB_DT_CS_INTERFACE,
+@@ -158,43 +157,112 @@ static const struct UVC_INPUT_HEADER_DESCRIPTOR(1, 2) uvc_input_header = {
+       .bmaControls[1][0]      = 4,
+ };
+-static const struct uvc_format_uncompressed uvc_format_yuv = {
+-      .bLength                = UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
+-      .bDescriptorType        = USB_DT_CS_INTERFACE,
+-      .bDescriptorSubType     = UVC_VS_FORMAT_UNCOMPRESSED,
+-      .bFormatIndex           = 1,
+-      .bNumFrameDescriptors   = 2,
+-      .guidFormat             =
+-              { 'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
+-               0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71},
+-      .bBitsPerPixel          = 16,
+-      .bDefaultFrameIndex     = 1,
+-      .bAspectRatioX          = 0,
+-      .bAspectRatioY          = 0,
+-      .bmInterlaceFlags       = 0,
+-      .bCopyProtect           = 0,
++static const struct uvcg_color_matching uvcg_color_matching = {
++      .desc = {
++              .bLength                = UVC_DT_COLOR_MATCHING_SIZE,
++              .bDescriptorType        = USB_DT_CS_INTERFACE,
++              .bDescriptorSubType     = UVC_VS_COLORFORMAT,
++              .bColorPrimaries        = 1,
++              .bTransferCharacteristics       = 1,
++              .bMatrixCoefficients    = 4,
++      },
++};
++
++static struct uvcg_uncompressed uvcg_format_yuv = {
++      .fmt = {
++              .type                   = UVCG_UNCOMPRESSED,
++              /* add to .frames and fill .num_frames at runtime */
++              .color_matching         = (struct uvcg_color_matching *)&uvcg_color_matching,
++      },
++      .desc = {
++              .bLength                = UVC_DT_FORMAT_UNCOMPRESSED_SIZE,
++              .bDescriptorType        = USB_DT_CS_INTERFACE,
++              .bDescriptorSubType     = UVC_VS_FORMAT_UNCOMPRESSED,
++              .bFormatIndex           = 1,
++              .bNumFrameDescriptors   = 2,
++              .guidFormat             = {
++                      'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
++                       0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
++              },
++              .bBitsPerPixel          = 16,
++              .bDefaultFrameIndex     = 1,
++              .bAspectRatioX          = 0,
++              .bAspectRatioY          = 0,
++              .bmInterlaceFlags       = 0,
++              .bCopyProtect           = 0,
++      },
++};
++
++static struct uvcg_format_ptr uvcg_format_ptr_yuv = {
++      .fmt = &uvcg_format_yuv.fmt,
+ };
+ DECLARE_UVC_FRAME_UNCOMPRESSED(1);
+ DECLARE_UVC_FRAME_UNCOMPRESSED(3);
++#define UVCG_WIDTH_360P                       640
++#define UVCG_HEIGHT_360P              360
++#define UVCG_MIN_BITRATE_360P         18432000
++#define UVCG_MAX_BITRATE_360P         55296000
++#define UVCG_MAX_VIDEO_FB_SZ_360P     460800
++#define UVCG_FRM_INTERV_0_360P                666666
++#define UVCG_FRM_INTERV_1_360P                1000000
++#define UVCG_FRM_INTERV_2_360P                5000000
++#define UVCG_DEFAULT_FRM_INTERV_360P  UVCG_FRM_INTERV_0_360P
++
+ static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = {
+       .bLength                = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
+       .bDescriptorType        = USB_DT_CS_INTERFACE,
+       .bDescriptorSubType     = UVC_VS_FRAME_UNCOMPRESSED,
+       .bFrameIndex            = 1,
+       .bmCapabilities         = 0,
+-      .wWidth                 = cpu_to_le16(640),
+-      .wHeight                = cpu_to_le16(360),
+-      .dwMinBitRate           = cpu_to_le32(18432000),
+-      .dwMaxBitRate           = cpu_to_le32(55296000),
+-      .dwMaxVideoFrameBufferSize      = cpu_to_le32(460800),
+-      .dwDefaultFrameInterval = cpu_to_le32(666666),
++      .wWidth                 = cpu_to_le16(UVCG_WIDTH_360P),
++      .wHeight                = cpu_to_le16(UVCG_HEIGHT_360P),
++      .dwMinBitRate           = cpu_to_le32(UVCG_MIN_BITRATE_360P),
++      .dwMaxBitRate           = cpu_to_le32(UVCG_MAX_BITRATE_360P),
++      .dwMaxVideoFrameBufferSize      = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P),
++      .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P),
+       .bFrameIntervalType     = 3,
+-      .dwFrameInterval[0]     = cpu_to_le32(666666),
+-      .dwFrameInterval[1]     = cpu_to_le32(1000000),
+-      .dwFrameInterval[2]     = cpu_to_le32(5000000),
++      .dwFrameInterval[0]     = cpu_to_le32(UVCG_FRM_INTERV_0_360P),
++      .dwFrameInterval[1]     = cpu_to_le32(UVCG_FRM_INTERV_1_360P),
++      .dwFrameInterval[2]     = cpu_to_le32(UVCG_FRM_INTERV_2_360P),
++};
++
++static u32 uvcg_frame_yuv_360p_dw_frame_interval[] = {
++      [0] = UVCG_FRM_INTERV_0_360P,
++      [1] = UVCG_FRM_INTERV_1_360P,
++      [2] = UVCG_FRM_INTERV_2_360P,
++};
++
++static const struct uvcg_frame uvcg_frame_yuv_360p = {
++      .fmt_type               = UVCG_UNCOMPRESSED,
++      .frame = {
++              .b_length                       = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3),
++              .b_descriptor_type              = USB_DT_CS_INTERFACE,
++              .b_descriptor_subtype           = UVC_VS_FRAME_UNCOMPRESSED,
++              .b_frame_index                  = 1,
++              .bm_capabilities                = 0,
++              .w_width                        = UVCG_WIDTH_360P,
++              .w_height                       = UVCG_HEIGHT_360P,
++              .dw_min_bit_rate                = UVCG_MIN_BITRATE_360P,
++              .dw_max_bit_rate                = UVCG_MAX_BITRATE_360P,
++              .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_360P,
++              .dw_default_frame_interval      = UVCG_DEFAULT_FRM_INTERV_360P,
++              .b_frame_interval_type          = 3,
++      },
++      .dw_frame_interval      = uvcg_frame_yuv_360p_dw_frame_interval,
++};
++
++static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_360p = {
++      .frm = (struct uvcg_frame *)&uvcg_frame_yuv_360p,
+ };
++#define UVCG_WIDTH_720P                       1280
++#define UVCG_HEIGHT_720P              720
++#define UVCG_MIN_BITRATE_720P         29491200
++#define UVCG_MAX_BITRATE_720P         29491200
++#define UVCG_MAX_VIDEO_FB_SZ_720P     1843200
++#define UVCG_FRM_INTERV_0_720P                5000000
++#define UVCG_DEFAULT_FRM_INTERV_720P  UVCG_FRM_INTERV_0_720P
+ static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
+       .bLength                = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
+@@ -202,28 +270,66 @@ static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = {
+       .bDescriptorSubType     = UVC_VS_FRAME_UNCOMPRESSED,
+       .bFrameIndex            = 2,
+       .bmCapabilities         = 0,
+-      .wWidth                 = cpu_to_le16(1280),
+-      .wHeight                = cpu_to_le16(720),
+-      .dwMinBitRate           = cpu_to_le32(29491200),
+-      .dwMaxBitRate           = cpu_to_le32(29491200),
+-      .dwMaxVideoFrameBufferSize      = cpu_to_le32(1843200),
+-      .dwDefaultFrameInterval = cpu_to_le32(5000000),
++      .wWidth                 = cpu_to_le16(UVCG_WIDTH_720P),
++      .wHeight                = cpu_to_le16(UVCG_HEIGHT_720P),
++      .dwMinBitRate           = cpu_to_le32(UVCG_MIN_BITRATE_720P),
++      .dwMaxBitRate           = cpu_to_le32(UVCG_MAX_BITRATE_720P),
++      .dwMaxVideoFrameBufferSize      = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P),
++      .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P),
+       .bFrameIntervalType     = 1,
+-      .dwFrameInterval[0]     = cpu_to_le32(5000000),
++      .dwFrameInterval[0]     = cpu_to_le32(UVCG_FRM_INTERV_0_720P),
+ };
+-static const struct uvc_format_mjpeg uvc_format_mjpg = {
+-      .bLength                = UVC_DT_FORMAT_MJPEG_SIZE,
+-      .bDescriptorType        = USB_DT_CS_INTERFACE,
+-      .bDescriptorSubType     = UVC_VS_FORMAT_MJPEG,
+-      .bFormatIndex           = 2,
+-      .bNumFrameDescriptors   = 2,
+-      .bmFlags                = 0,
+-      .bDefaultFrameIndex     = 1,
+-      .bAspectRatioX          = 0,
+-      .bAspectRatioY          = 0,
+-      .bmInterlaceFlags       = 0,
+-      .bCopyProtect           = 0,
++static u32 uvcg_frame_yuv_720p_dw_frame_interval[] = {
++      [0] = UVCG_FRM_INTERV_0_720P,
++};
++
++static const struct uvcg_frame uvcg_frame_yuv_720p = {
++      .fmt_type               = UVCG_UNCOMPRESSED,
++      .frame = {
++              .b_length                       = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1),
++              .b_descriptor_type              = USB_DT_CS_INTERFACE,
++              .b_descriptor_subtype           = UVC_VS_FRAME_UNCOMPRESSED,
++              .b_frame_index                  = 2,
++              .bm_capabilities                = 0,
++              .w_width                        = UVCG_WIDTH_720P,
++              .w_height                       = UVCG_HEIGHT_720P,
++              .dw_min_bit_rate                = UVCG_MIN_BITRATE_720P,
++              .dw_max_bit_rate                = UVCG_MAX_BITRATE_720P,
++              .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_720P,
++              .dw_default_frame_interval      = UVCG_DEFAULT_FRM_INTERV_720P,
++              .b_frame_interval_type          = 1,
++      },
++      .dw_frame_interval      = uvcg_frame_yuv_720p_dw_frame_interval,
++};
++
++static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_720p = {
++      .frm = (struct uvcg_frame *)&uvcg_frame_yuv_720p,
++};
++
++static struct uvcg_mjpeg uvcg_format_mjpeg = {
++      .fmt = {
++              .type                   = UVCG_MJPEG,
++              /* add to .frames and fill .num_frames at runtime */
++              .color_matching         = (struct uvcg_color_matching *)&uvcg_color_matching,
++      },
++      .desc = {
++              .bLength                = UVC_DT_FORMAT_MJPEG_SIZE,
++              .bDescriptorType        = USB_DT_CS_INTERFACE,
++              .bDescriptorSubType     = UVC_VS_FORMAT_MJPEG,
++              .bFormatIndex           = 2,
++              .bNumFrameDescriptors   = 2,
++              .bmFlags                = 0,
++              .bDefaultFrameIndex     = 1,
++              .bAspectRatioX          = 0,
++              .bAspectRatioY          = 0,
++              .bmInterlaceFlags       = 0,
++              .bCopyProtect           = 0,
++      },
++};
++
++static struct uvcg_format_ptr uvcg_format_ptr_mjpeg = {
++      .fmt = &uvcg_format_mjpeg.fmt,
+ };
+ DECLARE_UVC_FRAME_MJPEG(1);
+@@ -235,16 +341,45 @@ static const struct UVC_FRAME_MJPEG(3) uvc_frame_mjpg_360p = {
+       .bDescriptorSubType     = UVC_VS_FRAME_MJPEG,
+       .bFrameIndex            = 1,
+       .bmCapabilities         = 0,
+-      .wWidth                 = cpu_to_le16(640),
+-      .wHeight                = cpu_to_le16(360),
+-      .dwMinBitRate           = cpu_to_le32(18432000),
+-      .dwMaxBitRate           = cpu_to_le32(55296000),
+-      .dwMaxVideoFrameBufferSize      = cpu_to_le32(460800),
+-      .dwDefaultFrameInterval = cpu_to_le32(666666),
++      .wWidth                 = cpu_to_le16(UVCG_WIDTH_360P),
++      .wHeight                = cpu_to_le16(UVCG_HEIGHT_360P),
++      .dwMinBitRate           = cpu_to_le32(UVCG_MIN_BITRATE_360P),
++      .dwMaxBitRate           = cpu_to_le32(UVCG_MAX_BITRATE_360P),
++      .dwMaxVideoFrameBufferSize      = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P),
++      .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P),
+       .bFrameIntervalType     = 3,
+-      .dwFrameInterval[0]     = cpu_to_le32(666666),
+-      .dwFrameInterval[1]     = cpu_to_le32(1000000),
+-      .dwFrameInterval[2]     = cpu_to_le32(5000000),
++      .dwFrameInterval[0]     = cpu_to_le32(UVCG_FRM_INTERV_0_360P),
++      .dwFrameInterval[1]     = cpu_to_le32(UVCG_FRM_INTERV_1_360P),
++      .dwFrameInterval[2]     = cpu_to_le32(UVCG_FRM_INTERV_2_360P),
++};
++
++static u32 uvcg_frame_mjpeg_360p_dw_frame_interval[] = {
++      [0] = UVCG_FRM_INTERV_0_360P,
++      [1] = UVCG_FRM_INTERV_1_360P,
++      [2] = UVCG_FRM_INTERV_2_360P,
++};
++
++static const struct uvcg_frame uvcg_frame_mjpeg_360p = {
++      .fmt_type               = UVCG_MJPEG,
++      .frame = {
++              .b_length                       = UVC_DT_FRAME_MJPEG_SIZE(3),
++              .b_descriptor_type              = USB_DT_CS_INTERFACE,
++              .b_descriptor_subtype           = UVC_VS_FRAME_MJPEG,
++              .b_frame_index                  = 1,
++              .bm_capabilities                = 0,
++              .w_width                        = UVCG_WIDTH_360P,
++              .w_height                       = UVCG_HEIGHT_360P,
++              .dw_min_bit_rate                = UVCG_MIN_BITRATE_360P,
++              .dw_max_bit_rate                = UVCG_MAX_BITRATE_360P,
++              .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_360P,
++              .dw_default_frame_interval      = UVCG_DEFAULT_FRM_INTERV_360P,
++              .b_frame_interval_type          = 3,
++      },
++      .dw_frame_interval      = uvcg_frame_mjpeg_360p_dw_frame_interval,
++};
++
++static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_360p = {
++      .frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_360p,
+ };
+ static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
+@@ -253,23 +388,44 @@ static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = {
+       .bDescriptorSubType     = UVC_VS_FRAME_MJPEG,
+       .bFrameIndex            = 2,
+       .bmCapabilities         = 0,
+-      .wWidth                 = cpu_to_le16(1280),
+-      .wHeight                = cpu_to_le16(720),
+-      .dwMinBitRate           = cpu_to_le32(29491200),
+-      .dwMaxBitRate           = cpu_to_le32(29491200),
+-      .dwMaxVideoFrameBufferSize      = cpu_to_le32(1843200),
+-      .dwDefaultFrameInterval = cpu_to_le32(5000000),
++      .wWidth                 = cpu_to_le16(UVCG_WIDTH_720P),
++      .wHeight                = cpu_to_le16(UVCG_HEIGHT_720P),
++      .dwMinBitRate           = cpu_to_le32(UVCG_MIN_BITRATE_720P),
++      .dwMaxBitRate           = cpu_to_le32(UVCG_MAX_BITRATE_720P),
++      .dwMaxVideoFrameBufferSize      = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P),
++      .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P),
+       .bFrameIntervalType     = 1,
+-      .dwFrameInterval[0]     = cpu_to_le32(5000000),
++      .dwFrameInterval[0]     = cpu_to_le32(UVCG_FRM_INTERV_0_720P),
+ };
+-static const struct uvc_color_matching_descriptor uvc_color_matching = {
+-      .bLength                = UVC_DT_COLOR_MATCHING_SIZE,
+-      .bDescriptorType        = USB_DT_CS_INTERFACE,
+-      .bDescriptorSubType     = UVC_VS_COLORFORMAT,
+-      .bColorPrimaries        = 1,
+-      .bTransferCharacteristics       = 1,
+-      .bMatrixCoefficients    = 4,
++static u32 uvcg_frame_mjpeg_720p_dw_frame_interval[] = {
++      [0] = UVCG_FRM_INTERV_0_720P,
++};
++
++static const struct uvcg_frame uvcg_frame_mjpeg_720p = {
++      .fmt_type               = UVCG_MJPEG,
++      .frame = {
++              .b_length                       = UVC_DT_FRAME_MJPEG_SIZE(1),
++              .b_descriptor_type              = USB_DT_CS_INTERFACE,
++              .b_descriptor_subtype           = UVC_VS_FRAME_MJPEG,
++              .b_frame_index                  = 2,
++              .bm_capabilities                = 0,
++              .w_width                        = UVCG_WIDTH_720P,
++              .w_height                       = UVCG_HEIGHT_720P,
++              .dw_min_bit_rate                = UVCG_MIN_BITRATE_720P,
++              .dw_max_bit_rate                = UVCG_MAX_BITRATE_720P,
++              .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_720P,
++              .dw_default_frame_interval      = UVCG_DEFAULT_FRM_INTERV_720P,
++              .b_frame_interval_type          = 1,
++      },
++      .dw_frame_interval      = uvcg_frame_mjpeg_720p_dw_frame_interval,
++};
++
++static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_720p = {
++      .frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_720p,
++};
++
++static struct uvcg_streaming_header uvcg_streaming_header = {
+ };
+ static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
+@@ -290,40 +446,40 @@ static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
+ static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = {
+       (const struct uvc_descriptor_header *) &uvc_input_header,
+-      (const struct uvc_descriptor_header *) &uvc_format_yuv,
++      (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
+-      (const struct uvc_descriptor_header *) &uvc_color_matching,
+-      (const struct uvc_descriptor_header *) &uvc_format_mjpg,
++      (const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
++      (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
+-      (const struct uvc_descriptor_header *) &uvc_color_matching,
++      (const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
+       NULL,
+ };
+ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
+       (const struct uvc_descriptor_header *) &uvc_input_header,
+-      (const struct uvc_descriptor_header *) &uvc_format_yuv,
++      (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
+-      (const struct uvc_descriptor_header *) &uvc_color_matching,
+-      (const struct uvc_descriptor_header *) &uvc_format_mjpg,
++      (const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
++      (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
+-      (const struct uvc_descriptor_header *) &uvc_color_matching,
++      (const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
+       NULL,
+ };
+ static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
+       (const struct uvc_descriptor_header *) &uvc_input_header,
+-      (const struct uvc_descriptor_header *) &uvc_format_yuv,
++      (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
+-      (const struct uvc_descriptor_header *) &uvc_color_matching,
+-      (const struct uvc_descriptor_header *) &uvc_format_mjpg,
++      (const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
++      (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
+       (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
+-      (const struct uvc_descriptor_header *) &uvc_color_matching,
++      (const struct uvc_descriptor_header *) &uvcg_color_matching.desc,
+       NULL,
+ };
+@@ -387,6 +543,23 @@ webcam_bind(struct usb_composite_dev *cdev)
+       uvc_opts->hs_streaming = uvc_hs_streaming_cls;
+       uvc_opts->ss_streaming = uvc_ss_streaming_cls;
++      INIT_LIST_HEAD(&uvcg_format_yuv.fmt.frames);
++      list_add_tail(&uvcg_frame_ptr_yuv_360p.entry, &uvcg_format_yuv.fmt.frames);
++      list_add_tail(&uvcg_frame_ptr_yuv_720p.entry, &uvcg_format_yuv.fmt.frames);
++      uvcg_format_yuv.fmt.num_frames = 2;
++
++      INIT_LIST_HEAD(&uvcg_format_mjpeg.fmt.frames);
++      list_add_tail(&uvcg_frame_ptr_mjpeg_360p.entry, &uvcg_format_mjpeg.fmt.frames);
++      list_add_tail(&uvcg_frame_ptr_mjpeg_720p.entry, &uvcg_format_mjpeg.fmt.frames);
++      uvcg_format_mjpeg.fmt.num_frames = 2;
++
++      INIT_LIST_HEAD(&uvcg_streaming_header.formats);
++      list_add_tail(&uvcg_format_ptr_yuv.entry, &uvcg_streaming_header.formats);
++      list_add_tail(&uvcg_format_ptr_mjpeg.entry, &uvcg_streaming_header.formats);
++      uvcg_streaming_header.num_fmt = 2;
++
++      uvc_opts->header = &uvcg_streaming_header;
++
+       /* Allocate string descriptor numbers ... note that string contents
+        * can be overridden by the composite_dev glue.
+        */
+-- 
+2.43.0
+
diff --git a/queue-6.6/usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch b/queue-6.6/usb-xhci-mtk-fix-a-short-packet-issue-of-gen1-isoc-i.patch
new file mode 100644 (file)
index 0000000..6c3460c
--- /dev/null
@@ -0,0 +1,129 @@
+From f0ad956b8d54d2a7a9023fb1f3e5987ce2595fde Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Jan 2024 14:16:39 +0800
+Subject: usb: xhci-mtk: fix a short packet issue of gen1 isoc-in transfer
+
+From: Chunfeng Yun <chunfeng.yun@mediatek.com>
+
+[ Upstream commit 017dbfc05c31284150819890b4cc86a699cbdb71 ]
+
+For Gen1 isoc-in transfer, host still send out unexpected ACK after device
+finish the burst with a short packet, this will cause an exception on the
+connected device, such as, a usb 4k camera.
+It can be fixed by setting rxfifo depth less than 4k bytes, prefer to use
+3k here, the side-effect is that may cause performance drop about 10%,
+including bulk transfer.
+
+Fixes: 926d60ae64a6 ("usb: xhci-mtk: modify the SOF/ITP interval for mt8195")
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com>
+Link: https://lore.kernel.org/r/20240104061640.7335-2-chunfeng.yun@mediatek.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-mtk.c | 40 +++++++++++++++++++++++++++++++++++--
+ drivers/usb/host/xhci-mtk.h |  2 ++
+ 2 files changed, 40 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c
+index bbdf1b0b7be1..3252e3d2d79c 100644
+--- a/drivers/usb/host/xhci-mtk.c
++++ b/drivers/usb/host/xhci-mtk.c
+@@ -7,6 +7,7 @@
+  *  Chunfeng Yun <chunfeng.yun@mediatek.com>
+  */
++#include <linux/bitfield.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/iopoll.h>
+ #include <linux/kernel.h>
+@@ -73,6 +74,9 @@
+ #define FRMCNT_LEV1_RANG      (0x12b << 8)
+ #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8)
++#define HSCH_CFG1             0x960
++#define SCH3_RXFIFO_DEPTH_MASK        GENMASK(21, 20)
++
+ #define SS_GEN2_EOF_CFG               0x990
+ #define SSG2EOF_OFFSET                0x3c
+@@ -114,6 +118,8 @@
+ #define SSC_IP_SLEEP_EN       BIT(4)
+ #define SSC_SPM_INT_EN                BIT(1)
++#define SCH_FIFO_TO_KB(x)     ((x) >> 10)
++
+ enum ssusb_uwk_vers {
+       SSUSB_UWK_V1 = 1,
+       SSUSB_UWK_V2,
+@@ -165,6 +171,35 @@ static void xhci_mtk_set_frame_interval(struct xhci_hcd_mtk *mtk)
+       writel(value, hcd->regs + SS_GEN2_EOF_CFG);
+ }
++/*
++ * workaround: usb3.2 gen1 isoc rx hw issue
++ * host send out unexpected ACK afer device fininsh a burst transfer with
++ * a short packet.
++ */
++static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk)
++{
++      struct usb_hcd *hcd = mtk->hcd;
++      u32 value;
++
++      if (!mtk->rxfifo_depth)
++              return;
++
++      value = readl(hcd->regs + HSCH_CFG1);
++      value &= ~SCH3_RXFIFO_DEPTH_MASK;
++      value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK,
++                          SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1);
++      writel(value, hcd->regs + HSCH_CFG1);
++}
++
++static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk)
++{
++      /* workaround only for mt8195 */
++      xhci_mtk_set_frame_interval(mtk);
++
++      /* workaround for SoCs using SSUSB about before IPM v1.6.0 */
++      xhci_mtk_rxfifo_depth_set(mtk);
++}
++
+ static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk)
+ {
+       struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs;
+@@ -448,8 +483,7 @@ static int xhci_mtk_setup(struct usb_hcd *hcd)
+               if (ret)
+                       return ret;
+-              /* workaround only for mt8195 */
+-              xhci_mtk_set_frame_interval(mtk);
++              xhci_mtk_init_quirk(mtk);
+       }
+       ret = xhci_gen_setup(hcd, xhci_mtk_quirks);
+@@ -527,6 +561,8 @@ static int xhci_mtk_probe(struct platform_device *pdev)
+       of_property_read_u32(node, "mediatek,u2p-dis-msk",
+                            &mtk->u2p_dis_msk);
++      of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth);
++
+       ret = usb_wakeup_of_property_parse(mtk, node);
+       if (ret) {
+               dev_err(dev, "failed to parse uwk property\n");
+diff --git a/drivers/usb/host/xhci-mtk.h b/drivers/usb/host/xhci-mtk.h
+index faaaf05e36ce..ac042077db8c 100644
+--- a/drivers/usb/host/xhci-mtk.h
++++ b/drivers/usb/host/xhci-mtk.h
+@@ -160,6 +160,8 @@ struct xhci_hcd_mtk {
+       struct regmap *uwk;
+       u32 uwk_reg_base;
+       u32 uwk_vers;
++      /* quirk */
++      u32 rxfifo_depth;
+ };
+ static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd)
+-- 
+2.43.0
+
diff --git a/queue-6.6/vdpa-fix-an-error-handling-path-in-eni_vdpa_probe.patch b/queue-6.6/vdpa-fix-an-error-handling-path-in-eni_vdpa_probe.patch
new file mode 100644 (file)
index 0000000..df16af6
--- /dev/null
@@ -0,0 +1,55 @@
+From 5686b4dd8816736456a4830f68d099bafae87257 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 20 Oct 2022 21:21:09 +0200
+Subject: vdpa: Fix an error handling path in eni_vdpa_probe()
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit c1b9f2c66eed3261db76cccd8a22a9affae8dcbf ]
+
+After a successful vp_legacy_probe() call, vp_legacy_remove() should be
+called in the error handling path, as already done in the remove function.
+
+Add the missing call.
+
+Fixes: e85087beedca ("eni_vdpa: add vDPA driver for Alibaba ENI")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Message-Id: <a7b0ef1eabd081f1c7c894e9b11de01678e85dee.1666293559.git.christophe.jaillet@wanadoo.fr>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vdpa/alibaba/eni_vdpa.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/vdpa/alibaba/eni_vdpa.c b/drivers/vdpa/alibaba/eni_vdpa.c
+index 5a09a09cca70..cce3d1837104 100644
+--- a/drivers/vdpa/alibaba/eni_vdpa.c
++++ b/drivers/vdpa/alibaba/eni_vdpa.c
+@@ -497,7 +497,7 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       if (!eni_vdpa->vring) {
+               ret = -ENOMEM;
+               ENI_ERR(pdev, "failed to allocate virtqueues\n");
+-              goto err;
++              goto err_remove_vp_legacy;
+       }
+       for (i = 0; i < eni_vdpa->queues; i++) {
+@@ -509,11 +509,13 @@ static int eni_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+       ret = vdpa_register_device(&eni_vdpa->vdpa, eni_vdpa->queues);
+       if (ret) {
+               ENI_ERR(pdev, "failed to register to vdpa bus\n");
+-              goto err;
++              goto err_remove_vp_legacy;
+       }
+       return 0;
++err_remove_vp_legacy:
++      vp_legacy_remove(&eni_vdpa->ldev);
+ err:
+       put_device(&eni_vdpa->vdpa.dev);
+       return ret;
+-- 
+2.43.0
+
diff --git a/queue-6.6/vfio-pds-fix-calculations-in-pds_vfio_dirty_sync.patch b/queue-6.6/vfio-pds-fix-calculations-in-pds_vfio_dirty_sync.patch
new file mode 100644 (file)
index 0000000..9decd16
--- /dev/null
@@ -0,0 +1,59 @@
+From d5cb3d582538833fbe6a4ea44439650ce57035d6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 16 Nov 2023 16:12:02 -0800
+Subject: vfio/pds: Fix calculations in pds_vfio_dirty_sync
+
+From: Brett Creeley <brett.creeley@amd.com>
+
+[ Upstream commit 4004497cec3093d7b0087bc70709b45969fa07b6 ]
+
+The incorrect check is being done for comparing the
+iova/length being requested to sync. This can cause
+the dirty sync operation to fail. Fix this by making
+sure the iova offset added to the requested sync
+length doesn't exceed the region_size.
+
+Also, the region_start is assumed to always be at 0.
+This can cause dirty tracking to fail because the
+device/driver bitmap offset always starts at 0,
+however, the region_start/iova may not. Fix this by
+determining the iova offset from region_start to
+determine the bitmap offset.
+
+Fixes: f232836a9152 ("vfio/pds: Add support for dirty page tracking")
+Signed-off-by: Brett Creeley <brett.creeley@amd.com>
+Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
+Link: https://lore.kernel.org/r/20231117001207.2793-2-brett.creeley@amd.com
+Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/vfio/pci/pds/dirty.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/vfio/pci/pds/dirty.c b/drivers/vfio/pci/pds/dirty.c
+index c937aa6f3954..27607d7b9030 100644
+--- a/drivers/vfio/pci/pds/dirty.c
++++ b/drivers/vfio/pci/pds/dirty.c
+@@ -478,8 +478,7 @@ static int pds_vfio_dirty_sync(struct pds_vfio_pci_device *pds_vfio,
+               pds_vfio->vf_id, iova, length, pds_vfio->dirty.region_page_size,
+               pages, bitmap_size);
+-      if (!length || ((dirty->region_start + iova + length) >
+-                      (dirty->region_start + dirty->region_size))) {
++      if (!length || ((iova - dirty->region_start + length) > dirty->region_size)) {
+               dev_err(dev, "Invalid iova 0x%lx and/or length 0x%lx to sync\n",
+                       iova, length);
+               return -EINVAL;
+@@ -496,7 +495,8 @@ static int pds_vfio_dirty_sync(struct pds_vfio_pci_device *pds_vfio,
+               return -EINVAL;
+       }
+-      bmp_offset = DIV_ROUND_UP(iova / dirty->region_page_size, sizeof(u64));
++      bmp_offset = DIV_ROUND_UP((iova - dirty->region_start) /
++                                dirty->region_page_size, sizeof(u64));
+       dev_dbg(dev,
+               "Syncing dirty bitmap, iova 0x%lx length 0x%lx, bmp_offset %llu bmp_bytes %llu\n",
+-- 
+2.43.0
+