--- /dev/null
+From cc6fc55c7ae04ab19b3972f78d3a8b1be32bf533 Mon Sep 17 00:00:00 2001
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Date: Mon, 11 Dec 2023 22:54:11 +0530
+Subject: ARM: dts: qcom: sdx55: Fix the base address of PCIe PHY
+
+From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+
+commit cc6fc55c7ae04ab19b3972f78d3a8b1be32bf533 upstream.
+
+While convering the binding to new format, serdes address specified in the
+old binding was used as the base address. This causes a boot hang as the
+driver tries to access memory region outside of the specified address. Fix
+it!
+
+Cc: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Cc: stable@vger.kernel.org # 6.6
+Fixes: bb56cff4ac03 ("ARM: dts: qcom-sdx55: switch PCIe QMP PHY to new style of bindings")
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
+Link: https://lore.kernel.org/r/20231211172411.141289-1-manivannan.sadhasivam@linaro.org
+Signed-off-by: Bjorn Andersson <andersson@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm/boot/dts/qcom/qcom-sdx55.dtsi | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
++++ b/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi
+@@ -436,9 +436,9 @@
+ status = "disabled";
+ };
+
+- pcie_phy: phy@1c07000 {
++ pcie_phy: phy@1c06000 {
+ compatible = "qcom,sdx55-qmp-pcie-phy";
+- reg = <0x01c07000 0x2000>;
++ reg = <0x01c06000 0x2000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
--- /dev/null
+From d6488fee66472b468ed88d265b14aa3f04dc3bdf Mon Sep 17 00:00:00 2001
+From: Huang Ying <ying.huang@intel.com>
+Date: Fri, 8 Dec 2023 11:06:36 +0800
+Subject: cxl/port: Fix decoder initialization when nr_targets > interleave_ways
+
+From: Huang Ying <ying.huang@intel.com>
+
+commit d6488fee66472b468ed88d265b14aa3f04dc3bdf upstream.
+
+The decoder_populate_targets() helper walks all of the targets in a port
+and makes sure they can be looked up in @target_map. Where @target_map
+is a lookup table from target position to target id (corresponding to a
+cxl_dport instance). However @target_map is only responsible for
+conveying the active dport instances as indicated by interleave_ways.
+
+When nr_targets > interleave_ways it results in
+decoder_populate_targets() walking off the end of the valid entries in
+@target_map. Given target_map is initialized to 0 it results in the
+dport lookup failing if position 0 is not mapped to a dport with an id
+of 0:
+
+ cxl_port port3: Failed to populate active decoder targets
+ cxl_port port3: Failed to add decoder
+ cxl_port port3: Failed to add decoder3.0
+ cxl_bus_probe: cxl_port port3: probe: -6
+
+This bug also highlights that when the decoder's ->targets[] array is
+written in cxl_port_setup_targets() it is missing a hold of the
+targets_lock to synchronize against sysfs readers of the target list. A
+fix for that is saved for a later patch.
+
+Fixes: a5c258021689 ("cxl/bus: Populate the target list at decoder create")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Huang, Ying <ying.huang@intel.com>
+[djbw: rewrite the changelog, find the Fixes: tag]
+Co-developed-by: Dan Williams <dan.j.williams@intel.com>
+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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/port.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/cxl/core/port.c
++++ b/drivers/cxl/core/port.c
+@@ -1644,7 +1644,7 @@ static int decoder_populate_targets(stru
+ return -EINVAL;
+
+ write_seqlock(&cxlsd->target_lock);
+- for (i = 0; i < cxlsd->nr_targets; i++) {
++ for (i = 0; i < cxlsd->cxld.interleave_ways; i++) {
+ struct cxl_dport *dport = find_dport(port, target_map[i]);
+
+ if (!dport) {
--- /dev/null
+From fb1c93c2e9604a884467a773790016199f78ca08 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 10 Jan 2024 15:19:29 +0100
+Subject: drm/amdgpu: revert "Adjust removal control flow for smu v13_0_2"
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+commit fb1c93c2e9604a884467a773790016199f78ca08 upstream.
+
+Calling amdgpu_device_ip_resume_phase1() during shutdown leaves the
+HW in an active state and is an unbalanced use of the IP callbacks.
+
+Using the IP callbacks like this can lead to memory leaks, double
+free and imbalanced reference counters.
+
+Leaving the HW in an active state can lead to DMA accesses to memory now
+freed by the driver.
+
+Both is a complete no-go for driver unload so completely revert the
+workaround for now.
+
+This reverts commit f5c7e7797060255dbc8160734ccc5ad6183c5e04.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 32 -----------------------------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 32 -----------------------------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h | 1
+ drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h | 1
+ 4 files changed, 1 insertion(+), 65 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -5172,7 +5172,6 @@ int amdgpu_do_asic_reset(struct list_hea
+ struct amdgpu_device *tmp_adev = NULL;
+ bool need_full_reset, skip_hw_reset, vram_lost = false;
+ int r = 0;
+- bool gpu_reset_for_dev_remove = 0;
+
+ /* Try reset handler method first */
+ tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
+@@ -5192,10 +5191,6 @@ int amdgpu_do_asic_reset(struct list_hea
+ test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
+ skip_hw_reset = test_bit(AMDGPU_SKIP_HW_RESET, &reset_context->flags);
+
+- gpu_reset_for_dev_remove =
+- test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
+- test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
+-
+ /*
+ * ASIC reset has to be done on all XGMI hive nodes ASAP
+ * to allow proper links negotiation in FW (within 1 sec)
+@@ -5238,18 +5233,6 @@ int amdgpu_do_asic_reset(struct list_hea
+ amdgpu_ras_intr_cleared();
+ }
+
+- /* Since the mode1 reset affects base ip blocks, the
+- * phase1 ip blocks need to be resumed. Otherwise there
+- * will be a BIOS signature error and the psp bootloader
+- * can't load kdb on the next amdgpu install.
+- */
+- if (gpu_reset_for_dev_remove) {
+- list_for_each_entry(tmp_adev, device_list_handle, reset_list)
+- amdgpu_device_ip_resume_phase1(tmp_adev);
+-
+- goto end;
+- }
+-
+ list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
+ if (need_full_reset) {
+ /* post card */
+@@ -5486,11 +5469,6 @@ int amdgpu_device_gpu_recover(struct amd
+ int i, r = 0;
+ bool need_emergency_restart = false;
+ bool audio_suspended = false;
+- bool gpu_reset_for_dev_remove = false;
+-
+- gpu_reset_for_dev_remove =
+- test_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context->flags) &&
+- test_bit(AMDGPU_NEED_FULL_RESET, &reset_context->flags);
+
+ /*
+ * Special case: RAS triggered and full reset isn't supported
+@@ -5528,7 +5506,7 @@ int amdgpu_device_gpu_recover(struct amd
+ if (!amdgpu_sriov_vf(adev) && (adev->gmc.xgmi.num_physical_nodes > 1)) {
+ list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) {
+ list_add_tail(&tmp_adev->reset_list, &device_list);
+- if (gpu_reset_for_dev_remove && adev->shutdown)
++ if (adev->shutdown)
+ tmp_adev->shutdown = true;
+ }
+ if (!list_is_first(&adev->reset_list, &device_list))
+@@ -5613,10 +5591,6 @@ int amdgpu_device_gpu_recover(struct amd
+
+ retry: /* Rest of adevs pre asic reset from XGMI hive. */
+ list_for_each_entry(tmp_adev, device_list_handle, reset_list) {
+- if (gpu_reset_for_dev_remove) {
+- /* Workaroud for ASICs need to disable SMC first */
+- amdgpu_device_smu_fini_early(tmp_adev);
+- }
+ r = amdgpu_device_pre_asic_reset(tmp_adev, reset_context);
+ /*TODO Should we stop ?*/
+ if (r) {
+@@ -5648,9 +5622,6 @@ retry: /* Rest of adevs pre asic reset f
+ r = amdgpu_do_asic_reset(device_list_handle, reset_context);
+ if (r && r == -EAGAIN)
+ goto retry;
+-
+- if (!r && gpu_reset_for_dev_remove)
+- goto recover_end;
+ }
+
+ skip_hw_reset:
+@@ -5706,7 +5677,6 @@ skip_sched_resume:
+ amdgpu_ras_set_error_query_ready(tmp_adev, true);
+ }
+
+-recover_end:
+ tmp_adev = list_first_entry(device_list_handle, struct amdgpu_device,
+ reset_list);
+ amdgpu_device_unlock_reset_domain(tmp_adev->reset_domain);
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -2315,38 +2315,6 @@ amdgpu_pci_remove(struct pci_dev *pdev)
+ pm_runtime_forbid(dev->dev);
+ }
+
+- if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 2) &&
+- !amdgpu_sriov_vf(adev)) {
+- bool need_to_reset_gpu = false;
+-
+- if (adev->gmc.xgmi.num_physical_nodes > 1) {
+- struct amdgpu_hive_info *hive;
+-
+- hive = amdgpu_get_xgmi_hive(adev);
+- if (hive->device_remove_count == 0)
+- need_to_reset_gpu = true;
+- hive->device_remove_count++;
+- amdgpu_put_xgmi_hive(hive);
+- } else {
+- need_to_reset_gpu = true;
+- }
+-
+- /* Workaround for ASICs need to reset SMU.
+- * Called only when the first device is removed.
+- */
+- if (need_to_reset_gpu) {
+- struct amdgpu_reset_context reset_context;
+-
+- adev->shutdown = true;
+- memset(&reset_context, 0, sizeof(reset_context));
+- reset_context.method = AMD_RESET_METHOD_NONE;
+- reset_context.reset_req_dev = adev;
+- set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags);
+- set_bit(AMDGPU_RESET_FOR_DEVICE_REMOVE, &reset_context.flags);
+- amdgpu_device_gpu_recover(adev, NULL, &reset_context);
+- }
+- }
+-
+ amdgpu_driver_unload_kms(dev);
+
+ /*
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.h
+@@ -32,7 +32,6 @@ enum AMDGPU_RESET_FLAGS {
+
+ AMDGPU_NEED_FULL_RESET = 0,
+ AMDGPU_SKIP_HW_RESET = 1,
+- AMDGPU_RESET_FOR_DEVICE_REMOVE = 2,
+ };
+
+ struct amdgpu_reset_context {
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.h
+@@ -43,7 +43,6 @@ struct amdgpu_hive_info {
+ } pstate;
+
+ struct amdgpu_reset_domain *reset_domain;
+- uint32_t device_remove_count;
+ atomic_t ras_recovery;
+ };
+
--- /dev/null
+From 8e2f79f41a5d1b1a4a53ec524eb7609ca89f3c65 Mon Sep 17 00:00:00 2001
+From: Yauhen Kharuzhy <jekhor@gmail.com>
+Date: Wed, 20 Dec 2023 01:15:03 +0200
+Subject: HID: sensor-hub: Enable hid core report processing for all devices
+
+From: Yauhen Kharuzhy <jekhor@gmail.com>
+
+commit 8e2f79f41a5d1b1a4a53ec524eb7609ca89f3c65 upstream.
+
+After the commit 666cf30a589a ("HID: sensor-hub: Allow multi-function
+sensor devices") hub devices are claimed by hidraw driver in hid_connect().
+This causes stoppping of processing HID reports by hid core due to
+optimization.
+
+In such case, the hid-sensor-custom driver cannot match a known custom
+sensor in hid_sensor_custom_get_known() because it try to check custom
+properties which weren't filled from the report because hid core didn't
+parsed it.
+
+As result, custom sensors like hinge angle sensor and LISS sensors
+don't work.
+
+Mark the sensor hub devices claimed by some driver to avoid hidraw-related
+optimizations.
+
+Fixes: 666cf30a589a ("HID: sensor-hub: Allow multi-function sensor devices")
+Cc: stable@vger.kernel.org
+Signed-off-by: Yauhen Kharuzhy <jekhor@gmail.com>
+Tested-by: Daniel Thompson <daniel.thompson@linaro.org>
+Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+Link: https://lore.kernel.org/r/20231219231503.1506801-1-jekhor@gmail.com
+Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/hid-sensor-hub.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hid/hid-sensor-hub.c
++++ b/drivers/hid/hid-sensor-hub.c
+@@ -632,7 +632,7 @@ static int sensor_hub_probe(struct hid_d
+ }
+ INIT_LIST_HEAD(&hdev->inputs);
+
+- ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
++ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_DRIVER);
+ if (ret) {
+ hid_err(hdev, "hw start failed\n");
+ return ret;
--- /dev/null
+From 502296030ec6b0329e00f9fb15018e170cc63037 Mon Sep 17 00:00:00 2001
+From: Jason Gerecke <jason.gerecke@wacom.com>
+Date: Tue, 19 Dec 2023 13:33:43 -0800
+Subject: HID: wacom: Correct behavior when processing some confidence == false touches
+
+From: Jason Gerecke <jason.gerecke@wacom.com>
+
+commit 502296030ec6b0329e00f9fb15018e170cc63037 upstream.
+
+There appear to be a few different ways that Wacom devices can deal with
+confidence:
+
+ 1. If the device looses confidence in a touch, it will first clear
+ the tipswitch flag in one report, and then clear the confidence
+ flag in a second report. This behavior is used by e.g. DTH-2452.
+
+ 2. If the device looses confidence in a touch, it will clear both
+ the tipswitch and confidence flags within the same report. This
+ behavior is used by some AES devices.
+
+ 3. If the device looses confidence in a touch, it will clear *only*
+ the confidence bit. The tipswitch bit will remain set so long as
+ the touch is tracked. This behavior may be used in future devices.
+
+The driver does not currently handle situation 3 properly. Touches that
+loose confidence will remain "in prox" and essentially frozen in place
+until the tipswitch bit is finally cleared. Not only does this result
+in userspace seeing a stuck touch, but it also prevents pen arbitration
+from working properly (the pen won't send events until all touches are
+up, but we don't currently process events from non-confident touches).
+
+This commit centralizes the checking of the confidence bit in the
+wacom_wac_finger_slot() function and has 'prox' depend on it. In the
+case where situation 3 is encountered, the treat the touch as though
+it was removed, allowing both userspace and the pen arbitration to
+act normally.
+
+Signed-off-by: Tatsunosuke Tobita <tatsunosuke.tobita@wacom.com>
+Signed-off-by: Ping Cheng <ping.cheng@wacom.com>
+Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
+Fixes: 7fb0413baa7f ("HID: wacom: Use "Confidence" flag to prevent reporting invalid contacts")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jiri Kosina <jkosina@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/hid/wacom_wac.c | 32 ++++----------------------------
+ 1 file changed, 4 insertions(+), 28 deletions(-)
+
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -2649,8 +2649,8 @@ static void wacom_wac_finger_slot(struct
+ {
+ struct hid_data *hid_data = &wacom_wac->hid_data;
+ bool mt = wacom_wac->features.touch_max > 1;
+- bool prox = hid_data->tipswitch &&
+- report_touch_events(wacom_wac);
++ bool touch_down = hid_data->tipswitch && hid_data->confidence;
++ bool prox = touch_down && report_touch_events(wacom_wac);
+
+ if (touch_is_muted(wacom_wac)) {
+ if (!wacom_wac->shared->touch_down)
+@@ -2700,24 +2700,6 @@ static void wacom_wac_finger_slot(struct
+ }
+ }
+
+-static bool wacom_wac_slot_is_active(struct input_dev *dev, int key)
+-{
+- struct input_mt *mt = dev->mt;
+- struct input_mt_slot *s;
+-
+- if (!mt)
+- return false;
+-
+- for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
+- if (s->key == key &&
+- input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) {
+- return true;
+- }
+- }
+-
+- return false;
+-}
+-
+ static void wacom_wac_finger_event(struct hid_device *hdev,
+ struct hid_field *field, struct hid_usage *usage, __s32 value)
+ {
+@@ -2768,14 +2750,8 @@ static void wacom_wac_finger_event(struc
+ }
+
+ if (usage->usage_index + 1 == field->report_count) {
+- if (equivalent_usage == wacom_wac->hid_data.last_slot_field) {
+- bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input,
+- wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch;
+-
+- if (wacom_wac->hid_data.confidence || touch_removed) {
+- wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
+- }
+- }
++ if (equivalent_usage == wacom_wac->hid_data.last_slot_field)
++ wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
+ }
+ }
+
--- /dev/null
+From 020e71c7ffc25dfe29ed9be6c2d39af7bd7f661f Mon Sep 17 00:00:00 2001
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Date: Tue, 19 Dec 2023 17:26:01 -0300
+Subject: iio: adc: ad7091r: Allow users to configure device events
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+commit 020e71c7ffc25dfe29ed9be6c2d39af7bd7f661f upstream.
+
+AD7091R-5 devices are supported by the ad7091r-5 driver together with
+the ad7091r-base driver. Those drivers declared iio events for notifying
+user space when ADC readings fall bellow the thresholds of low limit
+registers or above the values set in high limit registers.
+However, to configure iio events and their thresholds, a set of callback
+functions must be implemented and those were not present until now.
+The consequence of trying to configure ad7091r-5 events without the
+proper callback functions was a null pointer dereference in the kernel
+because the pointers to the callback functions were not set.
+
+Implement event configuration callbacks allowing users to read/write
+event thresholds and enable/disable event generation.
+
+Since the event spec structs are generic to AD7091R devices, also move
+those from the ad7091r-5 driver the base driver so they can be reused
+when support for ad7091r-2/-4/-8 be added.
+
+Fixes: ca69300173b6 ("iio: adc: Add support for AD7091R5 ADC")
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/59552d3548dabd56adc3107b7b4869afee2b0c3c.1703013352.git.marcelo.schmitt1@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 156 +++++++++++++++++++++++++++++++++++++++++
+ drivers/iio/adc/ad7091r-base.h | 6 +
+ drivers/iio/adc/ad7091r5.c | 28 +------
+ 3 files changed, 166 insertions(+), 24 deletions(-)
+
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -6,6 +6,7 @@
+ */
+
+ #include <linux/bitops.h>
++#include <linux/bitfield.h>
+ #include <linux/iio/events.h>
+ #include <linux/iio/iio.h>
+ #include <linux/interrupt.h>
+@@ -49,6 +50,27 @@ struct ad7091r_state {
+ struct mutex lock; /*lock to prevent concurent reads */
+ };
+
++const struct iio_event_spec ad7091r_events[] = {
++ {
++ .type = IIO_EV_TYPE_THRESH,
++ .dir = IIO_EV_DIR_RISING,
++ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
++ BIT(IIO_EV_INFO_ENABLE),
++ },
++ {
++ .type = IIO_EV_TYPE_THRESH,
++ .dir = IIO_EV_DIR_FALLING,
++ .mask_separate = BIT(IIO_EV_INFO_VALUE) |
++ BIT(IIO_EV_INFO_ENABLE),
++ },
++ {
++ .type = IIO_EV_TYPE_THRESH,
++ .dir = IIO_EV_DIR_EITHER,
++ .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
++ },
++};
++EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R);
++
+ static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode)
+ {
+ int ret, conf;
+@@ -168,8 +190,142 @@ unlock:
+ return ret;
+ }
+
++static int ad7091r_read_event_config(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++ int val, ret;
++
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ &val);
++ if (ret)
++ return ret;
++ return val != AD7091R_HIGH_LIMIT;
++ case IIO_EV_DIR_FALLING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ &val);
++ if (ret)
++ return ret;
++ return val != AD7091R_LOW_LIMIT;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ad7091r_write_event_config(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir, int state)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++
++ if (state) {
++ return regmap_set_bits(st->map, AD7091R_REG_CONF,
++ AD7091R_REG_CONF_ALERT_EN);
++ } else {
++ /*
++ * Set thresholds either to 0 or to 2^12 - 1 as appropriate to
++ * prevent alerts and thus disable event generation.
++ */
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ AD7091R_HIGH_LIMIT);
++ case IIO_EV_DIR_FALLING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ AD7091R_LOW_LIMIT);
++ default:
++ return -EINVAL;
++ }
++ }
++}
++
++static int ad7091r_read_event_value(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir,
++ enum iio_event_info info, int *val, int *val2)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++ int ret;
++
++ switch (info) {
++ case IIO_EV_INFO_VALUE:
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ val);
++ if (ret)
++ return ret;
++ return IIO_VAL_INT;
++ case IIO_EV_DIR_FALLING:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ val);
++ if (ret)
++ return ret;
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
++ }
++ case IIO_EV_INFO_HYSTERESIS:
++ ret = regmap_read(st->map,
++ AD7091R_REG_CH_HYSTERESIS(chan->channel),
++ val);
++ if (ret)
++ return ret;
++ return IIO_VAL_INT;
++ default:
++ return -EINVAL;
++ }
++}
++
++static int ad7091r_write_event_value(struct iio_dev *indio_dev,
++ const struct iio_chan_spec *chan,
++ enum iio_event_type type,
++ enum iio_event_direction dir,
++ enum iio_event_info info, int val, int val2)
++{
++ struct ad7091r_state *st = iio_priv(indio_dev);
++
++ switch (info) {
++ case IIO_EV_INFO_VALUE:
++ switch (dir) {
++ case IIO_EV_DIR_RISING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
++ val);
++ case IIO_EV_DIR_FALLING:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_LOW_LIMIT(chan->channel),
++ val);
++ default:
++ return -EINVAL;
++ }
++ case IIO_EV_INFO_HYSTERESIS:
++ return regmap_write(st->map,
++ AD7091R_REG_CH_HYSTERESIS(chan->channel),
++ val);
++ default:
++ return -EINVAL;
++ }
++}
++
+ static const struct iio_info ad7091r_info = {
+ .read_raw = ad7091r_read_raw,
++ .read_event_config = &ad7091r_read_event_config,
++ .write_event_config = &ad7091r_write_event_config,
++ .read_event_value = &ad7091r_read_event_value,
++ .write_event_value = &ad7091r_write_event_value,
+ };
+
+ static irqreturn_t ad7091r_event_handler(int irq, void *private)
+--- a/drivers/iio/adc/ad7091r-base.h
++++ b/drivers/iio/adc/ad7091r-base.h
+@@ -8,6 +8,10 @@
+ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+
++/* AD7091R_REG_CH_LIMIT */
++#define AD7091R_HIGH_LIMIT 0xFFF
++#define AD7091R_LOW_LIMIT 0x0
++
+ struct device;
+ struct ad7091r_state;
+
+@@ -17,6 +21,8 @@ struct ad7091r_chip_info {
+ unsigned int vref_mV;
+ };
+
++extern const struct iio_event_spec ad7091r_events[3];
++
+ extern const struct regmap_config ad7091r_regmap_config;
+
+ int ad7091r_probe(struct device *dev, const char *name,
+--- a/drivers/iio/adc/ad7091r5.c
++++ b/drivers/iio/adc/ad7091r5.c
+@@ -12,26 +12,6 @@
+
+ #include "ad7091r-base.h"
+
+-static const struct iio_event_spec ad7091r5_events[] = {
+- {
+- .type = IIO_EV_TYPE_THRESH,
+- .dir = IIO_EV_DIR_RISING,
+- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+- BIT(IIO_EV_INFO_ENABLE),
+- },
+- {
+- .type = IIO_EV_TYPE_THRESH,
+- .dir = IIO_EV_DIR_FALLING,
+- .mask_separate = BIT(IIO_EV_INFO_VALUE) |
+- BIT(IIO_EV_INFO_ENABLE),
+- },
+- {
+- .type = IIO_EV_TYPE_THRESH,
+- .dir = IIO_EV_DIR_EITHER,
+- .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
+- },
+-};
+-
+ #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \
+ .type = IIO_VOLTAGE, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+@@ -44,10 +24,10 @@ static const struct iio_event_spec ad709
+ .scan_type.realbits = bits, \
+ }
+ static const struct iio_chan_spec ad7091r5_channels_irq[] = {
+- AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+- AD7091R_CHANNEL(1, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+- AD7091R_CHANNEL(2, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
+- AD7091R_CHANNEL(3, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)),
++ AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++ AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++ AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
++ AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)),
+ };
+
+ static const struct iio_chan_spec ad7091r5_channels_noirq[] = {
--- /dev/null
+From e71c5c89bcb165a02df35325aa13d1ee40112401 Mon Sep 17 00:00:00 2001
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Date: Tue, 19 Dec 2023 17:26:27 -0300
+Subject: iio: adc: ad7091r: Enable internal vref if external vref is not supplied
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+commit e71c5c89bcb165a02df35325aa13d1ee40112401 upstream.
+
+The ADC needs a voltage reference to work correctly.
+Users can provide an external voltage reference or use the chip internal
+reference to operate the ADC.
+The availability of an in chip reference for the ADC saves the user from
+having to supply an external voltage reference, which makes the external
+reference an optional property as described in the device tree
+documentation.
+Though, to use the internal reference, it must be enabled by writing to
+the configuration register.
+Enable AD7091R internal voltage reference if no external vref is supplied.
+
+Fixes: 260442cc5be4 ("iio: adc: ad7091r5: Add scale and external VREF support")
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/b865033fa6a4fc4bf2b4a98ec51a6144e0f64f77.1703013352.git.marcelo.schmitt1@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 7 +++++++
+ drivers/iio/adc/ad7091r-base.h | 2 ++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -399,7 +399,14 @@ int ad7091r_probe(struct device *dev, co
+ if (IS_ERR(st->vref)) {
+ if (PTR_ERR(st->vref) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
++
+ st->vref = NULL;
++ /* Enable internal vref */
++ ret = regmap_set_bits(st->map, AD7091R_REG_CONF,
++ AD7091R_REG_CONF_INT_VREF);
++ if (ret)
++ return dev_err_probe(st->dev, ret,
++ "Error on enable internal reference\n");
+ } else {
+ ret = regulator_enable(st->vref);
+ if (ret)
+--- a/drivers/iio/adc/ad7091r-base.h
++++ b/drivers/iio/adc/ad7091r-base.h
+@@ -8,6 +8,8 @@
+ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__
+
++#define AD7091R_REG_CONF_INT_VREF BIT(0)
++
+ /* AD7091R_REG_CH_LIMIT */
+ #define AD7091R_HIGH_LIMIT 0xFFF
+ #define AD7091R_LOW_LIMIT 0x0
--- /dev/null
+From a25a7df518fc71b1ba981d691e9322e645d2689c Mon Sep 17 00:00:00 2001
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Date: Sat, 16 Dec 2023 14:46:11 -0300
+Subject: iio: adc: ad7091r: Pass iio_dev to event handler
+
+From: Marcelo Schmitt <marcelo.schmitt@analog.com>
+
+commit a25a7df518fc71b1ba981d691e9322e645d2689c upstream.
+
+Previous version of ad7091r event handler received the ADC state pointer
+and retrieved the iio device from driver data field with dev_get_drvdata().
+However, no driver data have ever been set, which led to null pointer
+dereference when running the event handler.
+
+Pass the iio device to the event handler and retrieve the ADC state struct
+from it so we avoid the null pointer dereference and save the driver from
+filling the driver data field.
+
+Fixes: ca69300173b6 ("iio: adc: Add support for AD7091R5 ADC")
+Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
+Link: https://lore.kernel.org/r/5024b764107463de9578d5b3b0a3d5678e307b1a.1702746240.git.marcelo.schmitt1@gmail.com
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/ad7091r-base.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/adc/ad7091r-base.c
++++ b/drivers/iio/adc/ad7091r-base.c
+@@ -174,8 +174,8 @@ static const struct iio_info ad7091r_inf
+
+ static irqreturn_t ad7091r_event_handler(int irq, void *private)
+ {
+- struct ad7091r_state *st = (struct ad7091r_state *) private;
+- struct iio_dev *iio_dev = dev_get_drvdata(st->dev);
++ struct iio_dev *iio_dev = private;
++ struct ad7091r_state *st = iio_priv(iio_dev);
+ unsigned int i, read_val;
+ int ret;
+ s64 timestamp = iio_get_time_ns(iio_dev);
+@@ -234,7 +234,7 @@ int ad7091r_probe(struct device *dev, co
+ if (irq) {
+ ret = devm_request_threaded_irq(dev, irq, NULL,
+ ad7091r_event_handler,
+- IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, st);
++ IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev);
+ if (ret)
+ return ret;
+ }
--- /dev/null
+From ad362fe07fecf0aba839ff2cc59a3617bd42c33f Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oliver.upton@linux.dev>
+Date: Thu, 4 Jan 2024 18:32:32 +0000
+Subject: KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache
+
+From: Oliver Upton <oliver.upton@linux.dev>
+
+commit ad362fe07fecf0aba839ff2cc59a3617bd42c33f upstream.
+
+There is a potential UAF scenario in the case of an LPI translation
+cache hit racing with an operation that invalidates the cache, such
+as a DISCARD ITS command. The root of the problem is that
+vgic_its_check_cache() does not elevate the refcount on the vgic_irq
+before dropping the lock that serializes refcount changes.
+
+Have vgic_its_check_cache() raise the refcount on the returned vgic_irq
+and add the corresponding decrement after queueing the interrupt.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Link: https://lore.kernel.org/r/20240104183233.3560639-1-oliver.upton@linux.dev
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic-its.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/arch/arm64/kvm/vgic/vgic-its.c
++++ b/arch/arm64/kvm/vgic/vgic-its.c
+@@ -590,7 +590,11 @@ static struct vgic_irq *vgic_its_check_c
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&dist->lpi_list_lock, flags);
++
+ irq = __vgic_its_check_cache(dist, db, devid, eventid);
++ if (irq)
++ vgic_get_irq_kref(irq);
++
+ raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags);
+
+ return irq;
+@@ -769,6 +773,7 @@ int vgic_its_inject_cached_translation(s
+ raw_spin_lock_irqsave(&irq->irq_lock, flags);
+ irq->pending_latch = true;
+ vgic_queue_irq_unlock(kvm, irq, flags);
++ vgic_put_irq(kvm, irq);
+
+ return 0;
+ }
--- /dev/null
+From 7b95382f965133ef61ce44aaabc518c16eb46909 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Sun, 17 Dec 2023 11:15:09 +0000
+Subject: KVM: arm64: vgic-v4: Restore pending state on host userspace write
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit 7b95382f965133ef61ce44aaabc518c16eb46909 upstream.
+
+When the VMM writes to ISPENDR0 to set the state pending state of
+an SGI, we fail to convey this to the HW if this SGI is already
+backed by a GICv4.1 vSGI.
+
+This is a bit of a corner case, as this would only occur if the
+vgic state is changed on an already running VM, but this can
+apparently happen across a guest reset driven by the VMM.
+
+Fix this by always writing out the pending_latch value to the
+HW, and reseting it to false.
+
+Reported-by: Kunkun Jiang <jiangkunkun@huawei.com>
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
+Cc: stable@vger.kernel.org # 5.10+
+Link: https://lore.kernel.org/r/7e7f2c0c-448b-10a9-8929-4b8f4f6e2a32@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/vgic/vgic-mmio-v3.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+--- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c
++++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c
+@@ -365,19 +365,26 @@ static int vgic_v3_uaccess_write_pending
+ struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
+
+ raw_spin_lock_irqsave(&irq->irq_lock, flags);
+- if (test_bit(i, &val)) {
+- /*
+- * pending_latch is set irrespective of irq type
+- * (level or edge) to avoid dependency that VM should
+- * restore irq config before pending info.
+- */
+- irq->pending_latch = true;
+- vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
+- } else {
++
++ /*
++ * pending_latch is set irrespective of irq type
++ * (level or edge) to avoid dependency that VM should
++ * restore irq config before pending info.
++ */
++ irq->pending_latch = test_bit(i, &val);
++
++ if (irq->hw && vgic_irq_is_sgi(irq->intid)) {
++ irq_set_irqchip_state(irq->host_irq,
++ IRQCHIP_STATE_PENDING,
++ irq->pending_latch);
+ irq->pending_latch = false;
+- raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
+ }
+
++ if (irq->pending_latch)
++ vgic_queue_irq_unlock(vcpu->kvm, irq, flags);
++ else
++ raw_spin_unlock_irqrestore(&irq->irq_lock, flags);
++
+ vgic_put_irq(vcpu->kvm, irq);
+ }
+
--- /dev/null
+From cbb359d81a2695bb5e63ec9de06fcbef28518891 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 3 Nov 2023 16:05:36 -0700
+Subject: KVM: x86/pmu: Move PMU reset logic to common x86 code
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit cbb359d81a2695bb5e63ec9de06fcbef28518891 upstream.
+
+Move the common (or at least "ignored") aspects of resetting the vPMU to
+common x86 code, along with the stop/release helpers that are no used only
+by the common pmu.c.
+
+There is no need to manually handle fixed counters as all_valid_pmc_idx
+tracks both fixed and general purpose counters, and resetting the vPMU is
+far from a hot path, i.e. the extra bit of overhead to the PMC from the
+index is a non-issue.
+
+Zero fixed_ctr_ctrl in common code even though it's Intel specific.
+Ensuring it's zero doesn't harm AMD/SVM in any way, and stopping the fixed
+counters via all_valid_pmc_idx, but not clearing the associated control
+bits, would be odd/confusing.
+
+Make the .reset() hook optional as SVM no longer needs vendor specific
+handling.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Link: https://lore.kernel.org/r/20231103230541.352265-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/include/asm/kvm-x86-pmu-ops.h | 2 -
+ arch/x86/kvm/pmu.c | 40 ++++++++++++++++++++++++++++++++-
+ arch/x86/kvm/pmu.h | 18 --------------
+ arch/x86/kvm/svm/pmu.c | 16 -------------
+ arch/x86/kvm/vmx/pmu_intel.c | 20 ----------------
+ 5 files changed, 40 insertions(+), 56 deletions(-)
+
+--- a/arch/x86/include/asm/kvm-x86-pmu-ops.h
++++ b/arch/x86/include/asm/kvm-x86-pmu-ops.h
+@@ -22,7 +22,7 @@ KVM_X86_PMU_OP(get_msr)
+ KVM_X86_PMU_OP(set_msr)
+ KVM_X86_PMU_OP(refresh)
+ KVM_X86_PMU_OP(init)
+-KVM_X86_PMU_OP(reset)
++KVM_X86_PMU_OP_OPTIONAL(reset)
+ KVM_X86_PMU_OP_OPTIONAL(deliver_pmi)
+ KVM_X86_PMU_OP_OPTIONAL(cleanup)
+
+--- a/arch/x86/kvm/pmu.c
++++ b/arch/x86/kvm/pmu.c
+@@ -250,6 +250,24 @@ static bool pmc_resume_counter(struct kv
+ return true;
+ }
+
++static void pmc_release_perf_event(struct kvm_pmc *pmc)
++{
++ if (pmc->perf_event) {
++ perf_event_release_kernel(pmc->perf_event);
++ pmc->perf_event = NULL;
++ pmc->current_config = 0;
++ pmc_to_pmu(pmc)->event_count--;
++ }
++}
++
++static void pmc_stop_counter(struct kvm_pmc *pmc)
++{
++ if (pmc->perf_event) {
++ pmc->counter = pmc_read_counter(pmc);
++ pmc_release_perf_event(pmc);
++ }
++}
++
+ static int filter_cmp(const void *pa, const void *pb, u64 mask)
+ {
+ u64 a = *(u64 *)pa & mask;
+@@ -654,7 +672,27 @@ void kvm_pmu_refresh(struct kvm_vcpu *vc
+
+ void kvm_pmu_reset(struct kvm_vcpu *vcpu)
+ {
+- static_call(kvm_x86_pmu_reset)(vcpu);
++ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
++ struct kvm_pmc *pmc;
++ int i;
++
++ bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX);
++
++ for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
++ pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i);
++ if (!pmc)
++ continue;
++
++ pmc_stop_counter(pmc);
++ pmc->counter = 0;
++
++ if (pmc_is_gp(pmc))
++ pmc->eventsel = 0;
++ }
++
++ pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0;
++
++ static_call_cond(kvm_x86_pmu_reset)(vcpu);
+ }
+
+ void kvm_pmu_init(struct kvm_vcpu *vcpu)
+--- a/arch/x86/kvm/pmu.h
++++ b/arch/x86/kvm/pmu.h
+@@ -80,24 +80,6 @@ static inline void pmc_write_counter(str
+ pmc->counter &= pmc_bitmask(pmc);
+ }
+
+-static inline void pmc_release_perf_event(struct kvm_pmc *pmc)
+-{
+- if (pmc->perf_event) {
+- perf_event_release_kernel(pmc->perf_event);
+- pmc->perf_event = NULL;
+- pmc->current_config = 0;
+- pmc_to_pmu(pmc)->event_count--;
+- }
+-}
+-
+-static inline void pmc_stop_counter(struct kvm_pmc *pmc)
+-{
+- if (pmc->perf_event) {
+- pmc->counter = pmc_read_counter(pmc);
+- pmc_release_perf_event(pmc);
+- }
+-}
+-
+ static inline bool pmc_is_gp(struct kvm_pmc *pmc)
+ {
+ return pmc->type == KVM_PMC_GP;
+--- a/arch/x86/kvm/svm/pmu.c
++++ b/arch/x86/kvm/svm/pmu.c
+@@ -233,21 +233,6 @@ static void amd_pmu_init(struct kvm_vcpu
+ }
+ }
+
+-static void amd_pmu_reset(struct kvm_vcpu *vcpu)
+-{
+- struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+- int i;
+-
+- for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC; i++) {
+- struct kvm_pmc *pmc = &pmu->gp_counters[i];
+-
+- pmc_stop_counter(pmc);
+- pmc->counter = pmc->prev_counter = pmc->eventsel = 0;
+- }
+-
+- pmu->global_ctrl = pmu->global_status = 0;
+-}
+-
+ struct kvm_pmu_ops amd_pmu_ops __initdata = {
+ .hw_event_available = amd_hw_event_available,
+ .pmc_idx_to_pmc = amd_pmc_idx_to_pmc,
+@@ -259,7 +244,6 @@ struct kvm_pmu_ops amd_pmu_ops __initdat
+ .set_msr = amd_pmu_set_msr,
+ .refresh = amd_pmu_refresh,
+ .init = amd_pmu_init,
+- .reset = amd_pmu_reset,
+ .EVENTSEL_EVENT = AMD64_EVENTSEL_EVENT,
+ .MAX_NR_GP_COUNTERS = KVM_AMD_PMC_MAX_GENERIC,
+ .MIN_NR_GP_COUNTERS = AMD64_NUM_COUNTERS,
+--- a/arch/x86/kvm/vmx/pmu_intel.c
++++ b/arch/x86/kvm/vmx/pmu_intel.c
+@@ -632,26 +632,6 @@ static void intel_pmu_init(struct kvm_vc
+
+ static void intel_pmu_reset(struct kvm_vcpu *vcpu)
+ {
+- struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+- struct kvm_pmc *pmc = NULL;
+- int i;
+-
+- for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) {
+- pmc = &pmu->gp_counters[i];
+-
+- pmc_stop_counter(pmc);
+- pmc->counter = pmc->prev_counter = pmc->eventsel = 0;
+- }
+-
+- for (i = 0; i < KVM_PMC_MAX_FIXED; i++) {
+- pmc = &pmu->fixed_counters[i];
+-
+- pmc_stop_counter(pmc);
+- pmc->counter = pmc->prev_counter = 0;
+- }
+-
+- pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0;
+-
+ intel_pmu_release_guest_lbr_event(vcpu);
+ }
+
--- /dev/null
+From 1647b52757d59131fe30cf73fa36fac834d4367f Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Fri, 3 Nov 2023 16:05:37 -0700
+Subject: KVM: x86/pmu: Reset the PMU, i.e. stop counters, before refreshing
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 1647b52757d59131fe30cf73fa36fac834d4367f upstream.
+
+Stop all counters and release all perf events before refreshing the vPMU,
+i.e. before reconfiguring the vPMU to respond to changes in the vCPU
+model.
+
+Clear need_cleanup in kvm_pmu_reset() as well so that KVM doesn't
+prematurely stop counters, e.g. if KVM enters the guest and enables
+counters before the vCPU is scheduled out.
+
+Cc: stable@vger.kernel.org
+Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Link: https://lore.kernel.org/r/20231103230541.352265-3-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/pmu.c | 35 ++++++++++++++++++++++-------------
+ 1 file changed, 22 insertions(+), 13 deletions(-)
+
+--- a/arch/x86/kvm/pmu.c
++++ b/arch/x86/kvm/pmu.c
+@@ -657,25 +657,14 @@ int kvm_pmu_set_msr(struct kvm_vcpu *vcp
+ return 0;
+ }
+
+-/* refresh PMU settings. This function generally is called when underlying
+- * settings are changed (such as changes of PMU CPUID by guest VMs), which
+- * should rarely happen.
+- */
+-void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
+-{
+- if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm))
+- return;
+-
+- bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+- static_call(kvm_x86_pmu_refresh)(vcpu);
+-}
+-
+ void kvm_pmu_reset(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
+ struct kvm_pmc *pmc;
+ int i;
+
++ pmu->need_cleanup = false;
++
+ bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX);
+
+ for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) {
+@@ -695,6 +684,26 @@ void kvm_pmu_reset(struct kvm_vcpu *vcpu
+ static_call_cond(kvm_x86_pmu_reset)(vcpu);
+ }
+
++
++/*
++ * Refresh the PMU configuration for the vCPU, e.g. if userspace changes CPUID
++ * and/or PERF_CAPABILITIES.
++ */
++void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
++{
++ if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm))
++ return;
++
++ /*
++ * Stop/release all existing counters/events before realizing the new
++ * vPMU model.
++ */
++ kvm_pmu_reset(vcpu);
++
++ bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX);
++ static_call(kvm_x86_pmu_refresh)(vcpu);
++}
++
+ void kvm_pmu_init(struct kvm_vcpu *vcpu)
+ {
+ struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
--- /dev/null
+From 61921bdaa132b580b6db6858e6d7dcdb870df5fe Mon Sep 17 00:00:00 2001
+From: Petr Tesarik <petr@tesarici.cz>
+Date: Fri, 5 Jan 2024 21:16:42 +0100
+Subject: net: stmmac: fix ethtool per-queue statistics
+
+From: Petr Tesarik <petr@tesarici.cz>
+
+commit 61921bdaa132b580b6db6858e6d7dcdb870df5fe upstream.
+
+Fix per-queue statistics for devices with more than one queue.
+
+The output data pointer is currently reset in each loop iteration,
+effectively summing all queue statistics in the first four u64 values.
+
+The summary values are not even labeled correctly. For example, if eth0 has
+2 queues, ethtool -S eth0 shows:
+
+ q0_tx_pkt_n: 374 (actually tx_pkt_n over all queues)
+ q0_tx_irq_n: 23 (actually tx_normal_irq_n over all queues)
+ q1_tx_pkt_n: 462 (actually rx_pkt_n over all queues)
+ q1_tx_irq_n: 446 (actually rx_normal_irq_n over all queues)
+ q0_rx_pkt_n: 0
+ q0_rx_irq_n: 0
+ q1_rx_pkt_n: 0
+ q1_rx_irq_n: 0
+
+Fixes: 133466c3bbe1 ("net: stmmac: use per-queue 64 bit statistics where necessary")
+Cc: stable@vger.kernel.org
+Signed-off-by: Petr Tesarik <petr@tesarici.cz>
+Reviewed-by: Jisheng Zhang <jszhang@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+@@ -543,15 +543,12 @@ static void stmmac_get_per_qstats(struct
+ u32 rx_cnt = priv->plat->rx_queues_to_use;
+ unsigned int start;
+ int q, stat;
+- u64 *pos;
+ char *p;
+
+- pos = data;
+ for (q = 0; q < tx_cnt; q++) {
+ struct stmmac_txq_stats *txq_stats = &priv->xstats.txq_stats[q];
+ struct stmmac_txq_stats snapshot;
+
+- data = pos;
+ do {
+ start = u64_stats_fetch_begin(&txq_stats->syncp);
+ snapshot = *txq_stats;
+@@ -559,17 +556,15 @@ static void stmmac_get_per_qstats(struct
+
+ p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
+ for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
+- *data++ += (*(u64 *)p);
++ *data++ = (*(u64 *)p);
+ p += sizeof(u64);
+ }
+ }
+
+- pos = data;
+ for (q = 0; q < rx_cnt; q++) {
+ struct stmmac_rxq_stats *rxq_stats = &priv->xstats.rxq_stats[q];
+ struct stmmac_rxq_stats snapshot;
+
+- data = pos;
+ do {
+ start = u64_stats_fetch_begin(&rxq_stats->syncp);
+ snapshot = *rxq_stats;
+@@ -577,7 +572,7 @@ static void stmmac_get_per_qstats(struct
+
+ p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
+ for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
+- *data++ += (*(u64 *)p);
++ *data++ = (*(u64 *)p);
+ p += sizeof(u64);
+ }
+ }
--- /dev/null
+From c2945c435c999c63e47f337bc7c13c98c21d0bcc Mon Sep 17 00:00:00 2001
+From: Romain Gantois <romain.gantois@bootlin.com>
+Date: Tue, 16 Jan 2024 13:19:17 +0100
+Subject: net: stmmac: Prevent DSA tags from breaking COE
+
+From: Romain Gantois <romain.gantois@bootlin.com>
+
+commit c2945c435c999c63e47f337bc7c13c98c21d0bcc upstream.
+
+Some DSA tagging protocols change the EtherType field in the MAC header
+e.g. DSA_TAG_PROTO_(DSA/EDSA/BRCM/MTK/RTL4C_A/SJA1105). On TX these tagged
+frames are ignored by the checksum offload engine and IP header checker of
+some stmmac cores.
+
+On RX, the stmmac driver wrongly assumes that checksums have been computed
+for these tagged packets, and sets CHECKSUM_UNNECESSARY.
+
+Add an additional check in the stmmac TX and RX hotpaths so that COE is
+deactivated for packets with ethertypes that will not trigger the COE and
+IP header checks.
+
+Fixes: 6b2c6e4a938f ("net: stmmac: propagate feature flags to vlan")
+Cc: <stable@vger.kernel.org>
+Reported-by: Richard Tresidder <rtresidd@electromag.com.au>
+Link: https://lore.kernel.org/netdev/e5c6c75f-2dfa-4e50-a1fb-6bf4cdb617c2@electromag.com.au/
+Reported-by: Romain Gantois <romain.gantois@bootlin.com>
+Link: https://lore.kernel.org/netdev/c57283ed-6b9b-b0e6-ee12-5655c1c54495@bootlin.com/
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Romain Gantois <romain.gantois@bootlin.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 32 +++++++++++++++++++---
+ 1 file changed, 29 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -4372,6 +4372,28 @@ dma_map_err:
+ }
+
+ /**
++ * stmmac_has_ip_ethertype() - Check if packet has IP ethertype
++ * @skb: socket buffer to check
++ *
++ * Check if a packet has an ethertype that will trigger the IP header checks
++ * and IP/TCP checksum engine of the stmmac core.
++ *
++ * Return: true if the ethertype can trigger the checksum engine, false
++ * otherwise
++ */
++static bool stmmac_has_ip_ethertype(struct sk_buff *skb)
++{
++ int depth = 0;
++ __be16 proto;
++
++ proto = __vlan_get_protocol(skb, eth_header_parse_protocol(skb),
++ &depth);
++
++ return (depth <= ETH_HLEN) &&
++ (proto == htons(ETH_P_IP) || proto == htons(ETH_P_IPV6));
++}
++
++/**
+ * stmmac_xmit - Tx entry point of the driver
+ * @skb : the socket buffer
+ * @dev : device pointer
+@@ -4435,9 +4457,13 @@ static netdev_tx_t stmmac_xmit(struct sk
+ /* DWMAC IPs can be synthesized to support tx coe only for a few tx
+ * queues. In that case, checksum offloading for those queues that don't
+ * support tx coe needs to fallback to software checksum calculation.
++ *
++ * Packets that won't trigger the COE e.g. most DSA-tagged packets will
++ * also have to be checksummed in software.
+ */
+ if (csum_insertion &&
+- priv->plat->tx_queues_cfg[queue].coe_unsupported) {
++ (priv->plat->tx_queues_cfg[queue].coe_unsupported ||
++ !stmmac_has_ip_ethertype(skb))) {
+ if (unlikely(skb_checksum_help(skb)))
+ goto dma_map_err;
+ csum_insertion = !csum_insertion;
+@@ -4997,7 +5023,7 @@ static void stmmac_dispatch_skb_zc(struc
+ stmmac_rx_vlan(priv->dev, skb);
+ skb->protocol = eth_type_trans(skb, priv->dev);
+
+- if (unlikely(!coe))
++ if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+@@ -5513,7 +5539,7 @@ drain_data:
+ stmmac_rx_vlan(priv->dev, skb);
+ skb->protocol = eth_type_trans(skb, priv->dev);
+
+- if (unlikely(!coe))
++ if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb))
+ skb_checksum_none_assert(skb);
+ else
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
--- /dev/null
+From 2217fffcd63f86776c985d42e76daa43a56abdf1 Mon Sep 17 00:00:00 2001
+From: Niklas Cassel <niklas.cassel@wdc.com>
+Date: Tue, 28 Nov 2023 14:22:30 +0100
+Subject: PCI: dwc: endpoint: Fix dw_pcie_ep_raise_msix_irq() alignment support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Niklas Cassel <niklas.cassel@wdc.com>
+
+commit 2217fffcd63f86776c985d42e76daa43a56abdf1 upstream.
+
+Commit 6f5e193bfb55 ("PCI: dwc: Fix dw_pcie_ep_raise_msix_irq() to get
+correct MSI-X table address") modified dw_pcie_ep_raise_msix_irq() to
+support iATUs which require a specific alignment.
+
+However, this support cannot have been properly tested.
+
+The whole point is for the iATU to map an address that is aligned,
+using dw_pcie_ep_map_addr(), and then let the writel() write to
+ep->msi_mem + aligned_offset.
+
+Thus, modify the address that is mapped such that it is aligned.
+With this change, dw_pcie_ep_raise_msix_irq() matches the logic in
+dw_pcie_ep_raise_msi_irq().
+
+Link: https://lore.kernel.org/linux-pci/20231128132231.2221614-1-nks@flawful.org
+Fixes: 6f5e193bfb55 ("PCI: dwc: Fix dw_pcie_ep_raise_msix_irq() to get correct MSI-X table address")
+Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Cc: stable@vger.kernel.org # 5.7
+Cc: Kishon Vijay Abraham I <kishon@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/dwc/pcie-designware-ep.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pci/controller/dwc/pcie-designware-ep.c
++++ b/drivers/pci/controller/dwc/pcie-designware-ep.c
+@@ -615,6 +615,7 @@ int dw_pcie_ep_raise_msix_irq(struct dw_
+ }
+
+ aligned_offset = msg_addr & (epc->mem->window.page_size - 1);
++ msg_addr &= ~aligned_offset;
+ ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr,
+ epc->mem->window.page_size);
+ if (ret)
--- /dev/null
+From 4e11c29873a8a296a20f99b3e03095e65ebf897d Mon Sep 17 00:00:00 2001
+From: qizhong cheng <qizhong.cheng@mediatek.com>
+Date: Mon, 11 Dec 2023 17:49:23 +0800
+Subject: PCI: mediatek: Clear interrupt status before dispatching handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: qizhong cheng <qizhong.cheng@mediatek.com>
+
+commit 4e11c29873a8a296a20f99b3e03095e65ebf897d upstream.
+
+We found a failure when using the iperf tool during WiFi performance
+testing, where some MSIs were received while clearing the interrupt
+status, and these MSIs cannot be serviced.
+
+The interrupt status can be cleared even if the MSI status remains pending.
+As such, given the edge-triggered interrupt type, its status should be
+cleared before being dispatched to the handler of the underling device.
+
+[kwilczynski: commit log, code comment wording]
+Link: https://lore.kernel.org/linux-pci/20231211094923.31967-1-jianjun.wang@mediatek.com
+Fixes: 43e6409db64d ("PCI: mediatek: Add MSI support for MT2712 and MT7622")
+Signed-off-by: qizhong cheng <qizhong.cheng@mediatek.com>
+Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com>
+Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
+[bhelgaas: rewrap comment]
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/pci/controller/pcie-mediatek.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/controller/pcie-mediatek.c
++++ b/drivers/pci/controller/pcie-mediatek.c
+@@ -617,12 +617,18 @@ static void mtk_pcie_intr_handler(struct
+ if (status & MSI_STATUS){
+ unsigned long imsi_status;
+
++ /*
++ * The interrupt status can be cleared even if the
++ * MSI status remains pending. As such, given the
++ * edge-triggered interrupt type, its status should
++ * be cleared before being dispatched to the
++ * handler of the underlying device.
++ */
++ writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
+ while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) {
+ for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM)
+ generic_handle_domain_irq(port->inner_domain, bit);
+ }
+- /* Clear MSI interrupt status */
+- writel(MSI_STATUS, port->base + PCIE_INT_STATUS);
+ }
+ }
+
--- /dev/null
+From 9a000a72af75886e5de13f4edef7f0d788622e7d Mon Sep 17 00:00:00 2001
+From: Tadeusz Struk <tstruk@gigaio.com>
+Date: Mon, 13 Nov 2023 19:03:25 +0100
+Subject: PCI/P2PDMA: Remove reference to pci_p2pdma_map_sg()
+
+From: Tadeusz Struk <tstruk@gigaio.com>
+
+commit 9a000a72af75886e5de13f4edef7f0d788622e7d upstream.
+
+Update Documentation/driver-api/pci/p2pdma.rst doc and remove references to
+obsolete p2pdma mapping functions.
+
+Fixes: 0d06132fc84b ("PCI/P2PDMA: Remove pci_p2pdma_[un]map_sg()")
+Link: https://lore.kernel.org/r/20231113180325.444692-1-tstruk@gmail.com
+Signed-off-by: Tadeusz Struk <tstruk@gigaio.com>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
+Cc: stable@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/driver-api/pci/p2pdma.rst | 16 +++-------------
+ 1 file changed, 3 insertions(+), 13 deletions(-)
+
+--- a/Documentation/driver-api/pci/p2pdma.rst
++++ b/Documentation/driver-api/pci/p2pdma.rst
+@@ -83,19 +83,9 @@ this to include other types of resources
+ Client Drivers
+ --------------
+
+-A client driver typically only has to conditionally change its DMA map
+-routine to use the mapping function :c:func:`pci_p2pdma_map_sg()` instead
+-of the usual :c:func:`dma_map_sg()` function. Memory mapped in this
+-way does not need to be unmapped.
+-
+-The client may also, optionally, make use of
+-:c:func:`is_pci_p2pdma_page()` to determine when to use the P2P mapping
+-functions and when to use the regular mapping functions. In some
+-situations, it may be more appropriate to use a flag to indicate a
+-given request is P2P memory and map appropriately. It is important to
+-ensure that struct pages that back P2P memory stay out of code that
+-does not have support for them as other code may treat the pages as
+-regular memory which may not be appropriate.
++A client driver only has to use the mapping API :c:func:`dma_map_sg()`
++and :c:func:`dma_unmap_sg()` functions as usual, and the implementation
++will do the right thing for the P2P capable memory.
+
+
+ Orchestrator Drivers
--- /dev/null
+From ec4ffd100ffb396eca13ebe7d18938ea80f399c3 Mon Sep 17 00:00:00 2001
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Mon, 8 Jan 2024 10:41:02 +0100
+Subject: Revert "net: rtnetlink: Enslave device before bringing it up"
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+commit ec4ffd100ffb396eca13ebe7d18938ea80f399c3 upstream.
+
+This reverts commit a4abfa627c3865c37e036bccb681619a50d3d93c.
+
+The patch broke:
+> ip link set dummy0 up
+> ip link set dummy0 master bond0 down
+
+This last command is useful to be able to enslave an interface with only
+one netlink message.
+
+After discussion, there is no good reason to support:
+> ip link set dummy0 down
+> ip link set dummy0 master bond0 up
+because the bond interface already set the slave up when it is up.
+
+Cc: stable@vger.kernel.org
+Fixes: a4abfa627c38 ("net: rtnetlink: Enslave device before bringing it up")
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>
+Link: https://lore.kernel.org/r/20240108094103.2001224-2-nicolas.dichtel@6wind.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/rtnetlink.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -2905,13 +2905,6 @@ static int do_setlink(const struct sk_bu
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+ }
+
+- if (tb[IFLA_MASTER]) {
+- err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
+- if (err)
+- goto errout;
+- status |= DO_SETLINK_MODIFIED;
+- }
+-
+ if (ifm->ifi_flags || ifm->ifi_change) {
+ err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm),
+ extack);
+@@ -2919,6 +2912,13 @@ static int do_setlink(const struct sk_bu
+ goto errout;
+ }
+
++ if (tb[IFLA_MASTER]) {
++ err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack);
++ if (err)
++ goto errout;
++ status |= DO_SETLINK_MODIFIED;
++ }
++
+ if (tb[IFLA_CARRIER]) {
+ err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER]));
+ if (err)
--- /dev/null
+From a484755ab2526ebdbe042397cdd6e427eb4b1a68 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Wed, 18 Oct 2023 12:41:03 -0700
+Subject: Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB"
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit a484755ab2526ebdbe042397cdd6e427eb4b1a68 upstream.
+
+Revert KVM's made-up consistency check on SVM's TLB control. The APM says
+that unsupported encodings are reserved, but the APM doesn't state that
+VMRUN checks for a supported encoding. Unless something is called out
+in "Canonicalization and Consistency Checks" or listed as MBZ (Must Be
+Zero), AMD behavior is typically to let software shoot itself in the foot.
+
+This reverts commit 174a921b6975ef959dd82ee9e8844067a62e3ec1.
+
+Fixes: 174a921b6975 ("nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB")
+Reported-by: Stefan Sterz <s.sterz@proxmox.com>
+Closes: https://lkml.kernel.org/r/b9915c9c-4cf6-051a-2d91-44cc6380f455%40proxmox.com
+Cc: stable@vger.kernel.org
+Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
+Link: https://lore.kernel.org/r/20231018194104.1896415-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/svm/nested.c | 15 ---------------
+ 1 file changed, 15 deletions(-)
+
+--- a/arch/x86/kvm/svm/nested.c
++++ b/arch/x86/kvm/svm/nested.c
+@@ -247,18 +247,6 @@ static bool nested_svm_check_bitmap_pa(s
+ kvm_vcpu_is_legal_gpa(vcpu, addr + size - 1);
+ }
+
+-static bool nested_svm_check_tlb_ctl(struct kvm_vcpu *vcpu, u8 tlb_ctl)
+-{
+- /* Nested FLUSHBYASID is not supported yet. */
+- switch(tlb_ctl) {
+- case TLB_CONTROL_DO_NOTHING:
+- case TLB_CONTROL_FLUSH_ALL_ASID:
+- return true;
+- default:
+- return false;
+- }
+-}
+-
+ static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu,
+ struct vmcb_ctrl_area_cached *control)
+ {
+@@ -278,9 +266,6 @@ static bool __nested_vmcb_check_controls
+ IOPM_SIZE)))
+ return false;
+
+- if (CC(!nested_svm_check_tlb_ctl(vcpu, control->tlb_ctl)))
+- return false;
+-
+ if (CC((control->int_ctl & V_NMI_ENABLE_MASK) &&
+ !vmcb12_is_intercept(control, INTERCEPT_NMI))) {
+ return false;
--- /dev/null
+From 6d710b769c1f5f0d55c9ad9bb49b7dce009ec103 Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Thu, 21 Dec 2023 18:18:09 -0500
+Subject: serial: sc16is7xx: add check for unsupported SPI modes during probe
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit 6d710b769c1f5f0d55c9ad9bb49b7dce009ec103 upstream.
+
+The original comment is confusing because it implies that variants other
+than the SC16IS762 supports other SPI modes beside SPI_MODE_0.
+
+Extract from datasheet:
+ The SC16IS762 differs from the SC16IS752 in that it supports SPI clock
+ speeds up to 15 Mbit/s instead of the 4 Mbit/s supported by the
+ SC16IS752... In all other aspects, the SC16IS762 is functionally and
+ electrically the same as the SC16IS752.
+
+The same is also true of the SC16IS760 variant versus the SC16IS740 and
+SC16IS750 variants.
+
+For all variants, only SPI mode 0 is supported.
+
+Change comment and abort probing if the specified SPI mode is not
+SPI_MODE_0.
+
+Fixes: 2c837a8a8f9f ("sc16is7xx: spi interface is added")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231221231823.2327894-3-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -1727,7 +1727,10 @@ static int sc16is7xx_spi_probe(struct sp
+
+ /* Setup SPI bus */
+ spi->bits_per_word = 8;
+- /* only supports mode 0 on SC16IS762 */
++ /* For all variants, only mode 0 is supported */
++ if ((spi->mode & SPI_MODE_X_MASK) != SPI_MODE_0)
++ return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n");
++
+ spi->mode = spi->mode ? : SPI_MODE_0;
+ spi->max_speed_hz = spi->max_speed_hz ? : 15000000;
+ ret = spi_setup(spi);
--- /dev/null
+From 3ef79cd1412236d884ab0c46b4d1921380807b48 Mon Sep 17 00:00:00 2001
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Date: Thu, 21 Dec 2023 18:18:10 -0500
+Subject: serial: sc16is7xx: set safe default SPI clock frequency
+
+From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+
+commit 3ef79cd1412236d884ab0c46b4d1921380807b48 upstream.
+
+15 MHz is supported only by 76x variants.
+
+If the SPI clock frequency is not specified, use a safe default clock value
+of 4 MHz that is supported by all variants.
+
+Also use HZ_PER_MHZ macro to improve readability.
+
+Fixes: 2c837a8a8f9f ("sc16is7xx: spi interface is added")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
+Link: https://lore.kernel.org/r/20231221231823.2327894-4-hugo@hugovil.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/sc16is7xx.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -24,6 +24,7 @@
+ #include <linux/tty_flip.h>
+ #include <linux/spi/spi.h>
+ #include <linux/uaccess.h>
++#include <linux/units.h>
+ #include <uapi/linux/sched/types.h>
+
+ #define SC16IS7XX_NAME "sc16is7xx"
+@@ -1732,7 +1733,7 @@ static int sc16is7xx_spi_probe(struct sp
+ return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n");
+
+ spi->mode = spi->mode ? : SPI_MODE_0;
+- spi->max_speed_hz = spi->max_speed_hz ? : 15000000;
++ spi->max_speed_hz = spi->max_speed_hz ? : 4 * HZ_PER_MHZ;
+ ret = spi_setup(spi);
+ if (ret)
+ return ret;
media-solo6x10-replace-max-a-min-b-c-by-clamp-b-a-c.patch
iommu-arm-smmu-qcom-add-missing-gmu-entry-to-match-table.patch
iommu-dma-trace-bounce-buffer-usage-when-mapping-buffers.patch
-soundwire-fix-initializing-sysfs-for-same-devices-on-different-buses.patch
+wifi-mt76-fix-broken-precal-loading-from-mtd-for-mt7915.patch
+wifi-rtlwifi-remove-bogus-and-dangerous-aspm-disable-enable-code.patch
+wifi-rtlwifi-convert-lnkctl-change-to-pcie-cap-rmw-accessors.patch
+wifi-mwifiex-add-extra-delay-for-firmware-ready.patch
+wifi-mwifiex-configure-bssid-consistently-when-starting-ap.patch
+wifi-mwifiex-fix-uninitialized-firmware_stat.patch
+net-stmmac-fix-ethtool-per-queue-statistics.patch
+net-stmmac-prevent-dsa-tags-from-breaking-coe.patch
+revert-net-rtnetlink-enslave-device-before-bringing-it-up.patch
+revert-nsvm-check-for-reserved-encodings-of-tlb_control-in-nested-vmcb.patch
+drm-amdgpu-revert-adjust-removal-control-flow-for-smu-v13_0_2.patch
+cxl-port-fix-decoder-initialization-when-nr_targets-interleave_ways.patch
+pci-p2pdma-remove-reference-to-pci_p2pdma_map_sg.patch
+x86-pci-reserve-ecam-if-bios-didn-t-include-it-in-pnp0c02-_crs.patch
+pci-dwc-endpoint-fix-dw_pcie_ep_raise_msix_irq-alignment-support.patch
+pci-mediatek-clear-interrupt-status-before-dispatching-handler.patch
+arm-dts-qcom-sdx55-fix-the-base-address-of-pcie-phy.patch
+x86-kvm-do-not-try-to-disable-kvmclock-if-it-was-not-enabled.patch
+kvm-arm64-vgic-v4-restore-pending-state-on-host-userspace-write.patch
+kvm-arm64-vgic-its-avoid-potential-uaf-in-lpi-translation-cache.patch
+kvm-x86-pmu-move-pmu-reset-logic-to-common-x86-code.patch
+kvm-x86-pmu-reset-the-pmu-i.e.-stop-counters-before-refreshing.patch
+iio-adc-ad7091r-pass-iio_dev-to-event-handler.patch
+iio-adc-ad7091r-allow-users-to-configure-device-events.patch
+iio-adc-ad7091r-enable-internal-vref-if-external-vref-is-not-supplied.patch
+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
+++ /dev/null
-From 8a8a9ac8a4972ee69d3dd3d1ae43963ae39cee18 Mon Sep 17 00:00:00 2001
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Date: Tue, 17 Oct 2023 11:09:33 -0500
-Subject: soundwire: fix initializing sysfs for same devices on different buses
-
-From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-
-commit 8a8a9ac8a4972ee69d3dd3d1ae43963ae39cee18 upstream.
-
-If same devices with same device IDs are present on different soundwire
-buses, the probe fails due to conflicting device names and sysfs
-entries:
-
- sysfs: cannot create duplicate filename '/bus/soundwire/devices/sdw:0:0217:0204:00:0'
-
-The link ID is 0 for both devices, so they should be differentiated by
-the controller ID. Add the controller ID so, the device names and sysfs entries look
-like:
-
- sdw:1:0:0217:0204:00:0 -> ../../../devices/platform/soc@0/6ab0000.soundwire-controller/sdw-master-1-0/sdw:1:0:0217:0204:00:0
- sdw:3:0:0217:0204:00:0 -> ../../../devices/platform/soc@0/6b10000.soundwire-controller/sdw-master-3-0/sdw:3:0:0217:0204:00:0
-
-[PLB changes: use bus->controller_id instead of bus->id]
-
-Fixes: 7c3cd189b86d ("soundwire: Add Master registration")
-Cc: stable@vger.kernel.org
-Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
-Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
-Co-developed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
-Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
-Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
-Acked-by: Mark Brown <broonie@kernel.org>
-Tested-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-Link: https://lore.kernel.org/r/20231017160933.12624-3-pierre-louis.bossart@linux.intel.com
-Signed-off-by: Vinod Koul <vkoul@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- drivers/soundwire/slave.c | 12 ++++++------
- sound/soc/intel/boards/sof_sdw.c | 4 ++--
- 2 files changed, 8 insertions(+), 8 deletions(-)
-
---- a/drivers/soundwire/slave.c
-+++ b/drivers/soundwire/slave.c
-@@ -39,14 +39,14 @@ int sdw_slave_add(struct sdw_bus *bus,
- slave->dev.fwnode = fwnode;
-
- if (id->unique_id == SDW_IGNORED_UNIQUE_ID) {
-- /* name shall be sdw:link:mfg:part:class */
-- dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x",
-- bus->link_id, id->mfg_id, id->part_id,
-+ /* name shall be sdw:ctrl:link:mfg:part:class */
-+ dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x",
-+ bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
- id->class_id);
- } else {
-- /* name shall be sdw:link:mfg:part:class:unique */
-- dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x:%01x",
-- bus->link_id, id->mfg_id, id->part_id,
-+ /* name shall be sdw:ctrl:link:mfg:part:class:unique */
-+ dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x:%01x",
-+ bus->controller_id, bus->link_id, id->mfg_id, id->part_id,
- id->class_id, id->unique_id);
- }
-
---- a/sound/soc/intel/boards/sof_sdw.c
-+++ b/sound/soc/intel/boards/sof_sdw.c
-@@ -1232,11 +1232,11 @@ static int fill_sdw_codec_dlc(struct dev
- else if (is_unique_device(adr_link, sdw_version, mfg_id, part_id,
- class_id, adr_index))
- codec->name = devm_kasprintf(dev, GFP_KERNEL,
-- "sdw:%01x:%04x:%04x:%02x", link_id,
-+ "sdw:0:%01x:%04x:%04x:%02x", link_id,
- mfg_id, part_id, class_id);
- else
- codec->name = devm_kasprintf(dev, GFP_KERNEL,
-- "sdw:%01x:%04x:%04x:%02x:%01x", link_id,
-+ "sdw:0:%01x:%04x:%04x:%02x:%01x", link_id,
- mfg_id, part_id, class_id, unique_id);
-
- if (!codec->name)
--- /dev/null
+From e874a79250b39447765ac13272b67ac36ccf2a75 Mon Sep 17 00:00:00 2001
+From: Christian Marangi <ansuelsmth@gmail.com>
+Date: Wed, 18 Oct 2023 15:09:37 +0200
+Subject: wifi: mt76: fix broken precal loading from MTD for mt7915
+
+From: Christian Marangi <ansuelsmth@gmail.com>
+
+commit e874a79250b39447765ac13272b67ac36ccf2a75 upstream.
+
+Commit 495184ac91bb ("mt76: mt7915: add support for applying
+pre-calibration data") was fundamentally broken and never worked.
+
+The idea (before NVMEM support) was to expand the MTD function and pass
+an additional offset. For normal EEPROM load the offset would always be
+0. For the purpose of precal loading, an offset was passed that was
+internally the size of EEPROM, since precal data is right after the
+EEPROM.
+
+Problem is that the offset value passed is never handled and is actually
+overwrite by
+
+ offset = be32_to_cpup(list);
+ ret = mtd_read(mtd, offset, len, &retlen, eep);
+
+resulting in the passed offset value always ingnored. (and even passing
+garbage data as precal as the start of the EEPROM is getting read)
+
+Fix this by adding to the current offset value, the offset from DT to
+correctly read the piece of data at the requested location.
+
+Cc: stable@vger.kernel.org
+Fixes: 495184ac91bb ("mt76: mt7915: add support for applying pre-calibration data")
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/mediatek/mt76/eeprom.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/mediatek/mt76/eeprom.c
++++ b/drivers/net/wireless/mediatek/mt76/eeprom.c
+@@ -67,7 +67,7 @@ static int mt76_get_of_epprom_from_mtd(s
+ goto out_put_node;
+ }
+
+- offset = be32_to_cpup(list);
++ offset += be32_to_cpup(list);
+ ret = mtd_read(mtd, offset, len, &retlen, eep);
+ put_mtd_device(mtd);
+ if (mtd_is_bitflip(ret))
--- /dev/null
+From 1c5d463c0770c6fa2037511a24fb17966fd07d97 Mon Sep 17 00:00:00 2001
+From: David Lin <yu-hao.lin@nxp.com>
+Date: Sat, 9 Dec 2023 07:40:29 +0800
+Subject: wifi: mwifiex: add extra delay for firmware ready
+
+From: David Lin <yu-hao.lin@nxp.com>
+
+commit 1c5d463c0770c6fa2037511a24fb17966fd07d97 upstream.
+
+For SDIO IW416, due to a bug, FW may return ready before complete full
+initialization. Command timeout may occur at driver load after reboot.
+Workaround by adding 100ms delay at checking FW status.
+
+Signed-off-by: David Lin <yu-hao.lin@nxp.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Acked-by: Brian Norris <briannorris@chromium.org>
+Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com> # Verdin AM62 (IW416)
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231208234029.2197-1-yu-hao.lin@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/marvell/mwifiex/sdio.c | 19 +++++++++++++++++++
+ drivers/net/wireless/marvell/mwifiex/sdio.h | 2 ++
+ 2 files changed, 21 insertions(+)
+
+--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
++++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
+@@ -331,6 +331,7 @@ static const struct mwifiex_sdio_device
+ .can_dump_fw = false,
+ .can_auto_tdls = false,
+ .can_ext_scan = false,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {
+@@ -346,6 +347,7 @@ static const struct mwifiex_sdio_device
+ .can_dump_fw = false,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {
+@@ -361,6 +363,7 @@ static const struct mwifiex_sdio_device
+ .can_dump_fw = false,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
+@@ -376,6 +379,7 @@ static const struct mwifiex_sdio_device
+ .can_dump_fw = true,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {
+@@ -392,6 +396,7 @@ static const struct mwifiex_sdio_device
+ .fw_dump_enh = true,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {
+@@ -408,6 +413,7 @@ static const struct mwifiex_sdio_device
+ .fw_dump_enh = true,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = true,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {
+@@ -425,6 +431,7 @@ static const struct mwifiex_sdio_device
+ .fw_dump_enh = true,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {
+@@ -440,6 +447,7 @@ static const struct mwifiex_sdio_device
+ .can_dump_fw = false,
+ .can_auto_tdls = true,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {
+@@ -456,6 +464,7 @@ static const struct mwifiex_sdio_device
+ .fw_dump_enh = true,
+ .can_auto_tdls = true,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {
+@@ -471,6 +480,7 @@ static const struct mwifiex_sdio_device
+ .can_dump_fw = false,
+ .can_auto_tdls = false,
+ .can_ext_scan = true,
++ .fw_ready_extra_delay = false,
+ };
+
+ static struct memory_type_mapping generic_mem_type_map[] = {
+@@ -563,6 +573,7 @@ mwifiex_sdio_probe(struct sdio_func *fun
+ card->fw_dump_enh = data->fw_dump_enh;
+ card->can_auto_tdls = data->can_auto_tdls;
+ card->can_ext_scan = data->can_ext_scan;
++ card->fw_ready_extra_delay = data->fw_ready_extra_delay;
+ INIT_WORK(&card->work, mwifiex_sdio_work);
+ }
+
+@@ -766,6 +777,7 @@ mwifiex_sdio_read_fw_status(struct mwifi
+ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
+ u32 poll_num)
+ {
++ struct sdio_mmc_card *card = adapter->card;
+ int ret = 0;
+ u16 firmware_stat;
+ u32 tries;
+@@ -783,6 +795,13 @@ static int mwifiex_check_fw_status(struc
+ ret = -1;
+ }
+
++ if (card->fw_ready_extra_delay &&
++ firmware_stat == FIRMWARE_READY_SDIO)
++ /* firmware might pretend to be ready, when it's not.
++ * Wait a little bit more as a workaround.
++ */
++ msleep(100);
++
+ return ret;
+ }
+
+--- a/drivers/net/wireless/marvell/mwifiex/sdio.h
++++ b/drivers/net/wireless/marvell/mwifiex/sdio.h
+@@ -255,6 +255,7 @@ struct sdio_mmc_card {
+ bool fw_dump_enh;
+ bool can_auto_tdls;
+ bool can_ext_scan;
++ bool fw_ready_extra_delay;
+
+ struct mwifiex_sdio_mpa_tx mpa_tx;
+ struct mwifiex_sdio_mpa_rx mpa_rx;
+@@ -278,6 +279,7 @@ struct mwifiex_sdio_device {
+ bool fw_dump_enh;
+ bool can_auto_tdls;
+ bool can_ext_scan;
++ bool fw_ready_extra_delay;
+ };
+
+ /*
--- /dev/null
+From f0dd488e11e71ac095df7638d892209c629d9af2 Mon Sep 17 00:00:00 2001
+From: David Lin <yu-hao.lin@nxp.com>
+Date: Fri, 15 Dec 2023 08:51:18 +0800
+Subject: wifi: mwifiex: configure BSSID consistently when starting AP
+
+From: David Lin <yu-hao.lin@nxp.com>
+
+commit f0dd488e11e71ac095df7638d892209c629d9af2 upstream.
+
+AP BSSID configuration is missing at AP start. Without this fix, FW returns
+STA interface MAC address after first init. When hostapd restarts, it gets MAC
+address from netdev before driver sets STA MAC to netdev again. Now MAC address
+between hostapd and net interface are different causes STA cannot connect to
+AP. After that MAC address of uap0 mlan0 become the same. And issue disappears
+after following hostapd restart (another issue is AP/STA MAC address become the
+same).
+
+This patch fixes the issue cleanly.
+
+Signed-off-by: David Lin <yu-hao.lin@nxp.com>
+Fixes: 12190c5d80bd ("mwifiex: add cfg80211 start_ap and stop_ap handlers")
+Cc: stable@vger.kernel.org
+Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
+Tested-by: Rafael Beims <rafael.beims@toradex.com> # Verdin iMX8MP/SD8997 SD
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231215005118.17031-1-yu-hao.lin@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/marvell/mwifiex/cfg80211.c | 2 ++
+ drivers/net/wireless/marvell/mwifiex/fw.h | 1 +
+ drivers/net/wireless/marvell/mwifiex/ioctl.h | 1 +
+ drivers/net/wireless/marvell/mwifiex/uap_cmd.c | 8 ++++++++
+ 4 files changed, 12 insertions(+)
+
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -2047,6 +2047,8 @@ static int mwifiex_cfg80211_start_ap(str
+
+ mwifiex_set_sys_config_invalid_data(bss_cfg);
+
++ memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN);
++
+ if (params->beacon_interval)
+ bss_cfg->beacon_period = params->beacon_interval;
+ if (params->dtim_period)
+--- a/drivers/net/wireless/marvell/mwifiex/fw.h
++++ b/drivers/net/wireless/marvell/mwifiex/fw.h
+@@ -165,6 +165,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
+ #define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32)
+ #define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35)
+ #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42)
++#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43)
+ #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44)
+ #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45)
+ #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48)
+--- a/drivers/net/wireless/marvell/mwifiex/ioctl.h
++++ b/drivers/net/wireless/marvell/mwifiex/ioctl.h
+@@ -107,6 +107,7 @@ struct mwifiex_uap_bss_param {
+ u8 qos_info;
+ u8 power_constraint;
+ struct mwifiex_types_wmm_info wmm_info;
++ u8 mac_addr[ETH_ALEN];
+ };
+
+ enum {
+--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
++++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
+@@ -468,6 +468,7 @@ void mwifiex_config_uap_11d(struct mwifi
+ static int
+ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
+ {
++ struct host_cmd_tlv_mac_addr *mac_tlv;
+ struct host_cmd_tlv_dtim_period *dtim_period;
+ struct host_cmd_tlv_beacon_period *beacon_period;
+ struct host_cmd_tlv_ssid *ssid;
+@@ -487,6 +488,13 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, v
+ int i;
+ u16 cmd_size = *param_size;
+
++ mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv;
++ mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS);
++ mac_tlv->header.len = cpu_to_le16(ETH_ALEN);
++ memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN);
++ cmd_size += sizeof(struct host_cmd_tlv_mac_addr);
++ tlv += sizeof(struct host_cmd_tlv_mac_addr);
++
+ if (bss_cfg->ssid.ssid_len) {
+ ssid = (struct host_cmd_tlv_ssid *)tlv;
+ ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID);
--- /dev/null
+From 3df95e265924ac898c1a38a0c01846dd0bd3b354 Mon Sep 17 00:00:00 2001
+From: David Lin <yu-hao.lin@nxp.com>
+Date: Thu, 21 Dec 2023 09:55:11 +0800
+Subject: wifi: mwifiex: fix uninitialized firmware_stat
+
+From: David Lin <yu-hao.lin@nxp.com>
+
+commit 3df95e265924ac898c1a38a0c01846dd0bd3b354 upstream.
+
+Variable firmware_stat is possible to be used without initialization.
+
+Signed-off-by: David Lin <yu-hao.lin@nxp.com>
+Fixes: 1c5d463c0770 ("wifi: mwifiex: add extra delay for firmware ready")
+Cc: stable@vger.kernel.org
+Reported-by: kernel test robot <lkp@intel.com>
+Reported-by: Dan Carpenter <error27@gmail.com>
+Closes: https://lore.kernel.org/r/202312192236.ZflaWYCw-lkp@intel.com/
+Acked-by: Brian Norris <briannorris@chromium.org>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://msgid.link/20231221015511.1032128-1-yu-hao.lin@nxp.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/marvell/mwifiex/sdio.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/marvell/mwifiex/sdio.c
++++ b/drivers/net/wireless/marvell/mwifiex/sdio.c
+@@ -779,7 +779,7 @@ static int mwifiex_check_fw_status(struc
+ {
+ struct sdio_mmc_card *card = adapter->card;
+ int ret = 0;
+- u16 firmware_stat;
++ u16 firmware_stat = 0;
+ u32 tries;
+
+ for (tries = 0; tries < poll_num; tries++) {
--- /dev/null
+From 5894d0089cbc146063dcc0239a78ede0a8142efb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
+Date: Fri, 24 Nov 2023 10:47:17 +0200
+Subject: wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+commit 5894d0089cbc146063dcc0239a78ede0a8142efb upstream.
+
+The rtlwifi driver comes with custom code to write into PCIe Link
+Control register. RMW access for the Link Control register requires
+locking that is already provided by the standard PCIe capability
+accessors.
+
+Convert the custom RMW code writing into LNKCTL register to standard
+RMW capability accessors. The accesses are changed to cover the full
+LNKCTL register instead of touching just a single byte of the register.
+
+Fixes: 0c8173385e54 ("rtl8192ce: Add new driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20231124084725.12738-3-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/pci.c | 21 +++++++++++++++------
+ 1 file changed, 15 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
+@@ -164,21 +164,29 @@ static bool _rtl_pci_platform_switch_dev
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
++ value &= PCI_EXP_LNKCTL_ASPMC;
++
+ if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
+- value |= 0x40;
++ value |= PCI_EXP_LNKCTL_CCC;
+
+- pci_write_config_byte(rtlpci->pdev, 0x80, value);
++ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_ASPMC | value,
++ value);
+
+ return false;
+ }
+
+-/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
+-static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
++/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */
++static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value)
+ {
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+- pci_write_config_byte(rtlpci->pdev, 0x81, value);
++ value &= PCI_EXP_LNKCTL_CLKREQ_EN;
++
++ pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL,
++ PCI_EXP_LNKCTL_CLKREQ_EN,
++ value);
+
+ if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+ udelay(100);
+@@ -259,7 +267,8 @@ static void rtl_pci_enable_aspm(struct i
+
+ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) {
+ _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level &
+- RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
++ RT_RF_OFF_LEVL_CLK_REQ) ?
++ PCI_EXP_LNKCTL_CLKREQ_EN : 0);
+ RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
+ }
+ udelay(100);
--- /dev/null
+From b3943b3c2971444364e03224cfc828c5789deada Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= <ilpo.jarvinen@linux.intel.com>
+Date: Fri, 24 Nov 2023 10:47:16 +0200
+Subject: wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+
+commit b3943b3c2971444364e03224cfc828c5789deada upstream.
+
+Ever since introduction in the commit 0c8173385e54 ("rtl8192ce: Add new
+driver") the rtlwifi code has, according to comments, attempted to
+disable/enable ASPM of the upstream bridge by writing into its LNKCTL
+register. However, the code has never been correct because it performs
+the writes to the device instead of the upstream bridge.
+
+Worse yet, the offset where the PCIe capabilities reside is derived
+from the offset of the upstream bridge. As a result, the write will use
+an offset on the device that does not relate to the LNKCTL register
+making the ASPM disable/enable code outright dangerous.
+
+Because of those problems, there is no indication that the driver needs
+disable/enable ASPM on the upstream bridge. As the Capabilities offset
+is not correctly calculated for the write to target device's LNKCTL
+register, the code is not disabling/enabling device's ASPM either.
+Therefore, just remove the upstream bridge related ASPM disable/enable
+code entirely.
+
+The upstream bridge related ASPM code was the only user of the struct
+mp_adapter members num4bytes, pcibridge_pciehdr_offset, and
+pcibridge_linkctrlreg so those are removed as well.
+
+Note: This change does not remove the code related to changing the
+device's ASPM on purpose (which is independent of this flawed code
+related to upstream bridge's ASPM).
+
+Suggested-by: Bjorn Helgaas <bhelgaas@kernel.org>
+Fixes: 0c8173385e54 ("rtl8192ce: Add new driver")
+Fixes: 886e14b65a8f ("rtlwifi: Eliminate raw reads and writes from PCIe portion")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Kalle Valo <kvalo@kernel.org>
+Link: https://lore.kernel.org/r/20231124084725.12738-2-ilpo.jarvinen@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/realtek/rtlwifi/pci.c | 58 -----------------------------
+ drivers/net/wireless/realtek/rtlwifi/pci.h | 5 --
+ 2 files changed, 1 insertion(+), 62 deletions(-)
+
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
+@@ -192,11 +192,8 @@ static void rtl_pci_disable_aspm(struct
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+- u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+ /*Retrieve original configuration settings. */
+ u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg;
+- u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
+- pcibridge_linkctrlreg;
+ u16 aspmlevel = 0;
+ u8 tmp_u1b = 0;
+
+@@ -221,16 +218,8 @@ static void rtl_pci_disable_aspm(struct
+ /*Set corresponding value. */
+ aspmlevel |= BIT(0) | BIT(1);
+ linkctrl_reg &= ~aspmlevel;
+- pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1));
+
+ _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg);
+- udelay(50);
+-
+- /*4 Disable Pci Bridge ASPM */
+- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
+- pcibridge_linkctrlreg);
+-
+- udelay(50);
+ }
+
+ /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for
+@@ -245,9 +234,7 @@ static void rtl_pci_enable_aspm(struct i
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+ u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+- u8 num4bytes = pcipriv->ndis_adapter.num4bytes;
+ u16 aspmlevel;
+- u8 u_pcibridge_aspmsetting;
+ u8 u_device_aspmsetting;
+
+ if (!ppsc->support_aspm)
+@@ -259,25 +246,6 @@ static void rtl_pci_enable_aspm(struct i
+ return;
+ }
+
+- /*4 Enable Pci Bridge ASPM */
+-
+- u_pcibridge_aspmsetting =
+- pcipriv->ndis_adapter.pcibridge_linkctrlreg |
+- rtlpci->const_hostpci_aspm_setting;
+-
+- if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL)
+- u_pcibridge_aspmsetting &= ~BIT(0);
+-
+- pci_write_config_byte(rtlpci->pdev, (num4bytes << 2),
+- u_pcibridge_aspmsetting);
+-
+- rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD,
+- "PlatformEnableASPM(): Write reg[%x] = %x\n",
+- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10),
+- u_pcibridge_aspmsetting);
+-
+- udelay(50);
+-
+ /*Get ASPM level (with/without Clock Req) */
+ aspmlevel = rtlpci->const_devicepci_aspm_setting;
+ u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg;
+@@ -358,22 +326,6 @@ static bool rtl_pci_check_buddy_priv(str
+ return tpriv != NULL;
+ }
+
+-static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw)
+-{
+- struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+- struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+- u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
+- u8 linkctrl_reg;
+- u8 num4bbytes;
+-
+- num4bbytes = (capabilityoffset + 0x10) / 4;
+-
+- /*Read Link Control Register */
+- pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg);
+-
+- pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
+-}
+-
+ static void rtl_pci_parse_configuration(struct pci_dev *pdev,
+ struct ieee80211_hw *hw)
+ {
+@@ -2028,12 +1980,6 @@ static bool _rtl_pci_find_adapter(struct
+ PCI_SLOT(bridge_pdev->devfn);
+ pcipriv->ndis_adapter.pcibridge_funcnum =
+ PCI_FUNC(bridge_pdev->devfn);
+- pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+- pci_pcie_cap(bridge_pdev);
+- pcipriv->ndis_adapter.num4bytes =
+- (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
+-
+- rtl_pci_get_linkcontrol_field(hw);
+
+ if (pcipriv->ndis_adapter.pcibridge_vendor ==
+ PCI_BRIDGE_VENDOR_AMD) {
+@@ -2050,13 +1996,11 @@ static bool _rtl_pci_find_adapter(struct
+ pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg);
+
+ rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG,
+- "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n",
++ "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n",
+ pcipriv->ndis_adapter.pcibridge_busnum,
+ pcipriv->ndis_adapter.pcibridge_devnum,
+ pcipriv->ndis_adapter.pcibridge_funcnum,
+ pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor],
+- pcipriv->ndis_adapter.pcibridge_pciehdr_offset,
+- pcipriv->ndis_adapter.pcibridge_linkctrlreg,
+ pcipriv->ndis_adapter.amd_l1_patch);
+
+ rtl_pci_parse_configuration(pdev, hw);
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.h
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.h
+@@ -236,11 +236,6 @@ struct mp_adapter {
+ u16 pcibridge_vendorid;
+ u16 pcibridge_deviceid;
+
+- u8 num4bytes;
+-
+- u8 pcibridge_pciehdr_offset;
+- u8 pcibridge_linkctrlreg;
+-
+ bool amd_l1_patch;
+ };
+
--- /dev/null
+From 1c6d984f523f67ecfad1083bb04c55d91977bb15 Mon Sep 17 00:00:00 2001
+From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
+Date: Tue, 5 Dec 2023 03:45:01 +0300
+Subject: x86/kvm: Do not try to disable kvmclock if it was not enabled
+
+From: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+
+commit 1c6d984f523f67ecfad1083bb04c55d91977bb15 upstream.
+
+kvm_guest_cpu_offline() tries to disable kvmclock regardless if it is
+present in the VM. It leads to write to a MSR that doesn't exist on some
+configurations, namely in TDX guest:
+
+ unchecked MSR access error: WRMSR to 0x12 (tried to write 0x0000000000000000)
+ at rIP: 0xffffffff8110687c (kvmclock_disable+0x1c/0x30)
+
+kvmclock enabling is gated by CLOCKSOURCE and CLOCKSOURCE2 KVM paravirt
+features.
+
+Do not disable kvmclock if it was not enabled.
+
+Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
+Fixes: c02027b5742b ("x86/kvm: Disable kvmclock on all CPUs on shutdown")
+Reviewed-by: Sean Christopherson <seanjc@google.com>
+Reviewed-by: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Wanpeng Li <wanpengli@tencent.com>
+Cc: stable@vger.kernel.org
+Message-Id: <20231205004510.27164-6-kirill.shutemov@linux.intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kernel/kvmclock.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/kernel/kvmclock.c
++++ b/arch/x86/kernel/kvmclock.c
+@@ -24,8 +24,8 @@
+
+ static int kvmclock __initdata = 1;
+ static int kvmclock_vsyscall __initdata = 1;
+-static int msr_kvm_system_time __ro_after_init = MSR_KVM_SYSTEM_TIME;
+-static int msr_kvm_wall_clock __ro_after_init = MSR_KVM_WALL_CLOCK;
++static int msr_kvm_system_time __ro_after_init;
++static int msr_kvm_wall_clock __ro_after_init;
+ static u64 kvm_sched_clock_offset __ro_after_init;
+
+ static int __init parse_no_kvmclock(char *arg)
+@@ -195,7 +195,8 @@ static void kvm_setup_secondary_clock(vo
+
+ void kvmclock_disable(void)
+ {
+- native_write_msr(msr_kvm_system_time, 0, 0);
++ if (msr_kvm_system_time)
++ native_write_msr(msr_kvm_system_time, 0, 0);
+ }
+
+ static void __init kvmclock_init_mem(void)
+@@ -294,7 +295,10 @@ void __init kvmclock_init(void)
+ if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) {
+ msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW;
+ msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW;
+- } else if (!kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
++ } else if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
++ msr_kvm_system_time = MSR_KVM_SYSTEM_TIME;
++ msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK;
++ } else {
+ return;
+ }
+
--- /dev/null
+From 070909e56a7d65fd0b4aad6e808966b7c634befe Mon Sep 17 00:00:00 2001
+From: Bjorn Helgaas <bhelgaas@google.com>
+Date: Tue, 21 Nov 2023 12:36:35 -0600
+Subject: x86/pci: Reserve ECAM if BIOS didn't include it in PNP0C02 _CRS
+
+From: Bjorn Helgaas <bhelgaas@google.com>
+
+commit 070909e56a7d65fd0b4aad6e808966b7c634befe upstream.
+
+Tomasz, Sebastian, and some Proxmox users reported problems initializing
+ixgbe NICs.
+
+I think the problem is that ECAM space described in the ACPI MCFG table is
+not reserved via a PNP0C02 _CRS method as required by the PCI Firmware spec
+(r3.3, sec 4.1.2), but it *is* included in the PNP0A03 host bridge _CRS as
+part of the MMIO aperture.
+
+If we allocate space for a PCI BAR, we're likely to allocate it from that
+ECAM space, which obviously cannot work.
+
+This could happen for any device, but in the ixgbe case it happens because
+it's an SR-IOV device and the BIOS didn't allocate space for the VF BARs,
+so Linux reallocated the bridge window leading to ixgbe and put it on top
+of the ECAM space. From Tomasz' system:
+
+ PCI: MMCONFIG for domain 0000 [bus 00-ff] at [mem 0x80000000-0x8fffffff] (base 0x80000000)
+ PCI: MMCONFIG at [mem 0x80000000-0x8fffffff] not reserved in ACPI motherboard resources
+ pci_bus 0000:00: root bus resource [mem 0x80000000-0xfbffffff window]
+
+ pci 0000:00:01.1: PCI bridge to [bus 02-03]
+ pci 0000:00:01.1: bridge window [mem 0xfb900000-0xfbbfffff]
+ pci 0000:02:00.0: [8086:10fb] type 00 class 0x020000 # ixgbe
+ pci 0000:02:00.0: reg 0x10: [mem 0xfba80000-0xfbafffff 64bit]
+ pci 0000:02:00.0: VF(n) BAR0 space: [mem 0x00000000-0x000fffff 64bit] (contains BAR0 for 64 VFs)
+ pci 0000:02:00.0: BAR 7: no space for [mem size 0x00100000 64bit] # VF BAR 0
+
+ pci_bus 0000:00: No. 2 try to assign unassigned res
+ pci 0000:00:01.1: resource 14 [mem 0xfb900000-0xfbbfffff] released
+ pci 0000:00:01.1: BAR 14: assigned [mem 0x80000000-0x806fffff]
+ pci 0000:02:00.0: BAR 0: assigned [mem 0x80000000-0x8007ffff 64bit]
+ pci 0000:02:00.0: BAR 7: assigned [mem 0x80204000-0x80303fff 64bit] # VF BAR 0
+
+Fixes: 07eab0901ede ("efi/x86: Remove EfiMemoryMappedIO from E820 map")
+Fixes: fd3a8cff4d4a ("x86/pci: Treat EfiMemoryMappedIO as reservation of ECAM space")
+Reported-by: Tomasz Pala <gotar@polanet.pl>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218050
+Reported-by: Sebastian Manciulea <manciuleas@protonmail.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=218107
+Link: https://forum.proxmox.com/threads/proxmox-8-kernel-6-2-16-4-pve-ixgbe-driver-fails-to-load-due-to-pci-device-probing-failure.131203/
+Link: https://lore.kernel.org/r/20231121183643.249006-2-helgaas@kernel.org
+Tested-by: Tomasz Pala <gotar@polanet.pl>
+Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
+Cc: stable@vger.kernel.org # v6.2+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/pci/mmconfig-shared.c | 13 ++++++++++++-
+ 1 file changed, 12 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/pci/mmconfig-shared.c
++++ b/arch/x86/pci/mmconfig-shared.c
+@@ -525,6 +525,8 @@ static bool __ref is_mmconf_reserved(che
+ static bool __ref
+ pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int early)
+ {
++ struct resource *conflict;
++
+ if (!early && !acpi_disabled) {
+ if (is_mmconf_reserved(is_acpi_reserved, cfg, dev,
+ "ACPI motherboard resource"))
+@@ -542,8 +544,17 @@ pci_mmcfg_check_reserved(struct device *
+ &cfg->res);
+
+ if (is_mmconf_reserved(is_efi_mmio, cfg, dev,
+- "EfiMemoryMappedIO"))
++ "EfiMemoryMappedIO")) {
++ conflict = insert_resource_conflict(&iomem_resource,
++ &cfg->res);
++ if (conflict)
++ pr_warn("MMCONFIG %pR conflicts with %s %pR\n",
++ &cfg->res, conflict->name, conflict);
++ else
++ pr_info("MMCONFIG %pR reserved to work around lack of ACPI motherboard _CRS\n",
++ &cfg->res);
+ return true;
++ }
+ }
+
+ /*