--- /dev/null
+From c6557ccf8094ce2e1142c6e49cd47f5d5e2933a8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Adrien=20Verg=C3=A9?= <adrienverge@gmail.com>
+Date: Wed, 26 Feb 2025 14:55:15 +0100
+Subject: ALSA: hda/realtek: Fix microphone regression on ASUS N705UD
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Adrien Vergé <adrienverge@gmail.com>
+
+commit c6557ccf8094ce2e1142c6e49cd47f5d5e2933a8 upstream.
+
+This fixes a regression introduced a few weeks ago in stable kernels
+6.12.14 and 6.13.3. The internal microphone on ASUS Vivobook N705UD /
+X705UD laptops is broken: the microphone appears in userspace (e.g.
+Gnome settings) but no sound is detected.
+I bisected it to commit 3b4309546b48 ("ALSA: hda: Fix headset detection
+failure due to unstable sort").
+
+I figured out the cause:
+1. The initial pins enabled for the ALC256 driver are:
+ cfg->inputs == {
+ { pin=0x19, type=AUTO_PIN_MIC,
+ is_headset_mic=1, is_headphone_mic=0, has_boost_on_pin=1 },
+ { pin=0x1a, type=AUTO_PIN_MIC,
+ is_headset_mic=0, is_headphone_mic=0, has_boost_on_pin=1 } }
+2. Since 2017 and commits c1732ede5e8 ("ALSA: hda/realtek - Fix headset
+ and mic on several ASUS laptops with ALC256") and 28e8af8a163 ("ALSA:
+ hda/realtek: Fix mic and headset jack sense on ASUS X705UD"), the
+ quirk ALC256_FIXUP_ASUS_MIC is also applied to ASUS X705UD / N705UD
+ laptops.
+ This added another internal microphone on pin 0x13:
+ cfg->inputs == {
+ { pin=0x13, type=AUTO_PIN_MIC,
+ is_headset_mic=0, is_headphone_mic=0, has_boost_on_pin=1 },
+ { pin=0x19, type=AUTO_PIN_MIC,
+ is_headset_mic=1, is_headphone_mic=0, has_boost_on_pin=1 },
+ { pin=0x1a, type=AUTO_PIN_MIC,
+ is_headset_mic=0, is_headphone_mic=0, has_boost_on_pin=1 } }
+ I don't know what this pin 0x13 corresponds to. To the best of my
+ knowledge, these laptops have only one internal microphone.
+3. Before 2025 and commit 3b4309546b48 ("ALSA: hda: Fix headset
+ detection failure due to unstable sort"), the sort function would let
+ the microphone of pin 0x1a (the working one) *before* the microphone
+ of pin 0x13 (the phantom one).
+4. After this commit 3b4309546b48, the fixed sort function puts the
+ working microphone (pin 0x1a) *after* the phantom one (pin 0x13). As
+ a result, no sound is detected anymore.
+
+It looks like the quirk ALC256_FIXUP_ASUS_MIC is not needed anymore for
+ASUS Vivobook X705UD / N705UD laptops. Without it, everything works
+fine:
+- the internal microphone is detected and records actual sound,
+- plugging in a jack headset is detected and can record actual sound
+ with it,
+- unplugging the jack headset makes the system go back to internal
+ microphone and can record actual sound.
+
+Cc: stable@vger.kernel.org
+Cc: Kuan-Wei Chiu <visitorckw@gmail.com>
+Cc: Chris Chiu <chris.chiu@canonical.com>
+Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort")
+Tested-by: Adrien Vergé <adrienverge@gmail.com>
+Signed-off-by: Adrien Vergé <adrienverge@gmail.com>
+Link: https://patch.msgid.link/20250226135515.24219-1-adrienverge@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/patch_realtek.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -10629,7 +10629,6 @@ static const struct hda_quirk alc269_fix
+ SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE),
+ SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
+- SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
+ SND_PCI_QUIRK(0x1043, 0x1a63, "ASUS UX3405MA", ALC245_FIXUP_CS35L41_SPI_2),
+ SND_PCI_QUIRK(0x1043, 0x1a83, "ASUS UM5302LA", ALC294_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2),
--- /dev/null
+From 9af3b4f2d879da01192d6168e6c651e7fb5b652d Mon Sep 17 00:00:00 2001
+From: Dmitry Panchenko <dmitry@d-systems.ee>
+Date: Thu, 20 Feb 2025 18:15:37 +0200
+Subject: ALSA: usb-audio: Re-add sample rate quirk for Pioneer DJM-900NXS2
+
+From: Dmitry Panchenko <dmitry@d-systems.ee>
+
+commit 9af3b4f2d879da01192d6168e6c651e7fb5b652d upstream.
+
+Re-add the sample-rate quirk for the Pioneer DJM-900NXS2. This
+device does not work without setting sample-rate.
+
+Signed-off-by: Dmitry Panchenko <dmitry@d-systems.ee>
+Cc: <stable@vger.kernel.org>
+Link: https://patch.msgid.link/20250220161540.3624660-1-dmitry@d-systems.ee
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/usb/quirks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1868,6 +1868,7 @@ void snd_usb_set_format_quirk(struct snd
+ case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
+ subs->stream_offset_adj = 2;
+ break;
++ case USB_ID(0x2b73, 0x000a): /* Pioneer DJM-900NXS2 */
+ case USB_ID(0x2b73, 0x0013): /* Pioneer DJM-450 */
+ pioneer_djm_set_format_quirk(subs, 0x0082);
+ break;
--- /dev/null
+From 91dcc66b34beb72dde8412421bdc1b4cd40e4fb8 Mon Sep 17 00:00:00 2001
+From: "chr[]" <chris@rudorff.com>
+Date: Wed, 12 Feb 2025 16:51:38 +0100
+Subject: amdgpu/pm/legacy: fix suspend/resume issues
+
+From: chr[] <chris@rudorff.com>
+
+commit 91dcc66b34beb72dde8412421bdc1b4cd40e4fb8 upstream.
+
+resume and irq handler happily races in set_power_state()
+
+* amdgpu_legacy_dpm_compute_clocks() needs lock
+* protect irq work handler
+* fix dpm_enabled usage
+
+v2: fix clang build, integrate Lijo's comments (Alex)
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2524
+Fixes: 3712e7a49459 ("drm/amd/pm: unified lock protections in amdgpu_dpm.c")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Tested-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name> # on Oland PRO
+Signed-off-by: chr[] <chris@rudorff.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit ee3dc9e204d271c9c7a8d4d38a0bce4745d33e71)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c | 25 ++++++++++++++++++------
+ drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c | 8 +++++--
+ drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 26 +++++++++++++++++++------
+ 3 files changed, 45 insertions(+), 14 deletions(-)
+
+--- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c
++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c
+@@ -3042,6 +3042,7 @@ static int kv_dpm_hw_init(struct amdgpu_
+ if (!amdgpu_dpm)
+ return 0;
+
++ mutex_lock(&adev->pm.mutex);
+ kv_dpm_setup_asic(adev);
+ ret = kv_dpm_enable(adev);
+ if (ret)
+@@ -3049,6 +3050,8 @@ static int kv_dpm_hw_init(struct amdgpu_
+ else
+ adev->pm.dpm_enabled = true;
+ amdgpu_legacy_dpm_compute_clocks(adev);
++ mutex_unlock(&adev->pm.mutex);
++
+ return ret;
+ }
+
+@@ -3066,32 +3069,42 @@ static int kv_dpm_suspend(struct amdgpu_
+ {
+ struct amdgpu_device *adev = ip_block->adev;
+
++ cancel_work_sync(&adev->pm.dpm.thermal.work);
++
+ if (adev->pm.dpm_enabled) {
++ mutex_lock(&adev->pm.mutex);
++ adev->pm.dpm_enabled = false;
+ /* disable dpm */
+ kv_dpm_disable(adev);
+ /* reset the power state */
+ adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
++ mutex_unlock(&adev->pm.mutex);
+ }
+ return 0;
+ }
+
+ static int kv_dpm_resume(struct amdgpu_ip_block *ip_block)
+ {
+- int ret;
++ int ret = 0;
+ struct amdgpu_device *adev = ip_block->adev;
+
+- if (adev->pm.dpm_enabled) {
++ if (!amdgpu_dpm)
++ return 0;
++
++ if (!adev->pm.dpm_enabled) {
++ mutex_lock(&adev->pm.mutex);
+ /* asic init will reset to the boot state */
+ kv_dpm_setup_asic(adev);
+ ret = kv_dpm_enable(adev);
+- if (ret)
++ if (ret) {
+ adev->pm.dpm_enabled = false;
+- else
++ } else {
+ adev->pm.dpm_enabled = true;
+- if (adev->pm.dpm_enabled)
+ amdgpu_legacy_dpm_compute_clocks(adev);
++ }
++ mutex_unlock(&adev->pm.mutex);
+ }
+- return 0;
++ return ret;
+ }
+
+ static bool kv_dpm_is_idle(void *handle)
+--- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c
+@@ -1009,9 +1009,12 @@ void amdgpu_dpm_thermal_work_handler(str
+ enum amd_pm_state_type dpm_state = POWER_STATE_TYPE_INTERNAL_THERMAL;
+ int temp, size = sizeof(temp);
+
+- if (!adev->pm.dpm_enabled)
+- return;
++ mutex_lock(&adev->pm.mutex);
+
++ if (!adev->pm.dpm_enabled) {
++ mutex_unlock(&adev->pm.mutex);
++ return;
++ }
+ if (!pp_funcs->read_sensor(adev->powerplay.pp_handle,
+ AMDGPU_PP_SENSOR_GPU_TEMP,
+ (void *)&temp,
+@@ -1033,4 +1036,5 @@ void amdgpu_dpm_thermal_work_handler(str
+ adev->pm.dpm.state = dpm_state;
+
+ amdgpu_legacy_dpm_compute_clocks(adev->powerplay.pp_handle);
++ mutex_unlock(&adev->pm.mutex);
+ }
+--- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
++++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c
+@@ -7785,6 +7785,7 @@ static int si_dpm_hw_init(struct amdgpu_
+ if (!amdgpu_dpm)
+ return 0;
+
++ mutex_lock(&adev->pm.mutex);
+ si_dpm_setup_asic(adev);
+ ret = si_dpm_enable(adev);
+ if (ret)
+@@ -7792,6 +7793,7 @@ static int si_dpm_hw_init(struct amdgpu_
+ else
+ adev->pm.dpm_enabled = true;
+ amdgpu_legacy_dpm_compute_clocks(adev);
++ mutex_unlock(&adev->pm.mutex);
+ return ret;
+ }
+
+@@ -7809,32 +7811,44 @@ static int si_dpm_suspend(struct amdgpu_
+ {
+ struct amdgpu_device *adev = ip_block->adev;
+
++ cancel_work_sync(&adev->pm.dpm.thermal.work);
++
+ if (adev->pm.dpm_enabled) {
++ mutex_lock(&adev->pm.mutex);
++ adev->pm.dpm_enabled = false;
+ /* disable dpm */
+ si_dpm_disable(adev);
+ /* reset the power state */
+ adev->pm.dpm.current_ps = adev->pm.dpm.requested_ps = adev->pm.dpm.boot_ps;
++ mutex_unlock(&adev->pm.mutex);
+ }
++
+ return 0;
+ }
+
+ static int si_dpm_resume(struct amdgpu_ip_block *ip_block)
+ {
+- int ret;
++ int ret = 0;
+ struct amdgpu_device *adev = ip_block->adev;
+
+- if (adev->pm.dpm_enabled) {
++ if (!amdgpu_dpm)
++ return 0;
++
++ if (!adev->pm.dpm_enabled) {
+ /* asic init will reset to the boot state */
++ mutex_lock(&adev->pm.mutex);
+ si_dpm_setup_asic(adev);
+ ret = si_dpm_enable(adev);
+- if (ret)
++ if (ret) {
+ adev->pm.dpm_enabled = false;
+- else
++ } else {
+ adev->pm.dpm_enabled = true;
+- if (adev->pm.dpm_enabled)
+ amdgpu_legacy_dpm_compute_clocks(adev);
++ }
++ mutex_unlock(&adev->pm.mutex);
+ }
+- return 0;
++
++ return ret;
+ }
+
+ static bool si_dpm_is_idle(void *handle)
--- /dev/null
+From eed6bfa8b28230382b797a88569f2c7569a1a419 Mon Sep 17 00:00:00 2001
+From: Ryan Roberts <ryan.roberts@arm.com>
+Date: Wed, 26 Feb 2025 12:06:53 +0000
+Subject: arm64: hugetlb: Fix flush_hugetlb_tlb_range() invalidation level
+
+From: Ryan Roberts <ryan.roberts@arm.com>
+
+commit eed6bfa8b28230382b797a88569f2c7569a1a419 upstream.
+
+commit c910f2b65518 ("arm64/mm: Update tlb invalidation routines for
+FEAT_LPA2") changed the "invalidation level unknown" hint from 0 to
+TLBI_TTL_UNKNOWN (INT_MAX). But the fallback "unknown level" path in
+flush_hugetlb_tlb_range() was not updated. So as it stands, when trying
+to invalidate CONT_PMD_SIZE or CONT_PTE_SIZE hugetlb mappings, we will
+spuriously try to invalidate at level 0 on LPA2-enabled systems.
+
+Fix this so that the fallback passes TLBI_TTL_UNKNOWN, and while we are
+at it, explicitly use the correct stride and level for CONT_PMD_SIZE and
+CONT_PTE_SIZE, which should provide a minor optimization.
+
+Cc: stable@vger.kernel.org
+Fixes: c910f2b65518 ("arm64/mm: Update tlb invalidation routines for FEAT_LPA2")
+Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com>
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
+Link: https://lore.kernel.org/r/20250226120656.2400136-4-ryan.roberts@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/hugetlb.h | 22 ++++++++++++++++------
+ 1 file changed, 16 insertions(+), 6 deletions(-)
+
+--- a/arch/arm64/include/asm/hugetlb.h
++++ b/arch/arm64/include/asm/hugetlb.h
+@@ -76,12 +76,22 @@ static inline void flush_hugetlb_tlb_ran
+ {
+ unsigned long stride = huge_page_size(hstate_vma(vma));
+
+- if (stride == PMD_SIZE)
+- __flush_tlb_range(vma, start, end, stride, false, 2);
+- else if (stride == PUD_SIZE)
+- __flush_tlb_range(vma, start, end, stride, false, 1);
+- else
+- __flush_tlb_range(vma, start, end, PAGE_SIZE, false, 0);
++ switch (stride) {
++#ifndef __PAGETABLE_PMD_FOLDED
++ case PUD_SIZE:
++ __flush_tlb_range(vma, start, end, PUD_SIZE, false, 1);
++ break;
++#endif
++ case CONT_PMD_SIZE:
++ case PMD_SIZE:
++ __flush_tlb_range(vma, start, end, PMD_SIZE, false, 2);
++ break;
++ case CONT_PTE_SIZE:
++ __flush_tlb_range(vma, start, end, PAGE_SIZE, false, 3);
++ break;
++ default:
++ __flush_tlb_range(vma, start, end, PAGE_SIZE, false, TLBI_TTL_UNKNOWN);
++ }
+ }
+
+ #endif /* __ASM_HUGETLB_H */
--- /dev/null
+From 49c87f7677746f3c5bd16c81b23700bb6b88bfd4 Mon Sep 17 00:00:00 2001
+From: Ryan Roberts <ryan.roberts@arm.com>
+Date: Wed, 26 Feb 2025 12:06:52 +0000
+Subject: arm64: hugetlb: Fix huge_ptep_get_and_clear() for non-present ptes
+
+From: Ryan Roberts <ryan.roberts@arm.com>
+
+commit 49c87f7677746f3c5bd16c81b23700bb6b88bfd4 upstream.
+
+arm64 supports multiple huge_pte sizes. Some of the sizes are covered by
+a single pte entry at a particular level (PMD_SIZE, PUD_SIZE), and some
+are covered by multiple ptes at a particular level (CONT_PTE_SIZE,
+CONT_PMD_SIZE). So the function has to figure out the size from the
+huge_pte pointer. This was previously done by walking the pgtable to
+determine the level and by using the PTE_CONT bit to determine the
+number of ptes at the level.
+
+But the PTE_CONT bit is only valid when the pte is present. For
+non-present pte values (e.g. markers, migration entries), the previous
+implementation was therefore erroneously determining the size. There is
+at least one known caller in core-mm, move_huge_pte(), which may call
+huge_ptep_get_and_clear() for a non-present pte. So we must be robust to
+this case. Additionally the "regular" ptep_get_and_clear() is robust to
+being called for non-present ptes so it makes sense to follow the
+behavior.
+
+Fix this by using the new sz parameter which is now provided to the
+function. Additionally when clearing each pte in a contig range, don't
+gather the access and dirty bits if the pte is not present.
+
+An alternative approach that would not require API changes would be to
+store the PTE_CONT bit in a spare bit in the swap entry pte for the
+non-present case. But it felt cleaner to follow other APIs' lead and
+just pass in the size.
+
+As an aside, PTE_CONT is bit 52, which corresponds to bit 40 in the swap
+entry offset field (layout of non-present pte). Since hugetlb is never
+swapped to disk, this field will only be populated for markers, which
+always set this bit to 0 and hwpoison swap entries, which set the offset
+field to a PFN; So it would only ever be 1 for a 52-bit PVA system where
+memory in that high half was poisoned (I think!). So in practice, this
+bit would almost always be zero for non-present ptes and we would only
+clear the first entry if it was actually a contiguous block. That's
+probably a less severe symptom than if it was always interpreted as 1
+and cleared out potentially-present neighboring PTEs.
+
+Cc: stable@vger.kernel.org
+Fixes: 66b3923a1a0f ("arm64: hugetlb: add support for PTE contiguous bit")
+Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
+Link: https://lore.kernel.org/r/20250226120656.2400136-3-ryan.roberts@arm.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/mm/hugetlbpage.c | 51 ++++++++++++++++----------------------------
+ 1 file changed, 19 insertions(+), 32 deletions(-)
+
+--- a/arch/arm64/mm/hugetlbpage.c
++++ b/arch/arm64/mm/hugetlbpage.c
+@@ -100,20 +100,11 @@ static int find_num_contig(struct mm_str
+
+ static inline int num_contig_ptes(unsigned long size, size_t *pgsize)
+ {
+- int contig_ptes = 0;
++ int contig_ptes = 1;
+
+ *pgsize = size;
+
+ switch (size) {
+-#ifndef __PAGETABLE_PMD_FOLDED
+- case PUD_SIZE:
+- if (pud_sect_supported())
+- contig_ptes = 1;
+- break;
+-#endif
+- case PMD_SIZE:
+- contig_ptes = 1;
+- break;
+ case CONT_PMD_SIZE:
+ *pgsize = PMD_SIZE;
+ contig_ptes = CONT_PMDS;
+@@ -122,6 +113,8 @@ static inline int num_contig_ptes(unsign
+ *pgsize = PAGE_SIZE;
+ contig_ptes = CONT_PTES;
+ break;
++ default:
++ WARN_ON(!__hugetlb_valid_size(size));
+ }
+
+ return contig_ptes;
+@@ -163,24 +156,23 @@ static pte_t get_clear_contig(struct mm_
+ unsigned long pgsize,
+ unsigned long ncontig)
+ {
+- pte_t orig_pte = __ptep_get(ptep);
+- unsigned long i;
++ pte_t pte, tmp_pte;
++ bool present;
+
+- for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) {
+- pte_t pte = __ptep_get_and_clear(mm, addr, ptep);
+-
+- /*
+- * If HW_AFDBM is enabled, then the HW could turn on
+- * the dirty or accessed bit for any page in the set,
+- * so check them all.
+- */
+- if (pte_dirty(pte))
+- orig_pte = pte_mkdirty(orig_pte);
+-
+- if (pte_young(pte))
+- orig_pte = pte_mkyoung(orig_pte);
++ pte = __ptep_get_and_clear(mm, addr, ptep);
++ present = pte_present(pte);
++ while (--ncontig) {
++ ptep++;
++ addr += pgsize;
++ tmp_pte = __ptep_get_and_clear(mm, addr, ptep);
++ if (present) {
++ if (pte_dirty(tmp_pte))
++ pte = pte_mkdirty(pte);
++ if (pte_young(tmp_pte))
++ pte = pte_mkyoung(pte);
++ }
+ }
+- return orig_pte;
++ return pte;
+ }
+
+ static pte_t get_clear_contig_flush(struct mm_struct *mm,
+@@ -401,13 +393,8 @@ pte_t huge_ptep_get_and_clear(struct mm_
+ {
+ int ncontig;
+ size_t pgsize;
+- pte_t orig_pte = __ptep_get(ptep);
+-
+- if (!pte_cont(orig_pte))
+- return __ptep_get_and_clear(mm, addr, ptep);
+-
+- ncontig = find_num_contig(mm, addr, ptep, &pgsize);
+
++ ncontig = num_contig_ptes(sz, &pgsize);
+ return get_clear_contig(mm, addr, ptep, pgsize, ncontig);
+ }
+
--- /dev/null
+From 2b1283e1ea9b5e0b06f075f79391a51d9f70749b Mon Sep 17 00:00:00 2001
+From: Ryan Roberts <ryan.roberts@arm.com>
+Date: Tue, 25 Feb 2025 11:46:36 +0000
+Subject: arm64/mm: Fix Boot panic on Ampere Altra
+
+From: Ryan Roberts <ryan.roberts@arm.com>
+
+commit 2b1283e1ea9b5e0b06f075f79391a51d9f70749b upstream.
+
+When the range of present physical memory is sufficiently small enough
+and the reserved address space for the linear map is sufficiently large
+enough, The linear map base address is randomized in
+arm64_memblock_init().
+
+Prior to commit 62cffa496aac ("arm64/mm: Override PARange for !LPA2 and
+use it consistently"), we decided if the sizes were suitable with the
+help of the raw mmfr0.parange. But the commit changed this to use the
+sanitized version instead. But the function runs before the register has
+been sanitized so this returns 0, interpreted as a parange of 32 bits.
+Some fun wrapping occurs and the logic concludes that there is enough
+room to randomize the linear map base address, when really there isn't.
+So the top of the linear map ends up outside the reserved address space.
+
+Since the PA range cannot be overridden in the first place, restore the
+mmfr0 reading logic to its state prior to 62cffa496aac, where the raw
+register value is used.
+
+Reported-by: Luiz Capitulino <luizcap@redhat.com>
+Suggested-by: Ard Biesheuvel <ardb@kernel.org>
+Closes: https://lore.kernel.org/all/a3d9acbe-07c2-43b6-9ba9-a7585f770e83@redhat.com/
+Fixes: 62cffa496aac ("arm64/mm: Override PARange for !LPA2 and use it consistently")
+Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
+Link: https://lore.kernel.org/r/20250225114638.2038006-1-ryan.roberts@arm.com
+Cc: stable@vger.kernel.org
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/mm/init.c | 7 +------
+ 1 file changed, 1 insertion(+), 6 deletions(-)
+
+--- a/arch/arm64/mm/init.c
++++ b/arch/arm64/mm/init.c
+@@ -279,12 +279,7 @@ void __init arm64_memblock_init(void)
+
+ if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
+ extern u16 memstart_offset_seed;
+-
+- /*
+- * Use the sanitised version of id_aa64mmfr0_el1 so that linear
+- * map randomization can be enabled by shrinking the IPA space.
+- */
+- u64 mmfr0 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR0_EL1);
++ u64 mmfr0 = read_cpuid(ID_AA64MMFR0_EL1);
+ int parange = cpuid_feature_extract_unsigned_field(
+ mmfr0, ID_AA64MMFR0_EL1_PARANGE_SHIFT);
+ s64 range = linear_region_size -
--- /dev/null
+From a6aa36e957a1bfb5341986dec32d013d23228fe1 Mon Sep 17 00:00:00 2001
+From: Damien Le Moal <dlemoal@kernel.org>
+Date: Fri, 14 Feb 2025 13:14:34 +0900
+Subject: block: Remove zone write plugs when handling native zone append writes
+
+From: Damien Le Moal <dlemoal@kernel.org>
+
+commit a6aa36e957a1bfb5341986dec32d013d23228fe1 upstream.
+
+For devices that natively support zone append operations,
+REQ_OP_ZONE_APPEND BIOs are not processed through zone write plugging
+and are immediately issued to the zoned device. This means that there is
+no write pointer offset tracking done for these operations and that a
+zone write plug is not necessary.
+
+However, when receiving a zone append BIO, we may already have a zone
+write plug for the target zone if that zone was previously partially
+written using regular write operations. In such case, since the write
+pointer offset of the zone write plug is not incremented by the amount
+of sectors appended to the zone, 2 issues arise:
+1) we risk leaving the plug in the disk hash table if the zone is fully
+ written using zone append or regular write operations, because the
+ write pointer offset will never reach the "zone full" state.
+2) Regular write operations that are issued after zone append operations
+ will always be failed by blk_zone_wplug_prepare_bio() as the write
+ pointer alignment check will fail, even if the user correctly
+ accounted for the zone append operations and issued the regular
+ writes with a correct sector.
+
+Avoid these issues by immediately removing the zone write plug of zones
+that are the target of zone append operations when blk_zone_plug_bio()
+is called. The new function blk_zone_wplug_handle_native_zone_append()
+implements this for devices that natively support zone append. The
+removal of the zone write plug using disk_remove_zone_wplug() requires
+aborting all plugged regular write using disk_zone_wplug_abort() as
+otherwise the plugged write BIOs would never be executed (with the plug
+removed, the completion path will never see again the zone write plug as
+disk_get_zone_wplug() will return NULL). Rate-limited warnings are added
+to blk_zone_wplug_handle_native_zone_append() and to
+disk_zone_wplug_abort() to signal this.
+
+Since blk_zone_wplug_handle_native_zone_append() is called in the hot
+path for operations that will not be plugged, disk_get_zone_wplug() is
+optimized under the assumption that a user issuing zone append
+operations is not at the same time issuing regular writes and that there
+are no hashed zone write plugs. The struct gendisk atomic counter
+nr_zone_wplugs is added to check this, with this counter incremented in
+disk_insert_zone_wplug() and decremented in disk_remove_zone_wplug().
+
+To be consistent with this fix, we do not need to fill the zone write
+plug hash table with zone write plugs for zones that are partially
+written for a device that supports native zone append operations.
+So modify blk_revalidate_seq_zone() to return early to avoid allocating
+and inserting a zone write plug for partially written sequential zones
+if the device natively supports zone append.
+
+Reported-by: Jorgen Hansen <Jorgen.Hansen@wdc.com>
+Fixes: 9b1ce7f0c6f8 ("block: Implement zone append emulation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Tested-by: Jorgen Hansen <Jorgen.Hansen@wdc.com>
+Link: https://lore.kernel.org/r/20250214041434.82564-1-dlemoal@kernel.org
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ block/blk-zoned.c | 76 ++++++++++++++++++++++++++++++++++++++++++++-----
+ include/linux/blkdev.h | 7 ++--
+ 2 files changed, 73 insertions(+), 10 deletions(-)
+
+--- a/block/blk-zoned.c
++++ b/block/blk-zoned.c
+@@ -414,13 +414,14 @@ static bool disk_insert_zone_wplug(struc
+ }
+ }
+ hlist_add_head_rcu(&zwplug->node, &disk->zone_wplugs_hash[idx]);
++ atomic_inc(&disk->nr_zone_wplugs);
+ spin_unlock_irqrestore(&disk->zone_wplugs_lock, flags);
+
+ return true;
+ }
+
+-static struct blk_zone_wplug *disk_get_zone_wplug(struct gendisk *disk,
+- sector_t sector)
++static struct blk_zone_wplug *disk_get_hashed_zone_wplug(struct gendisk *disk,
++ sector_t sector)
+ {
+ unsigned int zno = disk_zone_no(disk, sector);
+ unsigned int idx = hash_32(zno, disk->zone_wplugs_hash_bits);
+@@ -441,6 +442,15 @@ static struct blk_zone_wplug *disk_get_z
+ return NULL;
+ }
+
++static inline struct blk_zone_wplug *disk_get_zone_wplug(struct gendisk *disk,
++ sector_t sector)
++{
++ if (!atomic_read(&disk->nr_zone_wplugs))
++ return NULL;
++
++ return disk_get_hashed_zone_wplug(disk, sector);
++}
++
+ static void disk_free_zone_wplug_rcu(struct rcu_head *rcu_head)
+ {
+ struct blk_zone_wplug *zwplug =
+@@ -505,6 +515,7 @@ static void disk_remove_zone_wplug(struc
+ zwplug->flags |= BLK_ZONE_WPLUG_UNHASHED;
+ spin_lock_irqsave(&disk->zone_wplugs_lock, flags);
+ hlist_del_init_rcu(&zwplug->node);
++ atomic_dec(&disk->nr_zone_wplugs);
+ spin_unlock_irqrestore(&disk->zone_wplugs_lock, flags);
+ disk_put_zone_wplug(zwplug);
+ }
+@@ -594,6 +605,11 @@ static void disk_zone_wplug_abort(struct
+ {
+ struct bio *bio;
+
++ if (bio_list_empty(&zwplug->bio_list))
++ return;
++
++ pr_warn_ratelimited("%s: zone %u: Aborting plugged BIOs\n",
++ zwplug->disk->disk_name, zwplug->zone_no);
+ while ((bio = bio_list_pop(&zwplug->bio_list)))
+ blk_zone_wplug_bio_io_error(zwplug, bio);
+ }
+@@ -1042,6 +1058,47 @@ plug:
+ return true;
+ }
+
++static void blk_zone_wplug_handle_native_zone_append(struct bio *bio)
++{
++ struct gendisk *disk = bio->bi_bdev->bd_disk;
++ struct blk_zone_wplug *zwplug;
++ unsigned long flags;
++
++ /*
++ * We have native support for zone append operations, so we are not
++ * going to handle @bio through plugging. However, we may already have a
++ * zone write plug for the target zone if that zone was previously
++ * partially written using regular writes. In such case, we risk leaving
++ * the plug in the disk hash table if the zone is fully written using
++ * zone append operations. Avoid this by removing the zone write plug.
++ */
++ zwplug = disk_get_zone_wplug(disk, bio->bi_iter.bi_sector);
++ if (likely(!zwplug))
++ return;
++
++ spin_lock_irqsave(&zwplug->lock, flags);
++
++ /*
++ * We are about to remove the zone write plug. But if the user
++ * (mistakenly) has issued regular writes together with native zone
++ * append, we must aborts the writes as otherwise the plugged BIOs would
++ * not be executed by the plug BIO work as disk_get_zone_wplug() will
++ * return NULL after the plug is removed. Aborting the plugged write
++ * BIOs is consistent with the fact that these writes will most likely
++ * fail anyway as there is no ordering guarantees between zone append
++ * operations and regular write operations.
++ */
++ if (!bio_list_empty(&zwplug->bio_list)) {
++ pr_warn_ratelimited("%s: zone %u: Invalid mix of zone append and regular writes\n",
++ disk->disk_name, zwplug->zone_no);
++ disk_zone_wplug_abort(zwplug);
++ }
++ disk_remove_zone_wplug(disk, zwplug);
++ spin_unlock_irqrestore(&zwplug->lock, flags);
++
++ disk_put_zone_wplug(zwplug);
++}
++
+ /**
+ * blk_zone_plug_bio - Handle a zone write BIO with zone write plugging
+ * @bio: The BIO being submitted
+@@ -1098,8 +1155,10 @@ bool blk_zone_plug_bio(struct bio *bio,
+ */
+ switch (bio_op(bio)) {
+ case REQ_OP_ZONE_APPEND:
+- if (!bdev_emulates_zone_append(bdev))
++ if (!bdev_emulates_zone_append(bdev)) {
++ blk_zone_wplug_handle_native_zone_append(bio);
+ return false;
++ }
+ fallthrough;
+ case REQ_OP_WRITE:
+ case REQ_OP_WRITE_ZEROES:
+@@ -1286,6 +1345,7 @@ static int disk_alloc_zone_resources(str
+ {
+ unsigned int i;
+
++ atomic_set(&disk->nr_zone_wplugs, 0);
+ disk->zone_wplugs_hash_bits =
+ min(ilog2(pool_size) + 1, BLK_ZONE_WPLUG_MAX_HASH_BITS);
+
+@@ -1340,6 +1400,7 @@ static void disk_destroy_zone_wplugs_has
+ }
+ }
+
++ WARN_ON_ONCE(atomic_read(&disk->nr_zone_wplugs));
+ kfree(disk->zone_wplugs_hash);
+ disk->zone_wplugs_hash = NULL;
+ disk->zone_wplugs_hash_bits = 0;
+@@ -1552,11 +1613,12 @@ static int blk_revalidate_seq_zone(struc
+ }
+
+ /*
+- * We need to track the write pointer of all zones that are not
+- * empty nor full. So make sure we have a zone write plug for
+- * such zone if the device has a zone write plug hash table.
++ * If the device needs zone append emulation, we need to track the
++ * write pointer of all zones that are not empty nor full. So make sure
++ * we have a zone write plug for such zone if the device has a zone
++ * write plug hash table.
+ */
+- if (!disk->zone_wplugs_hash)
++ if (!queue_emulates_zone_append(disk->queue) || !disk->zone_wplugs_hash)
+ return 0;
+
+ disk_zone_wplug_sync_wp_offset(disk, zone);
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -196,10 +196,11 @@ struct gendisk {
+ unsigned int zone_capacity;
+ unsigned int last_zone_capacity;
+ unsigned long __rcu *conv_zones_bitmap;
+- unsigned int zone_wplugs_hash_bits;
+- spinlock_t zone_wplugs_lock;
++ unsigned int zone_wplugs_hash_bits;
++ atomic_t nr_zone_wplugs;
++ spinlock_t zone_wplugs_lock;
+ struct mempool_s *zone_wplugs_pool;
+- struct hlist_head *zone_wplugs_hash;
++ struct hlist_head *zone_wplugs_hash;
+ struct workqueue_struct *zone_wplugs_wq;
+ #endif /* CONFIG_BLK_DEV_ZONED */
+
--- /dev/null
+From 15b3b3254d1453a8db038b7d44b311a2d6c71f98 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Sat, 15 Feb 2025 11:11:29 +0000
+Subject: btrfs: do regular iput instead of delayed iput during extent map shrinking
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 15b3b3254d1453a8db038b7d44b311a2d6c71f98 upstream.
+
+The extent map shrinker now runs in the system unbound workqueue and no
+longer in kswapd context so it can directly do an iput() on inodes even
+if that blocks or needs to acquire any lock (we aren't holding any locks
+when requesting the delayed iput from the shrinker). So we don't need to
+add a delayed iput, wake up the cleaner and delegate the iput() to the
+cleaner, which also adds extra contention on the spinlock that protects
+the delayed iputs list.
+
+Reported-by: Ivan Shapovalov <intelfx@intelfx.name>
+Tested-by: Ivan Shapovalov <intelfx@intelfx.name>
+Link: https://lore.kernel.org/linux-btrfs/0414d690ac5680d0d77dfc930606cdc36e42e12f.camel@intelfx.name/
+CC: stable@vger.kernel.org # 6.12+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent_map.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent_map.c
++++ b/fs/btrfs/extent_map.c
+@@ -1256,7 +1256,7 @@ static long btrfs_scan_root(struct btrfs
+
+ min_ino = btrfs_ino(inode) + 1;
+ fs_info->em_shrinker_last_ino = btrfs_ino(inode);
+- btrfs_add_delayed_iput(inode);
++ iput(&inode->vfs_inode);
+
+ if (ctx->scanned >= ctx->nr_to_scan ||
+ btrfs_fs_closing(inode->root->fs_info))
--- /dev/null
+From efa11fd269c139e29b71ec21bc9c9c0063fde40d Mon Sep 17 00:00:00 2001
+From: Qu Wenruo <wqu@suse.com>
+Date: Wed, 19 Feb 2025 09:06:33 +1030
+Subject: btrfs: fix data overwriting bug during buffered write when block size < page size
+
+From: Qu Wenruo <wqu@suse.com>
+
+commit efa11fd269c139e29b71ec21bc9c9c0063fde40d upstream.
+
+[BUG]
+When running generic/418 with a btrfs whose block size < page size
+(subpage cases), it always fails.
+
+And the following minimal reproducer is more than enough to trigger it
+reliably:
+
+workload()
+{
+ mkfs.btrfs -s 4k -f $dev > /dev/null
+ dmesg -C
+ mount $dev $mnt
+ $fsstree_dir/src/dio-invalidate-cache -r -b 4096 -n 3 -i 1 -f $mnt/diotest
+ ret=$?
+ umount $mnt
+ stop_trace
+ if [ $ret -ne 0 ]; then
+ fail
+ fi
+}
+
+for (( i = 0; i < 1024; i++)); do
+ echo "=== $i/$runtime ==="
+ workload
+done
+
+[CAUSE]
+With extra trace printk added to the following functions:
+- btrfs_buffered_write()
+ * Which folio is touched
+ * The file offset (start) where the buffered write is at
+ * How many bytes are copied
+ * The content of the write (the first 2 bytes)
+
+- submit_one_sector()
+ * Which folio is touched
+ * The position inside the folio
+ * The content of the page cache (the first 2 bytes)
+
+- pagecache_isize_extended()
+ * The parameters of the function itself
+ * The parameters of the folio_zero_range()
+
+Which are enough to show the problem:
+
+ 22.158114: btrfs_buffered_write: folio pos=0 start=0 copied=4096 content=0x0101
+ 22.158161: submit_one_sector: r/i=5/257 folio=0 pos=0 content=0x0101
+ 22.158609: btrfs_buffered_write: folio pos=0 start=4096 copied=4096 content=0x0101
+ 22.158634: btrfs_buffered_write: folio pos=0 start=8192 copied=4096 content=0x0101
+ 22.158650: pagecache_isize_extended: folio=0 from=4096 to=8192 bsize=4096 zero off=4096 len=8192
+ 22.158682: submit_one_sector: r/i=5/257 folio=0 pos=4096 content=0x0000
+ 22.158686: submit_one_sector: r/i=5/257 folio=0 pos=8192 content=0x0101
+
+The tool dio-invalidate-cache will start 3 threads, each doing a buffered
+write with 0x01 at offset 0, 4096 and 8192, do a fsync, then do a direct read,
+and compare the read buffer with the write buffer.
+
+Note that all 3 btrfs_buffered_write() are writing the correct 0x01 into
+the page cache.
+
+But at submit_one_sector(), at file offset 4096, the content is zeroed
+out, by pagecache_isize_extended().
+
+The race happens like this:
+ Thread A is writing into range [4K, 8K).
+ Thread B is writing into range [8K, 12k).
+
+ Thread A | Thread B
+-------------------------------------+------------------------------------
+btrfs_buffered_write() | btrfs_buffered_write()
+|- old_isize = 4K; | |- old_isize = 4096;
+|- btrfs_inode_lock() | |
+|- write into folio range [4K, 8K) | |
+|- pagecache_isize_extended() | |
+| extend isize from 4096 to 8192 | |
+| no folio_zero_range() called | |
+|- btrfs_inode_lock() | |
+ | |- btrfs_inode_lock()
+ | |- write into folio range [8K, 12K)
+ | |- pagecache_isize_extended()
+ | | calling folio_zero_range(4K, 8K)
+ | | This is caused by the old_isize is
+ | | grabbed too early, without any
+ | | inode lock.
+ | |- btrfs_inode_unlock()
+
+The @old_isize is grabbed without inode lock, causing race between two
+buffered write threads and making pagecache_isize_extended() to zero
+range which is still containing cached data.
+
+And this is only affecting subpage btrfs, because for regular blocksize
+== page size case, the function pagecache_isize_extended() will do
+nothing if the block size >= page size.
+
+[FIX]
+Grab the old i_size while holding the inode lock.
+This means each buffered write thread will have a stable view of the
+old inode size, thus avoid the above race.
+
+CC: stable@vger.kernel.org # 5.15+
+Fixes: 5e8b9ef30392 ("btrfs: move pos increment and pagecache extension to btrfs_buffered_write")
+Reviewed-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/file.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1127,7 +1127,7 @@ ssize_t btrfs_buffered_write(struct kioc
+ u64 lockend;
+ size_t num_written = 0;
+ ssize_t ret;
+- loff_t old_isize = i_size_read(inode);
++ loff_t old_isize;
+ unsigned int ilock_flags = 0;
+ const bool nowait = (iocb->ki_flags & IOCB_NOWAIT);
+ unsigned int bdp_flags = (nowait ? BDP_ASYNC : 0);
+@@ -1140,6 +1140,13 @@ ssize_t btrfs_buffered_write(struct kioc
+ if (ret < 0)
+ return ret;
+
++ /*
++ * We can only trust the isize with inode lock held, or it can race with
++ * other buffered writes and cause incorrect call of
++ * pagecache_isize_extended() to overwrite existing data.
++ */
++ old_isize = i_size_read(inode);
++
+ ret = generic_write_checks(iocb, i);
+ if (ret <= 0)
+ goto out;
--- /dev/null
+From 59f37036bb7ab3d554c24abc856aabca01126414 Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Sat, 15 Feb 2025 11:36:15 +0000
+Subject: btrfs: fix use-after-free on inode when scanning root during em shrinking
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit 59f37036bb7ab3d554c24abc856aabca01126414 upstream.
+
+At btrfs_scan_root() we are accessing the inode's root (and fs_info) in a
+call to btrfs_fs_closing() after we have scheduled the inode for a delayed
+iput, and that can result in a use-after-free on the inode in case the
+cleaner kthread does the iput before we dereference the inode in the call
+to btrfs_fs_closing().
+
+Fix this by using the fs_info stored already in a local variable instead
+of doing inode->root->fs_info.
+
+Fixes: 102044384056 ("btrfs: make the extent map shrinker run asynchronously as a work queue job")
+CC: stable@vger.kernel.org # 6.13+
+Tested-by: Ivan Shapovalov <intelfx@intelfx.name>
+Link: https://lore.kernel.org/linux-btrfs/0414d690ac5680d0d77dfc930606cdc36e42e12f.camel@intelfx.name/
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent_map.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/btrfs/extent_map.c
++++ b/fs/btrfs/extent_map.c
+@@ -1258,8 +1258,7 @@ static long btrfs_scan_root(struct btrfs
+ fs_info->em_shrinker_last_ino = btrfs_ino(inode);
+ iput(&inode->vfs_inode);
+
+- if (ctx->scanned >= ctx->nr_to_scan ||
+- btrfs_fs_closing(inode->root->fs_info))
++ if (ctx->scanned >= ctx->nr_to_scan || btrfs_fs_closing(fs_info))
+ break;
+
+ cond_resched();
--- /dev/null
+From c6c9c4d56483d941f567eb921434c25fc6086dfa Mon Sep 17 00:00:00 2001
+From: Filipe Manana <fdmanana@suse.com>
+Date: Sat, 15 Feb 2025 11:04:15 +0000
+Subject: btrfs: skip inodes without loaded extent maps when shrinking extent maps
+
+From: Filipe Manana <fdmanana@suse.com>
+
+commit c6c9c4d56483d941f567eb921434c25fc6086dfa upstream.
+
+If there are inodes that don't have any loaded extent maps, we end up
+grabbing a reference on them and later adding a delayed iput, which wakes
+up the cleaner and makes it do unnecessary work. This is common when for
+example the inodes were open only to run stat(2) or all their extent maps
+were already released through the folio release callback
+(btrfs_release_folio()) or released by a previous run of the shrinker, or
+directories which never have extent maps.
+
+Reported-by: Ivan Shapovalov <intelfx@intelfx.name>
+Tested-by: Ivan Shapovalov <intelfx@intelfx.name>
+Link: https://lore.kernel.org/linux-btrfs/0414d690ac5680d0d77dfc930606cdc36e42e12f.camel@intelfx.name/
+CC: stable@vger.kernel.org # 6.13+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/extent_map.c | 78 ++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 57 insertions(+), 21 deletions(-)
+
+--- a/fs/btrfs/extent_map.c
++++ b/fs/btrfs/extent_map.c
+@@ -1128,6 +1128,8 @@ static long btrfs_scan_inode(struct btrf
+ long nr_dropped = 0;
+ struct rb_node *node;
+
++ lockdep_assert_held_write(&tree->lock);
++
+ /*
+ * Take the mmap lock so that we serialize with the inode logging phase
+ * of fsync because we may need to set the full sync flag on the inode,
+@@ -1139,28 +1141,12 @@ static long btrfs_scan_inode(struct btrf
+ * to find new extents, which may not be there yet because ordered
+ * extents haven't completed yet.
+ *
+- * We also do a try lock because otherwise we could deadlock. This is
+- * because the shrinker for this filesystem may be invoked while we are
+- * in a path that is holding the mmap lock in write mode. For example in
+- * a reflink operation while COWing an extent buffer, when allocating
+- * pages for a new extent buffer and under memory pressure, the shrinker
+- * may be invoked, and therefore we would deadlock by attempting to read
+- * lock the mmap lock while we are holding already a write lock on it.
++ * We also do a try lock because we don't want to block for too long and
++ * we are holding the extent map tree's lock in write mode.
+ */
+ if (!down_read_trylock(&inode->i_mmap_lock))
+ return 0;
+
+- /*
+- * We want to be fast so if the lock is busy we don't want to spend time
+- * waiting for it - either some task is about to do IO for the inode or
+- * we may have another task shrinking extent maps, here in this code, so
+- * skip this inode.
+- */
+- if (!write_trylock(&tree->lock)) {
+- up_read(&inode->i_mmap_lock);
+- return 0;
+- }
+-
+ node = rb_first(&tree->root);
+ while (node) {
+ struct rb_node *next = rb_next(node);
+@@ -1201,12 +1187,61 @@ next:
+ break;
+ node = next;
+ }
+- write_unlock(&tree->lock);
+ up_read(&inode->i_mmap_lock);
+
+ return nr_dropped;
+ }
+
++static struct btrfs_inode *find_first_inode_to_shrink(struct btrfs_root *root,
++ u64 min_ino)
++{
++ struct btrfs_inode *inode;
++ unsigned long from = min_ino;
++
++ xa_lock(&root->inodes);
++ while (true) {
++ struct extent_map_tree *tree;
++
++ inode = xa_find(&root->inodes, &from, ULONG_MAX, XA_PRESENT);
++ if (!inode)
++ break;
++
++ tree = &inode->extent_tree;
++
++ /*
++ * We want to be fast so if the lock is busy we don't want to
++ * spend time waiting for it (some task is about to do IO for
++ * the inode).
++ */
++ if (!write_trylock(&tree->lock))
++ goto next;
++
++ /*
++ * Skip inode if it doesn't have loaded extent maps, so we avoid
++ * getting a reference and doing an iput later. This includes
++ * cases like files that were opened for things like stat(2), or
++ * files with all extent maps previously released through the
++ * release folio callback (btrfs_release_folio()) or released in
++ * a previous run, or directories which never have extent maps.
++ */
++ if (RB_EMPTY_ROOT(&tree->root)) {
++ write_unlock(&tree->lock);
++ goto next;
++ }
++
++ if (igrab(&inode->vfs_inode))
++ break;
++
++ write_unlock(&tree->lock);
++next:
++ from = btrfs_ino(inode) + 1;
++ cond_resched_lock(&root->inodes.xa_lock);
++ }
++ xa_unlock(&root->inodes);
++
++ return inode;
++}
++
+ static long btrfs_scan_root(struct btrfs_root *root, struct btrfs_em_shrink_ctx *ctx)
+ {
+ struct btrfs_fs_info *fs_info = root->fs_info;
+@@ -1214,9 +1249,10 @@ static long btrfs_scan_root(struct btrfs
+ long nr_dropped = 0;
+ u64 min_ino = fs_info->em_shrinker_last_ino + 1;
+
+- inode = btrfs_find_first_inode(root, min_ino);
++ inode = find_first_inode_to_shrink(root, min_ino);
+ while (inode) {
+ nr_dropped += btrfs_scan_inode(inode, ctx);
++ write_unlock(&inode->extent_tree.lock);
+
+ min_ino = btrfs_ino(inode) + 1;
+ fs_info->em_shrinker_last_ino = btrfs_ino(inode);
+@@ -1228,7 +1264,7 @@ static long btrfs_scan_root(struct btrfs
+
+ cond_resched();
+
+- inode = btrfs_find_first_inode(root, min_ino);
++ inode = find_first_inode_to_shrink(root, min_ino);
+ }
+
+ if (inode) {
--- /dev/null
+From 7fb39882b20c98a9a393c244c86b56ef6933cff8 Mon Sep 17 00:00:00 2001
+From: Milan Broz <gmazyland@gmail.com>
+Date: Sun, 16 Feb 2025 11:42:09 +0100
+Subject: dm-integrity: Avoid divide by zero in table status in Inline mode
+
+From: Milan Broz <gmazyland@gmail.com>
+
+commit 7fb39882b20c98a9a393c244c86b56ef6933cff8 upstream.
+
+In Inline mode, the journal is unused, and journal_sectors is zero.
+
+Calculating the journal watermark requires dividing by journal_sectors,
+which should be done only if the journal is configured.
+
+Otherwise, a simple table query (dmsetup table) can cause OOPS.
+
+This bug did not show on some systems, perhaps only due to
+compiler optimization.
+
+On my 32-bit testing machine, this reliably crashes with the following:
+
+ : Oops: divide error: 0000 [#1] PREEMPT SMP
+ : CPU: 0 UID: 0 PID: 2450 Comm: dmsetup Not tainted 6.14.0-rc2+ #959
+ : EIP: dm_integrity_status+0x2f8/0xab0 [dm_integrity]
+ ...
+
+Signed-off-by: Milan Broz <gmazyland@gmail.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Fixes: fb0987682c62 ("dm-integrity: introduce the Inline mode")
+Cc: stable@vger.kernel.org # 6.11+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-integrity.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -3790,10 +3790,6 @@ static void dm_integrity_status(struct d
+ break;
+
+ case STATUSTYPE_TABLE: {
+- __u64 watermark_percentage = (__u64)(ic->journal_entries - ic->free_sectors_threshold) * 100;
+-
+- watermark_percentage += ic->journal_entries / 2;
+- do_div(watermark_percentage, ic->journal_entries);
+ arg_count = 3;
+ arg_count += !!ic->meta_dev;
+ arg_count += ic->sectors_per_block != 1;
+@@ -3826,6 +3822,10 @@ static void dm_integrity_status(struct d
+ DMEMIT(" interleave_sectors:%u", 1U << ic->sb->log2_interleave_sectors);
+ DMEMIT(" buffer_sectors:%u", 1U << ic->log2_buffer_sectors);
+ if (ic->mode == 'J') {
++ __u64 watermark_percentage = (__u64)(ic->journal_entries - ic->free_sectors_threshold) * 100;
++
++ watermark_percentage += ic->journal_entries / 2;
++ do_div(watermark_percentage, ic->journal_entries);
+ DMEMIT(" journal_watermark:%u", (unsigned int)watermark_percentage);
+ DMEMIT(" commit_time:%u", ic->autocommit_msec);
+ }
--- /dev/null
+From 36e1b81f599a093ec7477e4593e110104adcfb96 Mon Sep 17 00:00:00 2001
+From: Ken Raeburn <raeburn@redhat.com>
+Date: Wed, 19 Feb 2025 17:56:00 -0500
+Subject: dm vdo: add missing spin_lock_init
+
+From: Ken Raeburn <raeburn@redhat.com>
+
+commit 36e1b81f599a093ec7477e4593e110104adcfb96 upstream.
+
+Signed-off-by: Ken Raeburn <raeburn@redhat.com>
+Signed-off-by: Matthew Sakai <msakai@redhat.com>
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/md/dm-vdo/dedupe.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/md/dm-vdo/dedupe.c
++++ b/drivers/md/dm-vdo/dedupe.c
+@@ -2178,6 +2178,7 @@ static int initialize_index(struct vdo *
+
+ vdo_set_dedupe_index_timeout_interval(vdo_dedupe_index_timeout_interval);
+ vdo_set_dedupe_index_min_timer_interval(vdo_dedupe_index_min_timer_interval);
++ spin_lock_init(&zones->lock);
+
+ /*
+ * Since we will save up the timeouts that would have been reported but were ratelimited,
--- /dev/null
+From b5f7242e49b927cfe488b369fa552f2eff579ef1 Mon Sep 17 00:00:00 2001
+From: Yilin Chen <Yilin.Chen@amd.com>
+Date: Fri, 7 Feb 2025 15:26:19 -0500
+Subject: drm/amd/display: add a quirk to enable eDP0 on DP1
+
+From: Yilin Chen <Yilin.Chen@amd.com>
+
+commit b5f7242e49b927cfe488b369fa552f2eff579ef1 upstream.
+
+[why]
+some board designs have eDP0 connected to DP1, need a way to enable
+support_edp0_on_dp1 flag, otherwise edp related features cannot work
+
+[how]
+do a dmi check during dm initialization to identify systems that
+require support_edp0_on_dp1. Optimize quirk table with callback
+functions to set quirk entries, retrieve_dmi_info can set quirks
+according to quirk entries
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Signed-off-by: Yilin Chen <Yilin.Chen@amd.com>
+Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit f6d17270d18a6a6753fff046330483d43f8405e4)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 69 +++++++++++++++++++---
+ 1 file changed, 62 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -1617,75 +1617,130 @@ static bool dm_should_disable_stutter(st
+ return false;
+ }
+
+-static const struct dmi_system_id hpd_disconnect_quirk_table[] = {
++struct amdgpu_dm_quirks {
++ bool aux_hpd_discon;
++ bool support_edp0_on_dp1;
++};
++
++static struct amdgpu_dm_quirks quirk_entries = {
++ .aux_hpd_discon = false,
++ .support_edp0_on_dp1 = false
++};
++
++static int edp0_on_dp1_callback(const struct dmi_system_id *id)
++{
++ quirk_entries.support_edp0_on_dp1 = true;
++ return 0;
++}
++
++static int aux_hpd_discon_callback(const struct dmi_system_id *id)
++{
++ quirk_entries.aux_hpd_discon = true;
++ return 0;
++}
++
++static const struct dmi_system_id dmi_quirk_table[] = {
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3660"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3260"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3460"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower Plus 7010"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Tower 7010"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF Plus 7010"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex SFF 7010"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro Plus 7010"),
+ },
+ },
+ {
++ .callback = aux_hpd_discon_callback,
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex Micro 7010"),
+ },
+ },
++ {
++ .callback = edp0_on_dp1_callback,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite mt645 G8 Mobile Thin Client"),
++ },
++ },
++ {
++ .callback = edp0_on_dp1_callback,
++ .matches = {
++ DMI_MATCH(DMI_SYS_VENDOR, "HP"),
++ DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook 665 16 inch G11 Notebook PC"),
++ },
++ },
+ {}
+ /* TODO: refactor this from a fixed table to a dynamic option */
+ };
+
+-static void retrieve_dmi_info(struct amdgpu_display_manager *dm)
++static void retrieve_dmi_info(struct amdgpu_display_manager *dm, struct dc_init_data *init_data)
+ {
+- const struct dmi_system_id *dmi_id;
++ int dmi_id;
++ struct drm_device *dev = dm->ddev;
+
+ dm->aux_hpd_discon_quirk = false;
++ init_data->flags.support_edp0_on_dp1 = false;
++
++ dmi_id = dmi_check_system(dmi_quirk_table);
+
+- dmi_id = dmi_first_match(hpd_disconnect_quirk_table);
+- if (dmi_id) {
++ if (!dmi_id)
++ return;
++
++ if (quirk_entries.aux_hpd_discon) {
+ dm->aux_hpd_discon_quirk = true;
+- DRM_INFO("aux_hpd_discon_quirk attached\n");
++ drm_info(dev, "aux_hpd_discon_quirk attached\n");
++ }
++ if (quirk_entries.support_edp0_on_dp1) {
++ init_data->flags.support_edp0_on_dp1 = true;
++ drm_info(dev, "aux_hpd_discon_quirk attached\n");
+ }
+ }
+
+@@ -1993,7 +2048,7 @@ static int amdgpu_dm_init(struct amdgpu_
+ if (amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 0, 0))
+ init_data.num_virtual_links = 1;
+
+- retrieve_dmi_info(&adev->dm);
++ retrieve_dmi_info(&adev->dm, &init_data);
+
+ if (adev->dm.bb_from_dmub)
+ init_data.bb_from_dmub = adev->dm.bb_from_dmub;
--- /dev/null
+From e8863f8b0316d8ee1e7e5291e8f2f72c91ac967d Mon Sep 17 00:00:00 2001
+From: Tom Chung <chiahsuan.chung@amd.com>
+Date: Thu, 6 Feb 2025 11:31:23 +0800
+Subject: drm/amd/display: Disable PSR-SU on eDP panels
+
+From: Tom Chung <chiahsuan.chung@amd.com>
+
+commit e8863f8b0316d8ee1e7e5291e8f2f72c91ac967d upstream.
+
+[Why]
+PSR-SU may cause some glitching randomly on several panels.
+
+[How]
+Temporarily disable the PSR-SU and fallback to PSR1 for
+all eDP panels.
+
+Link: https://gitlab.freedesktop.org/drm/amd/-/issues/3388
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Sun peng Li <sunpeng.li@amd.com>
+Signed-off-by: Tom Chung <chiahsuan.chung@amd.com>
+Signed-off-by: Roman Li <roman.li@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 6deeefb820d0efb0b36753622fb982d03b37b3ad)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c
+@@ -54,7 +54,8 @@ static bool link_supports_psrsu(struct d
+ if (amdgpu_dc_debug_mask & DC_DISABLE_PSR_SU)
+ return false;
+
+- return dc_dmub_check_min_version(dc->ctx->dmub_srv->dmub);
++ /* Temporarily disable PSR-SU to avoid glitches */
++ return false;
+ }
+
+ /*
--- /dev/null
+From 4de141b8b1b7991b607f77e5f4580e1c67c24717 Mon Sep 17 00:00:00 2001
+From: Roman Li <Roman.Li@amd.com>
+Date: Wed, 12 Feb 2025 14:49:36 -0500
+Subject: drm/amd/display: Fix HPD after gpu reset
+
+From: Roman Li <Roman.Li@amd.com>
+
+commit 4de141b8b1b7991b607f77e5f4580e1c67c24717 upstream.
+
+[Why]
+DC is not using amdgpu_irq_get/put to manage the HPD interrupt refcounts.
+So when amdgpu_irq_gpu_reset_resume_helper() reprograms all of the IRQs,
+HPD gets disabled.
+
+[How]
+Use amdgpu_irq_get/put() for HPD init/fini in DM in order to sync refcounts
+
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
+Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Roman Li <Roman.Li@amd.com>
+Signed-off-by: Zaeem Mohamed <zaeem.mohamed@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit f3dde2ff7fcaacd77884502e8f572f2328e9c745)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c
+@@ -894,6 +894,7 @@ void amdgpu_dm_hpd_init(struct amdgpu_de
+ struct drm_device *dev = adev_to_drm(adev);
+ struct drm_connector *connector;
+ struct drm_connector_list_iter iter;
++ int i;
+
+ drm_connector_list_iter_begin(dev, &iter);
+ drm_for_each_connector_iter(connector, &iter) {
+@@ -920,6 +921,12 @@ void amdgpu_dm_hpd_init(struct amdgpu_de
+ }
+ }
+ drm_connector_list_iter_end(&iter);
++
++ /* Update reference counts for HPDs */
++ for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) {
++ if (amdgpu_irq_get(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1))
++ drm_err(dev, "DM_IRQ: Failed get HPD for source=%d)!\n", i);
++ }
+ }
+
+ /**
+@@ -935,6 +942,7 @@ void amdgpu_dm_hpd_fini(struct amdgpu_de
+ struct drm_device *dev = adev_to_drm(adev);
+ struct drm_connector *connector;
+ struct drm_connector_list_iter iter;
++ int i;
+
+ drm_connector_list_iter_begin(dev, &iter);
+ drm_for_each_connector_iter(connector, &iter) {
+@@ -960,4 +968,10 @@ void amdgpu_dm_hpd_fini(struct amdgpu_de
+ }
+ }
+ drm_connector_list_iter_end(&iter);
++
++ /* Update reference counts for HPDs */
++ for (i = DC_IRQ_SOURCE_HPD1; i <= adev->mode_info.num_hpd; i++) {
++ if (amdgpu_irq_put(adev, &adev->hpd_irq, i - DC_IRQ_SOURCE_HPD1))
++ drm_err(dev, "DM_IRQ: Failed put HPD for source=%d!\n", i);
++ }
+ }
--- /dev/null
+From 099bffc7cadff40bfab1517c3461c53a7a38a0d7 Mon Sep 17 00:00:00 2001
+From: Alex Deucher <alexander.deucher@amd.com>
+Date: Mon, 17 Feb 2025 10:55:05 -0500
+Subject: drm/amdgpu: disable BAR resize on Dell G5 SE
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+commit 099bffc7cadff40bfab1517c3461c53a7a38a0d7 upstream.
+
+There was a quirk added to add a workaround for a Sapphire
+RX 5600 XT Pulse that didn't allow BAR resizing. However,
+the quirk caused a regression with runtime pm on Dell laptops
+using those chips, rather than narrowing the scope of the
+resizing quirk, add a quirk to prevent amdgpu from resizing
+the BAR on those Dell platforms unless runtime pm is disabled.
+
+v2: update commit message, add runpm check
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/1707
+Fixes: 907830b0fc9e ("PCI: Add a REBAR size quirk for Sapphire RX 5600 XT Pulse")
+Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 5235053f443cef4210606e5fb71f99b915a9723d)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+@@ -1635,6 +1635,13 @@ int amdgpu_device_resize_fb_bar(struct a
+ if (amdgpu_sriov_vf(adev))
+ return 0;
+
++ /* resizing on Dell G5 SE platforms causes problems with runtime pm */
++ if ((amdgpu_runtime_pm != 0) &&
++ adev->pdev->vendor == PCI_VENDOR_ID_ATI &&
++ adev->pdev->device == 0x731f &&
++ adev->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL)
++ return 0;
++
+ /* PCI_EXT_CAP_ID_VNDR extended capability is located at 0x100 */
+ if (!pci_find_ext_capability(adev->pdev, PCI_EXT_CAP_ID_VNDR))
+ DRM_WARN("System can't access extended configuration space, please check!!\n");
--- /dev/null
+From d3c7059b6a8600fc62cd863f1ea203b8675e63e1 Mon Sep 17 00:00:00 2001
+From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+Date: Thu, 20 Feb 2025 14:41:59 +0100
+Subject: drm/amdgpu: init return value in amdgpu_ttm_clear_buffer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+
+commit d3c7059b6a8600fc62cd863f1ea203b8675e63e1 upstream.
+
+Otherwise an uninitialized value can be returned if
+amdgpu_res_cleared returns true for all regions.
+
+Possibly closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3812
+
+Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality")
+Signed-off-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
+Acked-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 7c62aacc3b452f73a1284198c81551035fac6d71)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -2280,7 +2280,7 @@ int amdgpu_ttm_clear_buffer(struct amdgp
+ struct amdgpu_ring *ring = adev->mman.buffer_funcs_ring;
+ struct amdgpu_res_cursor cursor;
+ u64 addr;
+- int r;
++ int r = 0;
+
+ if (!adev->mman.buffer_funcs_enabled)
+ return -EINVAL;
--- /dev/null
+From 3502ab5022bb5ef1edd063bdb6465a8bf3b46e66 Mon Sep 17 00:00:00 2001
+From: David Yat Sin <David.YatSin@amd.com>
+Date: Wed, 19 Feb 2025 17:34:38 -0500
+Subject: drm/amdkfd: Preserve cp_hqd_pq_control on update_mqd
+
+From: David Yat Sin <David.YatSin@amd.com>
+
+commit 3502ab5022bb5ef1edd063bdb6465a8bf3b46e66 upstream.
+
+When userspace applications call AMDKFD_IOC_UPDATE_QUEUE. Preserve
+bitfields that do not need to be modified as they contain flags to
+track queue states that are used by CP FW.
+
+Signed-off-by: David Yat Sin <David.YatSin@amd.com>
+Reviewed-by: Jay Cornwall <jay.cornwall@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+(cherry picked from commit 8150827990b709ab5a40c46c30d21b7f7b9e9440)
+Cc: stable@vger.kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c | 6 ++++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c | 5 +++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c | 5 +++--
+ drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c | 5 ++++-
+ 4 files changed, 14 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c
+@@ -107,6 +107,8 @@ static void init_mqd(struct mqd_manager
+ m->cp_hqd_persistent_state = CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK |
+ 0x53 << CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT;
+
++ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+ m->cp_mqd_control = 1 << CP_MQD_CONTROL__PRIV_STATE__SHIFT;
+
+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
+@@ -167,10 +169,10 @@ static void update_mqd(struct mqd_manage
+
+ m = get_mqd(mqd);
+
+- m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control &= ~CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK;
+ m->cp_hqd_pq_control |=
+ ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
+- m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
++
+ pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+
+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c
+@@ -154,6 +154,8 @@ static void init_mqd(struct mqd_manager
+ m->cp_hqd_persistent_state = CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK |
+ 0x55 << CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT;
+
++ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+ m->cp_mqd_control = 1 << CP_MQD_CONTROL__PRIV_STATE__SHIFT;
+
+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
+@@ -221,10 +223,9 @@ static void update_mqd(struct mqd_manage
+
+ m = get_mqd(mqd);
+
+- m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control &= ~CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK;
+ m->cp_hqd_pq_control |=
+ ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
+- m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+ pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+
+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c
+@@ -121,6 +121,8 @@ static void init_mqd(struct mqd_manager
+ m->cp_hqd_persistent_state = CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK |
+ 0x55 << CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT;
+
++ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+ m->cp_mqd_control = 1 << CP_MQD_CONTROL__PRIV_STATE__SHIFT;
+
+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
+@@ -184,10 +186,9 @@ static void update_mqd(struct mqd_manage
+
+ m = get_mqd(mqd);
+
+- m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control &= ~CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK;
+ m->cp_hqd_pq_control |=
+ ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1;
+- m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
+ pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+
+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c
+@@ -182,6 +182,9 @@ static void init_mqd(struct mqd_manager
+ m->cp_hqd_persistent_state = CP_HQD_PERSISTENT_STATE__PRELOAD_REQ_MASK |
+ 0x53 << CP_HQD_PERSISTENT_STATE__PRELOAD_SIZE__SHIFT;
+
++ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK;
++
+ m->cp_mqd_control = 1 << CP_MQD_CONTROL__PRIV_STATE__SHIFT;
+
+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
+@@ -244,7 +247,7 @@ static void update_mqd(struct mqd_manage
+
+ m = get_mqd(mqd);
+
+- m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT;
++ m->cp_hqd_pq_control &= ~CP_HQD_PQ_CONTROL__QUEUE_SIZE_MASK;
+ m->cp_hqd_pq_control |= order_base_2(q->queue_size / 4) - 1;
+ pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control);
+
--- /dev/null
+From 3603996432997f7c88da37a97062a46cda01ac9d Mon Sep 17 00:00:00 2001
+From: Thomas Zimmermann <tzimmermann@suse.de>
+Date: Wed, 11 Dec 2024 10:06:28 +0100
+Subject: drm/fbdev-dma: Add shadow buffering for deferred I/O
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+commit 3603996432997f7c88da37a97062a46cda01ac9d upstream.
+
+DMA areas are not necessarily backed by struct page, so we cannot
+rely on it for deferred I/O. Allocate a shadow buffer for drivers
+that require deferred I/O and use it as framebuffer memory.
+
+Fixes driver errors about being "Unable to handle kernel NULL pointer
+dereference at virtual address" or "Unable to handle kernel paging
+request at virtual address".
+
+The patch splits drm_fbdev_dma_driver_fbdev_probe() in an initial
+allocation, which creates the DMA-backed buffer object, and a tail
+that sets up the fbdev data structures. There is a tail function for
+direct memory mappings and a tail function for deferred I/O with
+the shadow buffer.
+
+It is no longer possible to use deferred I/O without shadow buffer.
+It can be re-added if there exists a reliably test for usable struct
+page in the allocated DMA-backed buffer object.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reported-by: Nuno Gonçalves <nunojpg@gmail.com>
+CLoses: https://lore.kernel.org/dri-devel/CAEXMXLR55DziAMbv_+2hmLeH-jP96pmit6nhs6siB22cpQFr9w@mail.gmail.com/
+Tested-by: Nuno Gonçalves <nunojpg@gmail.com>
+Fixes: 5ab91447aa13 ("drm/tiny/ili9225: Use fbdev-dma")
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: <stable@vger.kernel.org> # v6.11+
+Reviewed-by: Simona Vetter <simona.vetter@ffwll.ch>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20241211090643.74250-1-tzimmermann@suse.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/drm_fbdev_dma.c | 217 ++++++++++++++++++++++++++++------------
+ 1 file changed, 155 insertions(+), 62 deletions(-)
+
+--- a/drivers/gpu/drm/drm_fbdev_dma.c
++++ b/drivers/gpu/drm/drm_fbdev_dma.c
+@@ -1,6 +1,7 @@
+ // SPDX-License-Identifier: MIT
+
+ #include <linux/fb.h>
++#include <linux/vmalloc.h>
+
+ #include <drm/drm_drv.h>
+ #include <drm/drm_fbdev_dma.h>
+@@ -70,37 +71,102 @@ static const struct fb_ops drm_fbdev_dma
+ .fb_destroy = drm_fbdev_dma_fb_destroy,
+ };
+
+-FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(drm_fbdev_dma,
++FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(drm_fbdev_dma_shadowed,
+ drm_fb_helper_damage_range,
+ drm_fb_helper_damage_area);
+
+-static int drm_fbdev_dma_deferred_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
++static void drm_fbdev_dma_shadowed_fb_destroy(struct fb_info *info)
+ {
+ struct drm_fb_helper *fb_helper = info->par;
+- struct drm_framebuffer *fb = fb_helper->fb;
+- struct drm_gem_dma_object *dma = drm_fb_dma_get_gem_obj(fb, 0);
++ void *shadow = info->screen_buffer;
++
++ if (!fb_helper->dev)
++ return;
+
+- if (!dma->map_noncoherent)
+- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
++ if (info->fbdefio)
++ fb_deferred_io_cleanup(info);
++ drm_fb_helper_fini(fb_helper);
++ vfree(shadow);
+
+- return fb_deferred_io_mmap(info, vma);
++ drm_client_buffer_vunmap(fb_helper->buffer);
++ drm_client_framebuffer_delete(fb_helper->buffer);
++ drm_client_release(&fb_helper->client);
++ drm_fb_helper_unprepare(fb_helper);
++ kfree(fb_helper);
+ }
+
+-static const struct fb_ops drm_fbdev_dma_deferred_fb_ops = {
++static const struct fb_ops drm_fbdev_dma_shadowed_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = drm_fbdev_dma_fb_open,
+ .fb_release = drm_fbdev_dma_fb_release,
+- __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_dma),
++ FB_DEFAULT_DEFERRED_OPS(drm_fbdev_dma_shadowed),
+ DRM_FB_HELPER_DEFAULT_OPS,
+- __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_dma),
+- .fb_mmap = drm_fbdev_dma_deferred_fb_mmap,
+- .fb_destroy = drm_fbdev_dma_fb_destroy,
++ .fb_destroy = drm_fbdev_dma_shadowed_fb_destroy,
+ };
+
+ /*
+ * struct drm_fb_helper
+ */
+
++static void drm_fbdev_dma_damage_blit_real(struct drm_fb_helper *fb_helper,
++ struct drm_clip_rect *clip,
++ struct iosys_map *dst)
++{
++ struct drm_framebuffer *fb = fb_helper->fb;
++ size_t offset = clip->y1 * fb->pitches[0];
++ size_t len = clip->x2 - clip->x1;
++ unsigned int y;
++ void *src;
++
++ switch (drm_format_info_bpp(fb->format, 0)) {
++ case 1:
++ offset += clip->x1 / 8;
++ len = DIV_ROUND_UP(len + clip->x1 % 8, 8);
++ break;
++ case 2:
++ offset += clip->x1 / 4;
++ len = DIV_ROUND_UP(len + clip->x1 % 4, 4);
++ break;
++ case 4:
++ offset += clip->x1 / 2;
++ len = DIV_ROUND_UP(len + clip->x1 % 2, 2);
++ break;
++ default:
++ offset += clip->x1 * fb->format->cpp[0];
++ len *= fb->format->cpp[0];
++ break;
++ }
++
++ src = fb_helper->info->screen_buffer + offset;
++ iosys_map_incr(dst, offset); /* go to first pixel within clip rect */
++
++ for (y = clip->y1; y < clip->y2; y++) {
++ iosys_map_memcpy_to(dst, 0, src, len);
++ iosys_map_incr(dst, fb->pitches[0]);
++ src += fb->pitches[0];
++ }
++}
++
++static int drm_fbdev_dma_damage_blit(struct drm_fb_helper *fb_helper,
++ struct drm_clip_rect *clip)
++{
++ struct drm_client_buffer *buffer = fb_helper->buffer;
++ struct iosys_map dst;
++
++ /*
++ * For fbdev emulation, we only have to protect against fbdev modeset
++ * operations. Nothing else will involve the client buffer's BO. So it
++ * is sufficient to acquire struct drm_fb_helper.lock here.
++ */
++ mutex_lock(&fb_helper->lock);
++
++ dst = buffer->map;
++ drm_fbdev_dma_damage_blit_real(fb_helper, clip, &dst);
++
++ mutex_unlock(&fb_helper->lock);
++
++ return 0;
++}
+ static int drm_fbdev_dma_helper_fb_dirty(struct drm_fb_helper *helper,
+ struct drm_clip_rect *clip)
+ {
+@@ -112,6 +178,10 @@ static int drm_fbdev_dma_helper_fb_dirty
+ return 0;
+
+ if (helper->fb->funcs->dirty) {
++ ret = drm_fbdev_dma_damage_blit(helper, clip);
++ if (drm_WARN_ONCE(dev, ret, "Damage blitter failed: ret=%d\n", ret))
++ return ret;
++
+ ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+ if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", ret))
+ return ret;
+@@ -128,14 +198,80 @@ static const struct drm_fb_helper_funcs
+ * struct drm_fb_helper
+ */
+
++static int drm_fbdev_dma_driver_fbdev_probe_tail(struct drm_fb_helper *fb_helper,
++ struct drm_fb_helper_surface_size *sizes)
++{
++ struct drm_device *dev = fb_helper->dev;
++ struct drm_client_buffer *buffer = fb_helper->buffer;
++ struct drm_gem_dma_object *dma_obj = to_drm_gem_dma_obj(buffer->gem);
++ struct drm_framebuffer *fb = fb_helper->fb;
++ struct fb_info *info = fb_helper->info;
++ struct iosys_map map = buffer->map;
++
++ info->fbops = &drm_fbdev_dma_fb_ops;
++
++ /* screen */
++ info->flags |= FBINFO_VIRTFB; /* system memory */
++ if (dma_obj->map_noncoherent)
++ info->flags |= FBINFO_READS_FAST; /* signal caching */
++ info->screen_size = sizes->surface_height * fb->pitches[0];
++ info->screen_buffer = map.vaddr;
++ if (!(info->flags & FBINFO_HIDE_SMEM_START)) {
++ if (!drm_WARN_ON(dev, is_vmalloc_addr(info->screen_buffer)))
++ info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
++ }
++ info->fix.smem_len = info->screen_size;
++
++ return 0;
++}
++
++static int drm_fbdev_dma_driver_fbdev_probe_tail_shadowed(struct drm_fb_helper *fb_helper,
++ struct drm_fb_helper_surface_size *sizes)
++{
++ struct drm_client_buffer *buffer = fb_helper->buffer;
++ struct fb_info *info = fb_helper->info;
++ size_t screen_size = buffer->gem->size;
++ void *screen_buffer;
++ int ret;
++
++ /*
++ * Deferred I/O requires struct page for framebuffer memory,
++ * which is not guaranteed for all DMA ranges. We thus create
++ * a shadow buffer in system memory.
++ */
++ screen_buffer = vzalloc(screen_size);
++ if (!screen_buffer)
++ return -ENOMEM;
++
++ info->fbops = &drm_fbdev_dma_shadowed_fb_ops;
++
++ /* screen */
++ info->flags |= FBINFO_VIRTFB; /* system memory */
++ info->flags |= FBINFO_READS_FAST; /* signal caching */
++ info->screen_buffer = screen_buffer;
++ info->fix.smem_len = screen_size;
++
++ fb_helper->fbdefio.delay = HZ / 20;
++ fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
++
++ info->fbdefio = &fb_helper->fbdefio;
++ ret = fb_deferred_io_init(info);
++ if (ret)
++ goto err_vfree;
++
++ return 0;
++
++err_vfree:
++ vfree(screen_buffer);
++ return ret;
++}
++
+ int drm_fbdev_dma_driver_fbdev_probe(struct drm_fb_helper *fb_helper,
+ struct drm_fb_helper_surface_size *sizes)
+ {
+ struct drm_client_dev *client = &fb_helper->client;
+ struct drm_device *dev = fb_helper->dev;
+- bool use_deferred_io = false;
+ struct drm_client_buffer *buffer;
+- struct drm_gem_dma_object *dma_obj;
+ struct drm_framebuffer *fb;
+ struct fb_info *info;
+ u32 format;
+@@ -152,19 +288,9 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+ sizes->surface_height, format);
+ if (IS_ERR(buffer))
+ return PTR_ERR(buffer);
+- dma_obj = to_drm_gem_dma_obj(buffer->gem);
+
+ fb = buffer->fb;
+
+- /*
+- * Deferred I/O requires struct page for framebuffer memory,
+- * which is not guaranteed for all DMA ranges. We thus only
+- * install deferred I/O if we have a framebuffer that requires
+- * it.
+- */
+- if (fb->funcs->dirty)
+- use_deferred_io = true;
+-
+ ret = drm_client_buffer_vmap(buffer, &map);
+ if (ret) {
+ goto err_drm_client_buffer_delete;
+@@ -185,45 +311,12 @@ int drm_fbdev_dma_driver_fbdev_probe(str
+
+ drm_fb_helper_fill_info(info, fb_helper, sizes);
+
+- if (use_deferred_io)
+- info->fbops = &drm_fbdev_dma_deferred_fb_ops;
++ if (fb->funcs->dirty)
++ ret = drm_fbdev_dma_driver_fbdev_probe_tail_shadowed(fb_helper, sizes);
+ else
+- info->fbops = &drm_fbdev_dma_fb_ops;
+-
+- /* screen */
+- info->flags |= FBINFO_VIRTFB; /* system memory */
+- if (dma_obj->map_noncoherent)
+- info->flags |= FBINFO_READS_FAST; /* signal caching */
+- info->screen_size = sizes->surface_height * fb->pitches[0];
+- info->screen_buffer = map.vaddr;
+- if (!(info->flags & FBINFO_HIDE_SMEM_START)) {
+- if (!drm_WARN_ON(dev, is_vmalloc_addr(info->screen_buffer)))
+- info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
+- }
+- info->fix.smem_len = info->screen_size;
+-
+- /*
+- * Only set up deferred I/O if the screen buffer supports
+- * it. If this disagrees with the previous test for ->dirty,
+- * mmap on the /dev/fb file might not work correctly.
+- */
+- if (!is_vmalloc_addr(info->screen_buffer) && info->fix.smem_start) {
+- unsigned long pfn = info->fix.smem_start >> PAGE_SHIFT;
+-
+- if (drm_WARN_ON(dev, !pfn_to_page(pfn)))
+- use_deferred_io = false;
+- }
+-
+- /* deferred I/O */
+- if (use_deferred_io) {
+- fb_helper->fbdefio.delay = HZ / 20;
+- fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+-
+- info->fbdefio = &fb_helper->fbdefio;
+- ret = fb_deferred_io_init(info);
+- if (ret)
+- goto err_drm_fb_helper_release_info;
+- }
++ ret = drm_fbdev_dma_driver_fbdev_probe_tail(fb_helper, sizes);
++ if (ret)
++ goto err_drm_fb_helper_release_info;
+
+ return 0;
+
--- /dev/null
+From f2ba0cf1ca32e075617813de98c826ab55d57f11 Mon Sep 17 00:00:00 2001
+From: Mingcong Bai <jeffbai@aosc.io>
+Date: Tue, 25 Feb 2025 15:31:01 +0800
+Subject: drm/xe/regs: remove a duplicate definition for RING_CTL_SIZE(size)
+
+From: Mingcong Bai <jeffbai@aosc.io>
+
+commit f2ba0cf1ca32e075617813de98c826ab55d57f11 upstream.
+
+Commit b79e8fd954c4 ("drm/xe: Remove dependency on intel_engine_regs.h")
+introduced an internal set of engine registers, however, as part of this
+change, it has also introduced two duplicate `define' lines for
+`RING_CTL_SIZE(size)'. This commit was introduced to the tree in v6.8-rc1.
+
+While this is harmless as the definitions did not change, so no compiler
+warning was observed.
+
+Drop this line anyway for the sake of correctness.
+
+Cc: stable@vger.kernel.org # v6.8-rc1+
+Fixes: b79e8fd954c4 ("drm/xe: Remove dependency on intel_engine_regs.h")
+Signed-off-by: Mingcong Bai <jeffbai@aosc.io>
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250225073104.865230-1-jeffbai@aosc.io
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+(cherry picked from commit 6b68c4542ffecc36087a9e14db8fc990c88bb01b)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/regs/xe_engine_regs.h | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h
++++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h
+@@ -53,7 +53,6 @@
+
+ #define RING_CTL(base) XE_REG((base) + 0x3c)
+ #define RING_CTL_SIZE(size) ((size) - PAGE_SIZE) /* in bytes -> pages */
+-#define RING_CTL_SIZE(size) ((size) - PAGE_SIZE) /* in bytes -> pages */
+
+ #define RING_START_UDW(base) XE_REG((base) + 0x48)
+
--- /dev/null
+From a9f4fa3a7efa65615ff7db13023ac84516e99e21 Mon Sep 17 00:00:00 2001
+From: Matthew Auld <matthew.auld@intel.com>
+Date: Fri, 21 Feb 2025 14:38:42 +0000
+Subject: drm/xe/userptr: fix EFAULT handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Auld <matthew.auld@intel.com>
+
+commit a9f4fa3a7efa65615ff7db13023ac84516e99e21 upstream.
+
+Currently we treat EFAULT from hmm_range_fault() as a non-fatal error
+when called from xe_vm_userptr_pin() with the idea that we want to avoid
+killing the entire vm and chucking an error, under the assumption that
+the user just did an unmap or something, and has no intention of
+actually touching that memory from the GPU. At this point we have
+already zapped the PTEs so any access should generate a page fault, and
+if the pin fails there also it will then become fatal.
+
+However it looks like it's possible for the userptr vma to still be on
+the rebind list in preempt_rebind_work_func(), if we had to retry the
+pin again due to something happening in the caller before we did the
+rebind step, but in the meantime needing to re-validate the userptr and
+this time hitting the EFAULT.
+
+This explains an internal user report of hitting:
+
+[ 191.738349] WARNING: CPU: 1 PID: 157 at drivers/gpu/drm/xe/xe_res_cursor.h:158 xe_pt_stage_bind.constprop.0+0x60a/0x6b0 [xe]
+[ 191.738551] Workqueue: xe-ordered-wq preempt_rebind_work_func [xe]
+[ 191.738616] RIP: 0010:xe_pt_stage_bind.constprop.0+0x60a/0x6b0 [xe]
+[ 191.738690] Call Trace:
+[ 191.738692] <TASK>
+[ 191.738694] ? show_regs+0x69/0x80
+[ 191.738698] ? __warn+0x93/0x1a0
+[ 191.738703] ? xe_pt_stage_bind.constprop.0+0x60a/0x6b0 [xe]
+[ 191.738759] ? report_bug+0x18f/0x1a0
+[ 191.738764] ? handle_bug+0x63/0xa0
+[ 191.738767] ? exc_invalid_op+0x19/0x70
+[ 191.738770] ? asm_exc_invalid_op+0x1b/0x20
+[ 191.738777] ? xe_pt_stage_bind.constprop.0+0x60a/0x6b0 [xe]
+[ 191.738834] ? ret_from_fork_asm+0x1a/0x30
+[ 191.738849] bind_op_prepare+0x105/0x7b0 [xe]
+[ 191.738906] ? dma_resv_reserve_fences+0x301/0x380
+[ 191.738912] xe_pt_update_ops_prepare+0x28c/0x4b0 [xe]
+[ 191.738966] ? kmemleak_alloc+0x4b/0x80
+[ 191.738973] ops_execute+0x188/0x9d0 [xe]
+[ 191.739036] xe_vm_rebind+0x4ce/0x5a0 [xe]
+[ 191.739098] ? trace_hardirqs_on+0x4d/0x60
+[ 191.739112] preempt_rebind_work_func+0x76f/0xd00 [xe]
+
+Followed by NPD, when running some workload, since the sg was never
+actually populated but the vma is still marked for rebind when it should
+be skipped for this special EFAULT case. This is confirmed to fix the
+user report.
+
+v2 (MattB):
+ - Move earlier.
+v3 (MattB):
+ - Update the commit message to make it clear that this indeed fixes the
+ issue.
+
+Fixes: 521db22a1d70 ("drm/xe: Invalidate userptr VMA on page pin fault")
+Signed-off-by: Matthew Auld <matthew.auld@intel.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: <stable@vger.kernel.org> # v6.10+
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Reviewed-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250221143840.167150-5-matthew.auld@intel.com
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+(cherry picked from commit 6b93cb98910c826c2e2004942f8b060311e43618)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_vm.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -682,6 +682,18 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
+ err = xe_vma_userptr_pin_pages(uvma);
+ if (err == -EFAULT) {
+ list_del_init(&uvma->userptr.repin_link);
++ /*
++ * We might have already done the pin once already, but
++ * then had to retry before the re-bind happened, due
++ * some other condition in the caller, but in the
++ * meantime the userptr got dinged by the notifier such
++ * that we need to revalidate here, but this time we hit
++ * the EFAULT. In such a case make sure we remove
++ * ourselves from the rebind list to avoid going down in
++ * flames.
++ */
++ if (!list_empty(&uvma->vma.combined_links.rebind))
++ list_del_init(&uvma->vma.combined_links.rebind);
+
+ /* Wait for pending binds */
+ xe_vm_lock(vm, false);
--- /dev/null
+From e043dc16c28c8446e66c55adfe7c6e862a6a7bb7 Mon Sep 17 00:00:00 2001
+From: Matthew Auld <matthew.auld@intel.com>
+Date: Fri, 21 Feb 2025 14:38:41 +0000
+Subject: drm/xe/userptr: restore invalidation list on error
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Matthew Auld <matthew.auld@intel.com>
+
+commit e043dc16c28c8446e66c55adfe7c6e862a6a7bb7 upstream.
+
+On error restore anything still on the pin_list back to the invalidation
+list on error. For the actual pin, so long as the vma is tracked on
+either list it should get picked up on the next pin, however it looks
+possible for the vma to get nuked but still be present on this per vm
+pin_list leading to corruption. An alternative might be then to instead
+just remove the link when destroying the vma.
+
+v2:
+ - Also add some asserts.
+ - Keep the overzealous locking so that we are consistent with the docs;
+ updating the docs and related bits will be done as a follow up.
+
+Fixes: ed2bdf3b264d ("drm/xe/vm: Subclass userptr vmas")
+Suggested-by: Matthew Brost <matthew.brost@intel.com>
+Signed-off-by: Matthew Auld <matthew.auld@intel.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: <stable@vger.kernel.org> # v6.8+
+Reviewed-by: Matthew Brost <matthew.brost@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250221143840.167150-4-matthew.auld@intel.com
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+(cherry picked from commit 4e37e928928b730de9aa9a2f5dc853feeebc1742)
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/xe/xe_vm.c | 28 +++++++++++++++++++++-------
+ 1 file changed, 21 insertions(+), 7 deletions(-)
+
+--- a/drivers/gpu/drm/xe/xe_vm.c
++++ b/drivers/gpu/drm/xe/xe_vm.c
+@@ -667,15 +667,16 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
+
+ /* Collect invalidated userptrs */
+ spin_lock(&vm->userptr.invalidated_lock);
++ xe_assert(vm->xe, list_empty(&vm->userptr.repin_list));
+ list_for_each_entry_safe(uvma, next, &vm->userptr.invalidated,
+ userptr.invalidate_link) {
+ list_del_init(&uvma->userptr.invalidate_link);
+- list_move_tail(&uvma->userptr.repin_link,
+- &vm->userptr.repin_list);
++ list_add_tail(&uvma->userptr.repin_link,
++ &vm->userptr.repin_list);
+ }
+ spin_unlock(&vm->userptr.invalidated_lock);
+
+- /* Pin and move to temporary list */
++ /* Pin and move to bind list */
+ list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
+ userptr.repin_link) {
+ err = xe_vma_userptr_pin_pages(uvma);
+@@ -691,10 +692,10 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
+ err = xe_vm_invalidate_vma(&uvma->vma);
+ xe_vm_unlock(vm);
+ if (err)
+- return err;
++ break;
+ } else {
+- if (err < 0)
+- return err;
++ if (err)
++ break;
+
+ list_del_init(&uvma->userptr.repin_link);
+ list_move_tail(&uvma->vma.combined_links.rebind,
+@@ -702,7 +703,19 @@ int xe_vm_userptr_pin(struct xe_vm *vm)
+ }
+ }
+
+- return 0;
++ if (err) {
++ down_write(&vm->userptr.notifier_lock);
++ spin_lock(&vm->userptr.invalidated_lock);
++ list_for_each_entry_safe(uvma, next, &vm->userptr.repin_list,
++ userptr.repin_link) {
++ list_del_init(&uvma->userptr.repin_link);
++ list_move_tail(&uvma->userptr.invalidate_link,
++ &vm->userptr.invalidated);
++ }
++ spin_unlock(&vm->userptr.invalidated_lock);
++ up_write(&vm->userptr.notifier_lock);
++ }
++ return err;
+ }
+
+ /**
+@@ -1066,6 +1079,7 @@ static void xe_vma_destroy(struct xe_vma
+ xe_assert(vm->xe, vma->gpuva.flags & XE_VMA_DESTROYED);
+
+ spin_lock(&vm->userptr.invalidated_lock);
++ xe_assert(vm->xe, list_empty(&to_userptr_vma(vma)->userptr.repin_link));
+ list_del(&to_userptr_vma(vma)->userptr.invalidate_link);
+ spin_unlock(&vm->userptr.invalidated_lock);
+ } else if (!xe_vma_is_null(vma)) {
--- /dev/null
+From 2b90e7ace79774a3540ce569e000388f8d22c9e0 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Wed, 26 Feb 2025 15:18:39 -0500
+Subject: efi: Don't map the entire mokvar table to determine its size
+
+From: Peter Jones <pjones@redhat.com>
+
+commit 2b90e7ace79774a3540ce569e000388f8d22c9e0 upstream.
+
+Currently, when validating the mokvar table, we (re)map the entire table
+on each iteration of the loop, adding space as we discover new entries.
+If the table grows over a certain size, this fails due to limitations of
+early_memmap(), and we get a failure and traceback:
+
+ ------------[ cut here ]------------
+ WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:139 __early_ioremap+0xef/0x220
+ ...
+ Call Trace:
+ <TASK>
+ ? __early_ioremap+0xef/0x220
+ ? __warn.cold+0x93/0xfa
+ ? __early_ioremap+0xef/0x220
+ ? report_bug+0xff/0x140
+ ? early_fixup_exception+0x5d/0xb0
+ ? early_idt_handler_common+0x2f/0x3a
+ ? __early_ioremap+0xef/0x220
+ ? efi_mokvar_table_init+0xce/0x1d0
+ ? setup_arch+0x864/0xc10
+ ? start_kernel+0x6b/0xa10
+ ? x86_64_start_reservations+0x24/0x30
+ ? x86_64_start_kernel+0xed/0xf0
+ ? common_startup_64+0x13e/0x141
+ </TASK>
+ ---[ end trace 0000000000000000 ]---
+ mokvar: Failed to map EFI MOKvar config table pa=0x7c4c3000, size=265187.
+
+Mapping the entire structure isn't actually necessary, as we don't ever
+need more than one entry header mapped at once.
+
+Changes efi_mokvar_table_init() to only map each entry header, not the
+entire table, when determining the table size. Since we're not mapping
+any data past the variable name, it also changes the code to enforce
+that each variable name is NUL terminated, rather than attempting to
+verify it in place.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Peter Jones <pjones@redhat.com>
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/efi/mokvar-table.c | 41 +++++++++++-------------------------
+ 1 file changed, 13 insertions(+), 28 deletions(-)
+
+--- a/drivers/firmware/efi/mokvar-table.c
++++ b/drivers/firmware/efi/mokvar-table.c
+@@ -103,7 +103,6 @@ void __init efi_mokvar_table_init(void)
+ void *va = NULL;
+ unsigned long cur_offset = 0;
+ unsigned long offset_limit;
+- unsigned long map_size = 0;
+ unsigned long map_size_needed = 0;
+ unsigned long size;
+ struct efi_mokvar_table_entry *mokvar_entry;
+@@ -134,48 +133,34 @@ void __init efi_mokvar_table_init(void)
+ */
+ err = -EINVAL;
+ while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
+- mokvar_entry = va + cur_offset;
+- map_size_needed = cur_offset + sizeof(*mokvar_entry);
+- if (map_size_needed > map_size) {
+- if (va)
+- early_memunmap(va, map_size);
+- /*
+- * Map a little more than the fixed size entry
+- * header, anticipating some data. It's safe to
+- * do so as long as we stay within current memory
+- * descriptor.
+- */
+- map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
+- offset_limit);
+- va = early_memremap(efi.mokvar_table, map_size);
+- if (!va) {
+- pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
+- efi.mokvar_table, map_size);
+- return;
+- }
+- mokvar_entry = va + cur_offset;
++ if (va)
++ early_memunmap(va, sizeof(*mokvar_entry));
++ va = early_memremap(efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
++ if (!va) {
++ pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%zu.\n",
++ efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
++ return;
+ }
++ mokvar_entry = va;
+
+ /* Check for last sentinel entry */
+ if (mokvar_entry->name[0] == '\0') {
+ if (mokvar_entry->data_size != 0)
+ break;
+ err = 0;
++ map_size_needed = cur_offset + sizeof(*mokvar_entry);
+ break;
+ }
+
+- /* Sanity check that the name is null terminated */
+- size = strnlen(mokvar_entry->name,
+- sizeof(mokvar_entry->name));
+- if (size >= sizeof(mokvar_entry->name))
+- break;
++ /* Enforce that the name is NUL terminated */
++ mokvar_entry->name[sizeof(mokvar_entry->name) - 1] = '\0';
+
+ /* Advance to the next entry */
+- cur_offset = map_size_needed + mokvar_entry->data_size;
++ cur_offset += sizeof(*mokvar_entry) + mokvar_entry->data_size;
+ }
+
+ if (va)
+- early_memunmap(va, map_size);
++ early_memunmap(va, sizeof(*mokvar_entry));
+ if (err) {
+ pr_err("EFI MOKvar config table is not valid\n");
+ return;
--- /dev/null
+From a1a7eb89ca0b89dc1c326eeee2596f263291aca3 Mon Sep 17 00:00:00 2001
+From: Nikolay Kuratov <kniv@yandex-team.ru>
+Date: Thu, 6 Feb 2025 12:01:56 +0300
+Subject: ftrace: Avoid potential division by zero in function_stat_show()
+
+From: Nikolay Kuratov <kniv@yandex-team.ru>
+
+commit a1a7eb89ca0b89dc1c326eeee2596f263291aca3 upstream.
+
+Check whether denominator expression x * (x - 1) * 1000 mod {2^32, 2^64}
+produce zero and skip stddev computation in that case.
+
+For now don't care about rec->counter * rec->counter overflow because
+rec->time * rec->time overflow will likely happen earlier.
+
+Cc: stable@vger.kernel.org
+Cc: Wen Yang <wenyang@linux.alibaba.com>
+Cc: Mark Rutland <mark.rutland@arm.com>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/20250206090156.1561783-1-kniv@yandex-team.ru
+Fixes: e31f7939c1c27 ("ftrace: Avoid potential division by zero in function profiler")
+Signed-off-by: Nikolay Kuratov <kniv@yandex-team.ru>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/ftrace.c | 27 ++++++++++++---------------
+ 1 file changed, 12 insertions(+), 15 deletions(-)
+
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -541,6 +541,7 @@ static int function_stat_show(struct seq
+ static struct trace_seq s;
+ unsigned long long avg;
+ unsigned long long stddev;
++ unsigned long long stddev_denom;
+ #endif
+ mutex_lock(&ftrace_profile_lock);
+
+@@ -562,23 +563,19 @@ static int function_stat_show(struct seq
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ seq_puts(m, " ");
+
+- /* Sample standard deviation (s^2) */
+- if (rec->counter <= 1)
+- stddev = 0;
+- else {
+- /*
+- * Apply Welford's method:
+- * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
+- */
++ /*
++ * Variance formula:
++ * s^2 = 1 / (n * (n-1)) * (n * \Sum (x_i)^2 - (\Sum x_i)^2)
++ * Maybe Welford's method is better here?
++ * Divide only by 1000 for ns^2 -> us^2 conversion.
++ * trace_print_graph_duration will divide by 1000 again.
++ */
++ stddev = 0;
++ stddev_denom = rec->counter * (rec->counter - 1) * 1000;
++ if (stddev_denom) {
+ stddev = rec->counter * rec->time_squared -
+ rec->time * rec->time;
+-
+- /*
+- * Divide only 1000 for ns^2 -> us^2 conversion.
+- * trace_print_graph_duration will divide 1000 again.
+- */
+- stddev = div64_ul(stddev,
+- rec->counter * (rec->counter - 1) * 1000);
++ stddev = div64_ul(stddev, stddev_denom);
+ }
+
+ trace_seq_init(&s);
--- /dev/null
+From 0c67c37e1710b2a8f61c8a02db95a51fe577e2c1 Mon Sep 17 00:00:00 2001
+From: Joanne Koong <joannelkoong@gmail.com>
+Date: Tue, 11 Feb 2025 13:47:50 -0800
+Subject: fuse: revert back to __readahead_folio() for readahead
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Joanne Koong <joannelkoong@gmail.com>
+
+commit 0c67c37e1710b2a8f61c8a02db95a51fe577e2c1 upstream.
+
+In commit 3eab9d7bc2f4 ("fuse: convert readahead to use folios"), the
+logic was converted to using the new folio readahead code, which drops
+the reference on the folio once it is locked, using an inferred
+reference on the folio. Previously we held a reference on the folio for
+the entire duration of the readpages call.
+
+This is fine, however for the case for splice pipe responses where we
+will remove the old folio and splice in the new folio (see
+fuse_try_move_page()), we assume that there is a reference held on the
+folio for ap->folios, which is no longer the case.
+
+To fix this, revert back to __readahead_folio() which allows us to hold
+the reference on the folio for the duration of readpages until either we
+drop the reference ourselves in fuse_readpages_end() or the reference is
+dropped after it's replaced in the page cache in the splice case.
+This will fix the UAF bug that was reported.
+
+Link: https://lore.kernel.org/linux-fsdevel/2f681f48-00f5-4e09-8431-2b3dbfaa881e@heusel.eu/
+Fixes: 3eab9d7bc2f4 ("fuse: convert readahead to use folios")
+Reported-by: Christian Heusel <christian@heusel.eu>
+Closes: https://lore.kernel.org/all/2f681f48-00f5-4e09-8431-2b3dbfaa881e@heusel.eu/
+Closes: https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/110
+Reported-by: Mantas Mikulėnas <grawity@gmail.com>
+Closes: https://lore.kernel.org/all/34feb867-09e2-46e4-aa31-d9660a806d1a@gmail.com/
+Closes: https://bugzilla.opensuse.org/show_bug.cgi?id=1236660
+Cc: <stable@vger.kernel.org> # v6.13
+Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/fuse/dev.c | 6 ++++++
+ fs/fuse/file.c | 13 +++++++++++--
+ 2 files changed, 17 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -836,6 +836,12 @@ static int fuse_check_folio(struct folio
+ return 0;
+ }
+
++/*
++ * Attempt to steal a page from the splice() pipe and move it into the
++ * pagecache. If successful, the pointer in @pagep will be updated. The
++ * folio that was originally in @pagep will lose a reference and the new
++ * folio returned in @pagep will carry a reference.
++ */
+ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
+ {
+ int err;
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -955,8 +955,10 @@ static void fuse_readpages_end(struct fu
+ fuse_invalidate_atime(inode);
+ }
+
+- for (i = 0; i < ap->num_folios; i++)
++ for (i = 0; i < ap->num_folios; i++) {
+ folio_end_read(ap->folios[i], !err);
++ folio_put(ap->folios[i]);
++ }
+ if (ia->ff)
+ fuse_file_put(ia->ff, false);
+
+@@ -1048,7 +1050,14 @@ static void fuse_readahead(struct readah
+ ap = &ia->ap;
+
+ while (ap->num_folios < cur_pages) {
+- folio = readahead_folio(rac);
++ /*
++ * This returns a folio with a ref held on it.
++ * The ref needs to be held until the request is
++ * completed, since the splice case (see
++ * fuse_try_move_page()) drops the ref after it's
++ * replaced in the page cache.
++ */
++ folio = __readahead_folio(rac);
+ ap->folios[ap->num_folios] = folio;
+ ap->descs[ap->num_folios].length = folio_size(folio);
+ ap->num_folios++;
--- /dev/null
+From de70981f295e7eab86325db3bf349fa676f16c42 Mon Sep 17 00:00:00 2001
+From: Harshitha Ramamurthy <hramamurthy@google.com>
+Date: Wed, 26 Feb 2025 00:35:26 +0000
+Subject: gve: unlink old napi when stopping a queue using queue API
+
+From: Harshitha Ramamurthy <hramamurthy@google.com>
+
+commit de70981f295e7eab86325db3bf349fa676f16c42 upstream.
+
+When a queue is stopped using the ndo queue API, before
+destroying its page pool, the associated NAPI instance
+needs to be unlinked to avoid warnings.
+
+Handle this by calling page_pool_disable_direct_recycling()
+when stopping a queue.
+
+Cc: stable@vger.kernel.org
+Fixes: ebdfae0d377b ("gve: adopt page pool for DQ RDA mode")
+Reviewed-by: Praveen Kaligineedi <pkaligineedi@google.com>
+Signed-off-by: Harshitha Ramamurthy <hramamurthy@google.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Link: https://patch.msgid.link/20250226003526.1546854-1-hramamurthy@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/google/gve/gve_rx_dqo.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+index 8ac0047f1ada..f0674a443567 100644
+--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c
++++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+@@ -109,10 +109,12 @@ static void gve_rx_reset_ring_dqo(struct gve_priv *priv, int idx)
+ void gve_rx_stop_ring_dqo(struct gve_priv *priv, int idx)
+ {
+ int ntfy_idx = gve_rx_idx_to_ntfy(priv, idx);
++ struct gve_rx_ring *rx = &priv->rx[idx];
+
+ if (!gve_rx_was_added_to_block(priv, idx))
+ return;
+
++ page_pool_disable_direct_recycling(rx->dqo.page_pool);
+ gve_remove_napi(priv, ntfy_idx);
+ gve_rx_remove_from_block(priv, idx);
+ gve_rx_reset_ring_dqo(priv, idx);
+--
+2.48.1
+
--- /dev/null
+From 9f3c507cb44498067c980674139bcad56e582ee6 Mon Sep 17 00:00:00 2001
+From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+Date: Wed, 19 Feb 2025 19:27:47 +0530
+Subject: i2c: amd-asf: Fix EOI register write to enable successive interrupts
+
+From: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+
+commit 9f3c507cb44498067c980674139bcad56e582ee6 upstream.
+
+The commit b1f8921dfbaa
+("i2c: amd-asf: Clear remote IRR bit to get successive interrupt")
+introduced a method to enable successive interrupts but inadvertently
+omitted the necessary write to the EOI register, resulting in a failure to
+receive successive interrupts.
+
+Fix this by adding the required write to the EOI register.
+
+Fixes: b1f8921dfbaa ("i2c: amd-asf: Clear remote IRR bit to get successive interrupt")
+Cc: stable@vger.kernel.org # v6.13+
+Co-developed-by: Sanket Goswami <Sanket.Goswami@amd.com>
+Signed-off-by: Sanket Goswami <Sanket.Goswami@amd.com>
+Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
+Fixes: 9b25419ad397 ("i2c: amd-asf: Add routine to handle the ASF slave process")
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20250219135747.3251182-1-Shyam-sundar.S-k@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-amd-asf-plat.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/i2c/busses/i2c-amd-asf-plat.c
++++ b/drivers/i2c/busses/i2c-amd-asf-plat.c
+@@ -293,6 +293,7 @@ static irqreturn_t amd_asf_irq_handler(i
+ amd_asf_update_ioport_target(piix4_smba, ASF_SLV_INTR, SMBHSTSTS, true);
+ }
+
++ iowrite32(irq, dev->eoi_base);
+ return IRQ_HANDLED;
+ }
+
--- /dev/null
+From 71c49ee9bb41e1709abac7e2eb05f9193222e580 Mon Sep 17 00:00:00 2001
+From: Binbin Zhou <zhoubinbin@loongson.cn>
+Date: Thu, 20 Feb 2025 20:56:12 +0800
+Subject: i2c: ls2x: Fix frequency division register access
+
+From: Binbin Zhou <zhoubinbin@loongson.cn>
+
+commit 71c49ee9bb41e1709abac7e2eb05f9193222e580 upstream.
+
+According to the chip manual, the I2C register access type of
+Loongson-2K2000/LS7A is "B", so we can only access registers in byte
+form (readb()/writeb()).
+
+Although Loongson-2K0500/Loongson-2K1000 do not have similar
+constraints, register accesses in byte form also behave correctly.
+
+Also, in hardware, the frequency division registers are defined as two
+separate registers (high 8-bit and low 8-bit), so we just access them
+directly as bytes.
+
+Fixes: 015e61f0bffd ("i2c: ls2x: Add driver for Loongson-2K/LS7A I2C controller")
+Co-developed-by: Hongliang Wang <wanghongliang@loongson.cn>
+Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
+Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
+Cc: stable@vger.kernel.org # v6.3+
+Reviewed-by: Andy Shevchenko <andy@kernel.org>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20250220125612.1910990-1-zhoubinbin@loongson.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-ls2x.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/i2c/busses/i2c-ls2x.c
++++ b/drivers/i2c/busses/i2c-ls2x.c
+@@ -10,6 +10,7 @@
+ * Rewritten for mainline by Binbin Zhou <zhoubinbin@loongson.cn>
+ */
+
++#include <linux/bitfield.h>
+ #include <linux/bits.h>
+ #include <linux/completion.h>
+ #include <linux/device.h>
+@@ -26,7 +27,8 @@
+ #include <linux/units.h>
+
+ /* I2C Registers */
+-#define I2C_LS2X_PRER 0x0 /* Freq Division Register(16 bits) */
++#define I2C_LS2X_PRER_LO 0x0 /* Freq Division Low Byte Register */
++#define I2C_LS2X_PRER_HI 0x1 /* Freq Division High Byte Register */
+ #define I2C_LS2X_CTR 0x2 /* Control Register */
+ #define I2C_LS2X_TXR 0x3 /* Transport Data Register */
+ #define I2C_LS2X_RXR 0x3 /* Receive Data Register */
+@@ -93,6 +95,7 @@ static irqreturn_t ls2x_i2c_isr(int this
+ */
+ static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv)
+ {
++ u16 val;
+ struct i2c_timings *t = &priv->i2c_t;
+ struct device *dev = priv->adapter.dev.parent;
+ u32 acpi_speed = i2c_acpi_find_bus_speed(dev);
+@@ -104,9 +107,14 @@ static void ls2x_i2c_adjust_bus_speed(st
+ else
+ t->bus_freq_hz = LS2X_I2C_FREQ_STD;
+
+- /* Calculate and set i2c frequency. */
+- writew(LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1,
+- priv->base + I2C_LS2X_PRER);
++ /*
++ * According to the chip manual, we can only access the registers as bytes,
++ * otherwise the high bits will be truncated.
++ * So set the I2C frequency with a sequential writeb() instead of writew().
++ */
++ val = LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1;
++ writeb(FIELD_GET(GENMASK(7, 0), val), priv->base + I2C_LS2X_PRER_LO);
++ writeb(FIELD_GET(GENMASK(15, 8), val), priv->base + I2C_LS2X_PRER_HI);
+ }
+
+ static void ls2x_i2c_init(struct ls2x_i2c_priv *priv)
--- /dev/null
+From dd1998e243f5fa25d348a384ba0b6c84d980f2b2 Mon Sep 17 00:00:00 2001
+From: Tyrone Ting <kfting@nuvoton.com>
+Date: Thu, 20 Feb 2025 12:00:29 +0800
+Subject: i2c: npcm: disable interrupt enable bit before devm_request_irq
+
+From: Tyrone Ting <kfting@nuvoton.com>
+
+commit dd1998e243f5fa25d348a384ba0b6c84d980f2b2 upstream.
+
+The customer reports that there is a soft lockup issue related to
+the i2c driver. After checking, the i2c module was doing a tx transfer
+and the bmc machine reboots in the middle of the i2c transaction, the i2c
+module keeps the status without being reset.
+
+Due to such an i2c module status, the i2c irq handler keeps getting
+triggered since the i2c irq handler is registered in the kernel booting
+process after the bmc machine is doing a warm rebooting.
+The continuous triggering is stopped by the soft lockup watchdog timer.
+
+Disable the interrupt enable bit in the i2c module before calling
+devm_request_irq to fix this issue since the i2c relative status bit
+is read-only.
+
+Here is the soft lockup log.
+[ 28.176395] watchdog: BUG: soft lockup - CPU#0 stuck for 26s! [swapper/0:1]
+[ 28.183351] Modules linked in:
+[ 28.186407] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.15.120-yocto-s-dirty-bbebc78 #1
+[ 28.201174] pstate: 40000005 (nZcv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+[ 28.208128] pc : __do_softirq+0xb0/0x368
+[ 28.212055] lr : __do_softirq+0x70/0x368
+[ 28.215972] sp : ffffff8035ebca00
+[ 28.219278] x29: ffffff8035ebca00 x28: 0000000000000002 x27: ffffff80071a3780
+[ 28.226412] x26: ffffffc008bdc000 x25: ffffffc008bcc640 x24: ffffffc008be50c0
+[ 28.233546] x23: ffffffc00800200c x22: 0000000000000000 x21: 000000000000001b
+[ 28.240679] x20: 0000000000000000 x19: ffffff80001c3200 x18: ffffffffffffffff
+[ 28.247812] x17: ffffffc02d2e0000 x16: ffffff8035eb8b40 x15: 00001e8480000000
+[ 28.254945] x14: 02c3647e37dbfcb6 x13: 02c364f2ab14200c x12: 0000000002c364f2
+[ 28.262078] x11: 00000000fa83b2da x10: 000000000000b67e x9 : ffffffc008010250
+[ 28.269211] x8 : 000000009d983d00 x7 : 7fffffffffffffff x6 : 0000036d74732434
+[ 28.276344] x5 : 00ffffffffffffff x4 : 0000000000000015 x3 : 0000000000000198
+[ 28.283476] x2 : ffffffc02d2e0000 x1 : 00000000000000e0 x0 : ffffffc008bdcb40
+[ 28.290611] Call trace:
+[ 28.293052] __do_softirq+0xb0/0x368
+[ 28.296625] __irq_exit_rcu+0xe0/0x100
+[ 28.300374] irq_exit+0x14/0x20
+[ 28.303513] handle_domain_irq+0x68/0x90
+[ 28.307440] gic_handle_irq+0x78/0xb0
+[ 28.311098] call_on_irq_stack+0x20/0x38
+[ 28.315019] do_interrupt_handler+0x54/0x5c
+[ 28.319199] el1_interrupt+0x2c/0x4c
+[ 28.322777] el1h_64_irq_handler+0x14/0x20
+[ 28.326872] el1h_64_irq+0x74/0x78
+[ 28.330269] __setup_irq+0x454/0x780
+[ 28.333841] request_threaded_irq+0xd0/0x1b4
+[ 28.338107] devm_request_threaded_irq+0x84/0x100
+[ 28.342809] npcm_i2c_probe_bus+0x188/0x3d0
+[ 28.346990] platform_probe+0x6c/0xc4
+[ 28.350653] really_probe+0xcc/0x45c
+[ 28.354227] __driver_probe_device+0x8c/0x160
+[ 28.358578] driver_probe_device+0x44/0xe0
+[ 28.362670] __driver_attach+0x124/0x1d0
+[ 28.366589] bus_for_each_dev+0x7c/0xe0
+[ 28.370426] driver_attach+0x28/0x30
+[ 28.373997] bus_add_driver+0x124/0x240
+[ 28.377830] driver_register+0x7c/0x124
+[ 28.381662] __platform_driver_register+0x2c/0x34
+[ 28.386362] npcm_i2c_init+0x3c/0x5c
+[ 28.389937] do_one_initcall+0x74/0x230
+[ 28.393768] kernel_init_freeable+0x24c/0x2b4
+[ 28.398126] kernel_init+0x28/0x130
+[ 28.401614] ret_from_fork+0x10/0x20
+[ 28.405189] Kernel panic - not syncing: softlockup: hung tasks
+[ 28.411011] SMP: stopping secondary CPUs
+[ 28.414933] Kernel Offset: disabled
+[ 28.418412] CPU features: 0x00000000,00000802
+[ 28.427644] Rebooting in 20 seconds..
+
+Fixes: 56a1485b102e ("i2c: npcm7xx: Add Nuvoton NPCM I2C controller driver")
+Signed-off-by: Tyrone Ting <kfting@nuvoton.com>
+Cc: <stable@vger.kernel.org> # v5.8+
+Reviewed-by: Tali Perry <tali.perry1@gmail.com>
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20250220040029.27596-2-kfting@nuvoton.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/i2c/busses/i2c-npcm7xx.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/i2c/busses/i2c-npcm7xx.c
++++ b/drivers/i2c/busses/i2c-npcm7xx.c
+@@ -2329,6 +2329,13 @@ static int npcm_i2c_probe_bus(struct pla
+ if (irq < 0)
+ return irq;
+
++ /*
++ * Disable the interrupt to avoid the interrupt handler being triggered
++ * incorrectly by the asynchronous interrupt status since the machine
++ * might do a warm reset during the last smbus/i2c transfer session.
++ */
++ npcm_i2c_int_enable(bus, false);
++
+ ret = devm_request_irq(bus->dev, irq, npcm_i2c_bus_irq, 0,
+ dev_name(bus->dev), bus);
+ if (ret)
--- /dev/null
+From 57a0ef02fefafc4b9603e33a18b669ba5ce59ba3 Mon Sep 17 00:00:00 2001
+From: Roberto Sassu <roberto.sassu@huawei.com>
+Date: Tue, 4 Feb 2025 13:57:20 +0100
+Subject: ima: Reset IMA_NONACTION_RULE_FLAGS after post_setattr
+
+From: Roberto Sassu <roberto.sassu@huawei.com>
+
+commit 57a0ef02fefafc4b9603e33a18b669ba5ce59ba3 upstream.
+
+Commit 0d73a55208e9 ("ima: re-introduce own integrity cache lock")
+mistakenly reverted the performance improvement introduced in commit
+42a4c603198f0 ("ima: fix ima_inode_post_setattr"). The unused bit mask was
+subsequently removed by commit 11c60f23ed13 ("integrity: Remove unused
+macro IMA_ACTION_RULE_FLAGS").
+
+Restore the performance improvement by introducing the new mask
+IMA_NONACTION_RULE_FLAGS, equal to IMA_NONACTION_FLAGS without
+IMA_NEW_FILE, which is not a rule-specific flag.
+
+Finally, reset IMA_NONACTION_RULE_FLAGS instead of IMA_NONACTION_FLAGS in
+process_measurement(), if the IMA_CHANGE_ATTR atomic flag is set (after
+file metadata modification).
+
+With this patch, new files for which metadata were modified while they are
+still open, can be reopened before the last file close (when security.ima
+is written), since the IMA_NEW_FILE flag is not cleared anymore. Otherwise,
+appraisal fails because security.ima is missing (files with IMA_NEW_FILE
+set are an exception).
+
+Cc: stable@vger.kernel.org # v4.16.x
+Fixes: 0d73a55208e9 ("ima: re-introduce own integrity cache lock")
+Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
+Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ security/integrity/ima/ima.h | 3 +++
+ security/integrity/ima/ima_main.c | 7 +++++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/security/integrity/ima/ima.h
++++ b/security/integrity/ima/ima.h
+@@ -149,6 +149,9 @@ struct ima_kexec_hdr {
+ #define IMA_CHECK_BLACKLIST 0x40000000
+ #define IMA_VERITY_REQUIRED 0x80000000
+
++/* Exclude non-action flags which are not rule-specific. */
++#define IMA_NONACTION_RULE_FLAGS (IMA_NONACTION_FLAGS & ~IMA_NEW_FILE)
++
+ #define IMA_DO_MASK (IMA_MEASURE | IMA_APPRAISE | IMA_AUDIT | \
+ IMA_HASH | IMA_APPRAISE_SUBMASK)
+ #define IMA_DONE_MASK (IMA_MEASURED | IMA_APPRAISED | IMA_AUDITED | \
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -269,10 +269,13 @@ static int process_measurement(struct fi
+ mutex_lock(&iint->mutex);
+
+ if (test_and_clear_bit(IMA_CHANGE_ATTR, &iint->atomic_flags))
+- /* reset appraisal flags if ima_inode_post_setattr was called */
++ /*
++ * Reset appraisal flags (action and non-action rule-specific)
++ * if ima_inode_post_setattr was called.
++ */
+ iint->flags &= ~(IMA_APPRAISE | IMA_APPRAISED |
+ IMA_APPRAISE_SUBMASK | IMA_APPRAISED_SUBMASK |
+- IMA_NONACTION_FLAGS);
++ IMA_NONACTION_RULE_FLAGS);
+
+ /*
+ * Re-evaulate the file if either the xattr has changed or the
--- /dev/null
+From c157d351460bcf202970e97e611cb6b54a3dd4a4 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 25 Feb 2025 23:37:08 +0100
+Subject: intel_idle: Handle older CPUs, which stop the TSC in deeper C states, correctly
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit c157d351460bcf202970e97e611cb6b54a3dd4a4 upstream.
+
+The Intel idle driver is preferred over the ACPI processor idle driver,
+but fails to implement the work around for Core2 generation CPUs, where
+the TSC stops in C2 and deeper C-states. This causes stalls and boot
+delays, when the clocksource watchdog does not catch the unstable TSC
+before the CPU goes deep idle for the first time.
+
+The ACPI driver marks the TSC unstable when it detects that the CPU
+supports C2 or deeper and the CPU does not have a non-stop TSC.
+
+Add the equivivalent work around to the Intel idle driver to cure that.
+
+Fixes: 18734958e9bf ("intel_idle: Use ACPI _CST for processor models without C-state tables")
+Reported-by: Fab Stz <fabstz-it@yahoo.fr>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Fab Stz <fabstz-it@yahoo.fr>
+Cc: All applicable <stable@vger.kernel.org>
+Closes: https://lore.kernel.org/all/10cf96aa-1276-4bd4-8966-c890377030c3@yahoo.fr
+Link: https://patch.msgid.link/87bjupfy7f.ffs@tglx
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/idle/intel_idle.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/idle/intel_idle.c
++++ b/drivers/idle/intel_idle.c
+@@ -55,6 +55,7 @@
+ #include <asm/intel-family.h>
+ #include <asm/mwait.h>
+ #include <asm/spec-ctrl.h>
++#include <asm/tsc.h>
+ #include <asm/fpu/api.h>
+
+ #define INTEL_IDLE_VERSION "0.5.1"
+@@ -1797,6 +1798,9 @@ static void __init intel_idle_init_cstat
+ if (intel_idle_state_needs_timer_stop(state))
+ state->flags |= CPUIDLE_FLAG_TIMER_STOP;
+
++ if (cx->type > ACPI_STATE_C1 && !boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
++ mark_tsc_unstable("TSC halts in idle");
++
+ state->enter = intel_idle;
+ state->enter_s2idle = intel_idle_s2idle;
+ }
--- /dev/null
+From b150654f74bf0df8e6a7936d5ec51400d9ec06d8 Mon Sep 17 00:00:00 2001
+From: Lu Baolu <baolu.lu@linux.intel.com>
+Date: Fri, 28 Feb 2025 18:27:26 +0800
+Subject: iommu/vt-d: Fix suspicious RCU usage
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+commit b150654f74bf0df8e6a7936d5ec51400d9ec06d8 upstream.
+
+Commit <d74169ceb0d2> ("iommu/vt-d: Allocate DMAR fault interrupts
+locally") moved the call to enable_drhd_fault_handling() to a code
+path that does not hold any lock while traversing the drhd list. Fix
+it by ensuring the dmar_global_lock lock is held when traversing the
+drhd list.
+
+Without this fix, the following warning is triggered:
+ =============================
+ WARNING: suspicious RCU usage
+ 6.14.0-rc3 #55 Not tainted
+ -----------------------------
+ drivers/iommu/intel/dmar.c:2046 RCU-list traversed in non-reader section!!
+ other info that might help us debug this:
+ rcu_scheduler_active = 1, debug_locks = 1
+ 2 locks held by cpuhp/1/23:
+ #0: ffffffff84a67c50 (cpu_hotplug_lock){++++}-{0:0}, at: cpuhp_thread_fun+0x87/0x2c0
+ #1: ffffffff84a6a380 (cpuhp_state-up){+.+.}-{0:0}, at: cpuhp_thread_fun+0x87/0x2c0
+ stack backtrace:
+ CPU: 1 UID: 0 PID: 23 Comm: cpuhp/1 Not tainted 6.14.0-rc3 #55
+ Call Trace:
+ <TASK>
+ dump_stack_lvl+0xb7/0xd0
+ lockdep_rcu_suspicious+0x159/0x1f0
+ ? __pfx_enable_drhd_fault_handling+0x10/0x10
+ enable_drhd_fault_handling+0x151/0x180
+ cpuhp_invoke_callback+0x1df/0x990
+ cpuhp_thread_fun+0x1ea/0x2c0
+ smpboot_thread_fn+0x1f5/0x2e0
+ ? __pfx_smpboot_thread_fn+0x10/0x10
+ kthread+0x12a/0x2d0
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x4a/0x60
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Holding the lock in enable_drhd_fault_handling() triggers a lockdep splat
+about a possible deadlock between dmar_global_lock and cpu_hotplug_lock.
+This is avoided by not holding dmar_global_lock when calling
+iommu_device_register(), which initiates the device probe process.
+
+Fixes: d74169ceb0d2 ("iommu/vt-d: Allocate DMAR fault interrupts locally")
+Reported-and-tested-by: Ido Schimmel <idosch@nvidia.com>
+Closes: https://lore.kernel.org/linux-iommu/Zx9OwdLIc_VoQ0-a@shredder.mtl.com/
+Tested-by: Breno Leitao <leitao@debian.org>
+Cc: stable@vger.kernel.org
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20250218022422.2315082-1-baolu.lu@linux.intel.com
+Tested-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/intel/dmar.c | 1 +
+ drivers/iommu/intel/iommu.c | 7 +++++++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -2043,6 +2043,7 @@ int enable_drhd_fault_handling(unsigned
+ /*
+ * Enable fault control interrupt.
+ */
++ guard(rwsem_read)(&dmar_global_lock);
+ for_each_iommu(iommu, drhd) {
+ u32 fault_status;
+ int ret;
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -3155,7 +3155,14 @@ int __init intel_iommu_init(void)
+ iommu_device_sysfs_add(&iommu->iommu, NULL,
+ intel_iommu_groups,
+ "%s", iommu->name);
++ /*
++ * The iommu device probe is protected by the iommu_probe_device_lock.
++ * Release the dmar_global_lock before entering the device probe path
++ * to avoid unnecessary lock order splat.
++ */
++ up_read(&dmar_global_lock);
+ iommu_device_register(&iommu->iommu, &intel_iommu_ops, NULL);
++ down_read(&dmar_global_lock);
+
+ iommu_pmu_register(iommu);
+ }
--- /dev/null
+From 64f792981e35e191eb619f6f2fefab76cc7d6112 Mon Sep 17 00:00:00 2001
+From: Jerry Snitselaar <jsnitsel@redhat.com>
+Date: Fri, 28 Feb 2025 18:27:25 +0800
+Subject: iommu/vt-d: Remove device comparison in context_setup_pass_through_cb
+
+From: Jerry Snitselaar <jsnitsel@redhat.com>
+
+commit 64f792981e35e191eb619f6f2fefab76cc7d6112 upstream.
+
+Remove the device comparison check in context_setup_pass_through_cb.
+pci_for_each_dma_alias already makes a decision on whether the
+callback function should be called for a device. With the check
+in place it will fail to create context entries for aliases as
+it walks up to the root bus.
+
+Fixes: 2031c469f816 ("iommu/vt-d: Add support for static identity domain")
+Closes: https://lore.kernel.org/linux-iommu/82499eb6-00b7-4f83-879a-e97b4144f576@linux.intel.com/
+Cc: stable@vger.kernel.org
+Signed-off-by: Jerry Snitselaar <jsnitsel@redhat.com>
+Link: https://lore.kernel.org/r/20250224180316.140123-1-jsnitsel@redhat.com
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/intel/iommu.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/iommu/intel/iommu.c
++++ b/drivers/iommu/intel/iommu.c
+@@ -4380,9 +4380,6 @@ static int context_setup_pass_through_cb
+ {
+ struct device *dev = data;
+
+- if (dev != &pdev->dev)
+- return 0;
+-
+ return context_setup_pass_through(dev, PCI_BUS_NUM(alias), alias & 0xff);
+ }
+
--- /dev/null
+From fa808ed4e199ed17d878eb75b110bda30dd52434 Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oliver.upton@linux.dev>
+Date: Wed, 19 Feb 2025 14:07:37 -0800
+Subject: KVM: arm64: Ensure a VMID is allocated before programming VTTBR_EL2
+
+From: Oliver Upton <oliver.upton@linux.dev>
+
+commit fa808ed4e199ed17d878eb75b110bda30dd52434 upstream.
+
+Vladimir reports that a race condition to attach a VMID to a stage-2 MMU
+sometimes results in a vCPU entering the guest with a VMID of 0:
+
+| CPU1 | CPU2
+| |
+| | kvm_arch_vcpu_ioctl_run
+| | vcpu_load <= load VTTBR_EL2
+| | kvm_vmid->id = 0
+| |
+| kvm_arch_vcpu_ioctl_run |
+| vcpu_load <= load VTTBR_EL2 |
+| with kvm_vmid->id = 0|
+| kvm_arm_vmid_update <= allocates fresh |
+| kvm_vmid->id and |
+| reload VTTBR_EL2 |
+| |
+| | kvm_arm_vmid_update <= observes that kvm_vmid->id
+| | already allocated,
+| | skips reload VTTBR_EL2
+
+Oh yeah, it's as bad as it looks. Remember that VHE loads the stage-2
+MMU eagerly but a VMID only gets attached to the MMU later on in the
+KVM_RUN loop.
+
+Even in the "best case" where VTTBR_EL2 correctly gets reprogrammed
+before entering the EL1&0 regime, there is a period of time where
+hardware is configured with VMID 0. That's completely insane. So, rather
+than decorating the 'late' binding with another hack, just allocate the
+damn thing up front.
+
+Attaching a VMID from vcpu_load() is still rollover safe since
+(surprise!) it'll always get called after a vCPU was preempted.
+
+Excuse me while I go find a brown paper bag.
+
+Cc: stable@vger.kernel.org
+Fixes: 934bf871f011 ("KVM: arm64: Load the stage-2 MMU context in kvm_vcpu_load_vhe()")
+Reported-by: Vladimir Murzin <vladimir.murzin@arm.com>
+Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
+Link: https://lore.kernel.org/r/20250219220737.130842-1-oliver.upton@linux.dev
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/kvm_host.h | 2 +-
+ arch/arm64/kvm/arm.c | 22 ++++++++++------------
+ arch/arm64/kvm/vmid.c | 11 +++--------
+ 3 files changed, 14 insertions(+), 21 deletions(-)
+
+--- a/arch/arm64/include/asm/kvm_host.h
++++ b/arch/arm64/include/asm/kvm_host.h
+@@ -1262,7 +1262,7 @@ int kvm_arm_pvtime_has_attr(struct kvm_v
+ extern unsigned int __ro_after_init kvm_arm_vmid_bits;
+ int __init kvm_arm_vmid_alloc_init(void);
+ void __init kvm_arm_vmid_alloc_free(void);
+-bool kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
++void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid);
+ void kvm_arm_vmid_clear_active(void);
+
+ static inline void kvm_arm_pvtime_vcpu_init(struct kvm_vcpu_arch *vcpu_arch)
+--- a/arch/arm64/kvm/arm.c
++++ b/arch/arm64/kvm/arm.c
+@@ -581,6 +581,16 @@ void kvm_arch_vcpu_load(struct kvm_vcpu
+ last_ran = this_cpu_ptr(mmu->last_vcpu_ran);
+
+ /*
++ * Ensure a VMID is allocated for the MMU before programming VTTBR_EL2,
++ * which happens eagerly in VHE.
++ *
++ * Also, the VMID allocator only preserves VMIDs that are active at the
++ * time of rollover, so KVM might need to grab a new VMID for the MMU if
++ * this is called from kvm_sched_in().
++ */
++ kvm_arm_vmid_update(&mmu->vmid);
++
++ /*
+ * We guarantee that both TLBs and I-cache are private to each
+ * vcpu. If detecting that a vcpu from the same VM has
+ * previously run on the same physical CPU, call into the
+@@ -1147,18 +1157,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_v
+ */
+ preempt_disable();
+
+- /*
+- * The VMID allocator only tracks active VMIDs per
+- * physical CPU, and therefore the VMID allocated may not be
+- * preserved on VMID roll-over if the task was preempted,
+- * making a thread's VMID inactive. So we need to call
+- * kvm_arm_vmid_update() in non-premptible context.
+- */
+- if (kvm_arm_vmid_update(&vcpu->arch.hw_mmu->vmid) &&
+- has_vhe())
+- __load_stage2(vcpu->arch.hw_mmu,
+- vcpu->arch.hw_mmu->arch);
+-
+ kvm_pmu_flush_hwstate(vcpu);
+
+ local_irq_disable();
+--- a/arch/arm64/kvm/vmid.c
++++ b/arch/arm64/kvm/vmid.c
+@@ -135,11 +135,10 @@ void kvm_arm_vmid_clear_active(void)
+ atomic64_set(this_cpu_ptr(&active_vmids), VMID_ACTIVE_INVALID);
+ }
+
+-bool kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
++void kvm_arm_vmid_update(struct kvm_vmid *kvm_vmid)
+ {
+ unsigned long flags;
+ u64 vmid, old_active_vmid;
+- bool updated = false;
+
+ vmid = atomic64_read(&kvm_vmid->id);
+
+@@ -157,21 +156,17 @@ bool kvm_arm_vmid_update(struct kvm_vmid
+ if (old_active_vmid != 0 && vmid_gen_match(vmid) &&
+ 0 != atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_vmids),
+ old_active_vmid, vmid))
+- return false;
++ return;
+
+ raw_spin_lock_irqsave(&cpu_vmid_lock, flags);
+
+ /* Check that our VMID belongs to the current generation. */
+ vmid = atomic64_read(&kvm_vmid->id);
+- if (!vmid_gen_match(vmid)) {
++ if (!vmid_gen_match(vmid))
+ vmid = new_vmid(kvm_vmid);
+- updated = true;
+- }
+
+ atomic64_set(this_cpu_ptr(&active_vmids), vmid);
+ raw_spin_unlock_irqrestore(&cpu_vmid_lock, flags);
+-
+- return updated;
+ }
+
+ /*
--- /dev/null
+From 982caaa1150479f022003390cd72a1941663d211 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <seanjc@google.com>
+Date: Mon, 24 Feb 2025 15:55:37 -0800
+Subject: KVM: nVMX: Process events on nested VM-Exit if injectable IRQ or NMI is pending
+
+From: Sean Christopherson <seanjc@google.com>
+
+commit 982caaa1150479f022003390cd72a1941663d211 upstream.
+
+Process pending events on nested VM-Exit if the vCPU has an injectable IRQ
+or NMI, as the event may have become pending while L2 was active, i.e. may
+not be tracked in the context of vmcs01. E.g. if L1 has passed its APIC
+through to L2 and an IRQ arrives while L2 is active, then KVM needs to
+request an IRQ window prior to running L1, otherwise delivery of the IRQ
+will be delayed until KVM happens to process events for some other reason.
+
+The missed failure is detected by vmx_apic_passthrough_tpr_threshold_test
+in KVM-Unit-Tests, but has effectively been masked due to a flaw in KVM's
+PIC emulation that causes KVM to make spurious KVM_REQ_EVENT requests (and
+apparently no one ever ran the test with split IRQ chips).
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Message-ID: <20250224235542.2562848-3-seanjc@google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/kvm/vmx/nested.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/arch/x86/kvm/vmx/nested.c
++++ b/arch/x86/kvm/vmx/nested.c
+@@ -5073,6 +5073,17 @@ void nested_vmx_vmexit(struct kvm_vcpu *
+
+ load_vmcs12_host_state(vcpu, vmcs12);
+
++ /*
++ * Process events if an injectable IRQ or NMI is pending, even
++ * if the event is blocked (RFLAGS.IF is cleared on VM-Exit).
++ * If an event became pending while L2 was active, KVM needs to
++ * either inject the event or request an IRQ/NMI window. SMIs
++ * don't need to be processed as SMM is mutually exclusive with
++ * non-root mode. INIT/SIPI don't need to be checked as INIT
++ * is blocked post-VMXON, and SIPIs are ignored.
++ */
++ if (kvm_cpu_has_injectable_intr(vcpu) || vcpu->arch.nmi_pending)
++ kvm_make_request(KVM_REQ_EVENT, vcpu);
+ return;
+ }
+
--- /dev/null
+From f865c24bc55158313d5779fc81116023a6940ca3 Mon Sep 17 00:00:00 2001
+From: Paolo Abeni <pabeni@redhat.com>
+Date: Mon, 24 Feb 2025 19:11:50 +0100
+Subject: mptcp: always handle address removal under msk socket lock
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+commit f865c24bc55158313d5779fc81116023a6940ca3 upstream.
+
+Syzkaller reported a lockdep splat in the PM control path:
+
+ WARNING: CPU: 0 PID: 6693 at ./include/net/sock.h:1711 sock_owned_by_me include/net/sock.h:1711 [inline]
+ WARNING: CPU: 0 PID: 6693 at ./include/net/sock.h:1711 msk_owned_by_me net/mptcp/protocol.h:363 [inline]
+ WARNING: CPU: 0 PID: 6693 at ./include/net/sock.h:1711 mptcp_pm_nl_addr_send_ack+0x57c/0x610 net/mptcp/pm_netlink.c:788
+ Modules linked in:
+ CPU: 0 UID: 0 PID: 6693 Comm: syz.0.205 Not tainted 6.14.0-rc2-syzkaller-00303-gad1b832bf1cf #0
+ Hardware name: Google Compute Engine/Google Compute Engine, BIOS Google 12/27/2024
+ RIP: 0010:sock_owned_by_me include/net/sock.h:1711 [inline]
+ RIP: 0010:msk_owned_by_me net/mptcp/protocol.h:363 [inline]
+ RIP: 0010:mptcp_pm_nl_addr_send_ack+0x57c/0x610 net/mptcp/pm_netlink.c:788
+ Code: 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc cc e8 ca 7b d3 f5 eb b9 e8 c3 7b d3 f5 90 0f 0b 90 e9 dd fb ff ff e8 b5 7b d3 f5 90 <0f> 0b 90 e9 3e fb ff ff 44 89 f1 80 e1 07 38 c1 0f 8c eb fb ff ff
+ RSP: 0000:ffffc900034f6f60 EFLAGS: 00010283
+ RAX: ffffffff8bee3c2b RBX: 0000000000000001 RCX: 0000000000080000
+ RDX: ffffc90004d42000 RSI: 000000000000a407 RDI: 000000000000a408
+ RBP: ffffc900034f7030 R08: ffffffff8bee37f6 R09: 0100000000000000
+ R10: dffffc0000000000 R11: ffffed100bcc62e4 R12: ffff88805e6316e0
+ R13: ffff88805e630c00 R14: dffffc0000000000 R15: ffff88805e630c00
+ FS: 00007f7e9a7e96c0(0000) GS:ffff8880b8600000(0000) knlGS:0000000000000000
+ CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 0000001b2fd18ff8 CR3: 0000000032c24000 CR4: 00000000003526f0
+ DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+ DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+ Call Trace:
+ <TASK>
+ mptcp_pm_remove_addr+0x103/0x1d0 net/mptcp/pm.c:59
+ mptcp_pm_remove_anno_addr+0x1f4/0x2f0 net/mptcp/pm_netlink.c:1486
+ mptcp_nl_remove_subflow_and_signal_addr net/mptcp/pm_netlink.c:1518 [inline]
+ mptcp_pm_nl_del_addr_doit+0x118d/0x1af0 net/mptcp/pm_netlink.c:1629
+ genl_family_rcv_msg_doit net/netlink/genetlink.c:1115 [inline]
+ genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
+ genl_rcv_msg+0xb1f/0xec0 net/netlink/genetlink.c:1210
+ netlink_rcv_skb+0x206/0x480 net/netlink/af_netlink.c:2543
+ genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
+ netlink_unicast_kernel net/netlink/af_netlink.c:1322 [inline]
+ netlink_unicast+0x7f6/0x990 net/netlink/af_netlink.c:1348
+ netlink_sendmsg+0x8de/0xcb0 net/netlink/af_netlink.c:1892
+ sock_sendmsg_nosec net/socket.c:718 [inline]
+ __sock_sendmsg+0x221/0x270 net/socket.c:733
+ ____sys_sendmsg+0x53a/0x860 net/socket.c:2573
+ ___sys_sendmsg net/socket.c:2627 [inline]
+ __sys_sendmsg+0x269/0x350 net/socket.c:2659
+ do_syscall_x64 arch/x86/entry/common.c:52 [inline]
+ do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
+ entry_SYSCALL_64_after_hwframe+0x77/0x7f
+ RIP: 0033:0x7f7e9998cde9
+ Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
+ RSP: 002b:00007f7e9a7e9038 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
+ RAX: ffffffffffffffda RBX: 00007f7e99ba5fa0 RCX: 00007f7e9998cde9
+ RDX: 000000002000c094 RSI: 0000400000000000 RDI: 0000000000000007
+ RBP: 00007f7e99a0e2a0 R08: 0000000000000000 R09: 0000000000000000
+ R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+ R13: 0000000000000000 R14: 00007f7e99ba5fa0 R15: 00007fff49231088
+
+Indeed the PM can try to send a RM_ADDR over a msk without acquiring
+first the msk socket lock.
+
+The bugged code-path comes from an early optimization: when there
+are no subflows, the PM should (usually) not send RM_ADDR
+notifications.
+
+The above statement is incorrect, as without locks another process
+could concurrent create a new subflow and cause the RM_ADDR generation.
+
+Additionally the supposed optimization is not very effective even
+performance-wise, as most mptcp sockets should have at least one
+subflow: the MPC one.
+
+Address the issue removing the buggy code path, the existing "slow-path"
+will handle correctly even the edge case.
+
+Fixes: b6c08380860b ("mptcp: remove addr and subflow in PM netlink")
+Cc: stable@vger.kernel.org
+Reported-by: syzbot+cd3ce3d03a3393ae9700@syzkaller.appspotmail.com
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/546
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20250224-net-mptcp-misc-fixes-v1-1-f550f636b435@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1514,11 +1514,6 @@ static int mptcp_nl_remove_subflow_and_s
+ if (mptcp_pm_is_userspace(msk))
+ goto next;
+
+- if (list_empty(&msk->conn_list)) {
+- mptcp_pm_remove_anno_addr(msk, addr, false);
+- goto next;
+- }
+-
+ lock_sock(sk);
+ remove_subflow = lookup_subflow_by_saddr(&msk->conn_list, addr);
+ mptcp_pm_remove_anno_addr(msk, addr, remove_subflow &&
--- /dev/null
+From 8668860b0ad32a13fcd6c94a0995b7aa7638c9ef Mon Sep 17 00:00:00 2001
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Mon, 24 Feb 2025 19:11:51 +0100
+Subject: mptcp: reset when MPTCP opts are dropped after join
+
+From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+
+commit 8668860b0ad32a13fcd6c94a0995b7aa7638c9ef upstream.
+
+Before this patch, if the checksum was not used, the subflow was only
+reset if map_data_len was != 0. If there were no MPTCP options or an
+invalid mapping, map_data_len was not set to the data len, and then the
+subflow was not reset as it should have been, leaving the MPTCP
+connection in a wrong fallback mode.
+
+This map_data_len condition has been introduced to handle the reception
+of the infinite mapping. Instead, a new dedicated mapping error could
+have been returned and treated as a special case. However, the commit
+31bf11de146c ("mptcp: introduce MAPPING_BAD_CSUM") has been introduced
+by Paolo Abeni soon after, and backported later on to stable. It better
+handle the csum case, and it means the exception for valid_csum_seen in
+subflow_can_fallback(), plus this one for the infinite mapping in
+subflow_check_data_avail(), are no longer needed.
+
+In other words, the code can be simplified there: a fallback should only
+be done if msk->allow_infinite_fallback is set. This boolean is set to
+false once MPTCP-specific operations acting on the whole MPTCP
+connection vs the initial path have been done, e.g. a second path has
+been created, or an MPTCP re-injection -- yes, possible even with a
+single subflow. The subflow_can_fallback() helper can then be dropped,
+and replaced by this single condition.
+
+This also makes the code clearer: a fallback should only be done if it
+is possible to do so.
+
+While at it, no need to set map_data_len to 0 in get_mapping_status()
+for the infinite mapping case: it will be set to skb->len just after, at
+the end of subflow_check_data_avail(), and not read in between.
+
+Fixes: f8d4bcacff3b ("mptcp: infinite mapping receiving")
+Cc: stable@vger.kernel.org
+Reported-by: Chester A. Unal <chester.a.unal@xpedite-tech.com>
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/544
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Tested-by: Chester A. Unal <chester.a.unal@xpedite-tech.com>
+Link: https://patch.msgid.link/20250224-net-mptcp-misc-fixes-v1-2-f550f636b435@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/subflow.c | 15 +--------------
+ 1 file changed, 1 insertion(+), 14 deletions(-)
+
+--- a/net/mptcp/subflow.c
++++ b/net/mptcp/subflow.c
+@@ -1142,7 +1142,6 @@ static enum mapping_status get_mapping_s
+ if (data_len == 0) {
+ pr_debug("infinite mapping received\n");
+ MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_INFINITEMAPRX);
+- subflow->map_data_len = 0;
+ return MAPPING_INVALID;
+ }
+
+@@ -1286,18 +1285,6 @@ static void subflow_sched_work_if_closed
+ mptcp_schedule_work(sk);
+ }
+
+-static bool subflow_can_fallback(struct mptcp_subflow_context *subflow)
+-{
+- struct mptcp_sock *msk = mptcp_sk(subflow->conn);
+-
+- if (subflow->mp_join)
+- return false;
+- else if (READ_ONCE(msk->csum_enabled))
+- return !subflow->valid_csum_seen;
+- else
+- return READ_ONCE(msk->allow_infinite_fallback);
+-}
+-
+ static void mptcp_subflow_fail(struct mptcp_sock *msk, struct sock *ssk)
+ {
+ struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
+@@ -1393,7 +1380,7 @@ fallback:
+ return true;
+ }
+
+- if (!subflow_can_fallback(subflow) && subflow->map_data_len) {
++ if (!READ_ONCE(msk->allow_infinite_fallback)) {
+ /* fatal protocol error, close the socket.
+ * subflow_error_report() will introduce the appropriate barriers
+ */
--- /dev/null
+From 8e43decdfbb477dd7800e3902d2d2f105d22ef5f Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:49 +0800
+Subject: net: enetc: add missing enetc4_link_deinit()
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit 8e43decdfbb477dd7800e3902d2d2f105d22ef5f upstream.
+
+The enetc4_link_init() is called when the PF driver probes to create
+phylink and MDIO bus, but we forgot to call enetc4_link_deinit() to
+free the phylink and MDIO bus when the driver was unbound. so add
+missing enetc4_link_deinit() to enetc4_pf_netdev_destroy().
+
+Fixes: 99100d0d9922 ("net: enetc: add preliminary support for i.MX95 ENETC PF")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-7-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc4_pf.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+@@ -683,6 +683,7 @@ static void enetc4_pf_netdev_destroy(str
+ struct net_device *ndev = si->ndev;
+
+ unregister_netdev(ndev);
++ enetc4_link_deinit(priv);
+ enetc_free_msix(priv);
+ free_netdev(ndev);
+ }
--- /dev/null
+From 432a2cb3ee97a7c6ea578888fe81baad035b9307 Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:46 +0800
+Subject: net: enetc: correct the xdp_tx statistics
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit 432a2cb3ee97a7c6ea578888fe81baad035b9307 upstream.
+
+The 'xdp_tx' is used to count the number of XDP_TX frames sent, not the
+number of Tx BDs.
+
+Fixes: 7ed2bc80074e ("net: enetc: add support for XDP_TX")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Ioana Ciornei <ioana.ciornei@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-4-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -1668,7 +1668,7 @@ static int enetc_clean_rx_ring_xdp(struc
+ enetc_xdp_drop(rx_ring, orig_i, i);
+ tx_ring->stats.xdp_tx_drops++;
+ } else {
+- tx_ring->stats.xdp_tx += xdp_tx_bd_cnt;
++ tx_ring->stats.xdp_tx++;
+ rx_ring->xdp.xdp_tx_in_flight += xdp_tx_bd_cnt;
+ xdp_tx_frm_cnt++;
+ /* The XDP_TX enqueue was successful, so we
--- /dev/null
+From 39ab773e4c120f7f98d759415ccc2aca706bbc10 Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:44 +0800
+Subject: net: enetc: fix the off-by-one issue in enetc_map_tx_buffs()
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit 39ab773e4c120f7f98d759415ccc2aca706bbc10 upstream.
+
+When a DMA mapping error occurs while processing skb frags, it will free
+one more tx_swbd than expected, so fix this off-by-one issue.
+
+Fixes: d4fd0404c1c9 ("enetc: Introduce basic PF and VF ENETC ethernet drivers")
+Cc: stable@vger.kernel.org
+Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Suggested-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-2-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 26 +++++++++++++++++++-------
+ 1 file changed, 19 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -146,6 +146,24 @@ static int enetc_ptp_parse(struct sk_buf
+ return 0;
+ }
+
++/**
++ * enetc_unwind_tx_frame() - Unwind the DMA mappings of a multi-buffer Tx frame
++ * @tx_ring: Pointer to the Tx ring on which the buffer descriptors are located
++ * @count: Number of Tx buffer descriptors which need to be unmapped
++ * @i: Index of the last successfully mapped Tx buffer descriptor
++ */
++static void enetc_unwind_tx_frame(struct enetc_bdr *tx_ring, int count, int i)
++{
++ while (count--) {
++ struct enetc_tx_swbd *tx_swbd = &tx_ring->tx_swbd[i];
++
++ enetc_free_tx_frame(tx_ring, tx_swbd);
++ if (i == 0)
++ i = tx_ring->bd_count;
++ i--;
++ }
++}
++
+ static int enetc_map_tx_buffs(struct enetc_bdr *tx_ring, struct sk_buff *skb)
+ {
+ bool do_vlan, do_onestep_tstamp = false, do_twostep_tstamp = false;
+@@ -329,13 +347,7 @@ static int enetc_map_tx_buffs(struct ene
+ dma_err:
+ dev_err(tx_ring->dev, "DMA map error");
+
+- do {
+- tx_swbd = &tx_ring->tx_swbd[i];
+- enetc_free_tx_frame(tx_ring, tx_swbd);
+- if (i == 0)
+- i = tx_ring->bd_count;
+- i--;
+- } while (count--);
++ enetc_unwind_tx_frame(tx_ring, count, i);
+
+ return 0;
+ }
--- /dev/null
+From 249df695c3ffe8c8d36d46c2580ce72410976f96 Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:51 +0800
+Subject: net: enetc: fix the off-by-one issue in enetc_map_tx_tso_buffs()
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit 249df695c3ffe8c8d36d46c2580ce72410976f96 upstream.
+
+There is an off-by-one issue for the err_chained_bd path, it will free
+one more tx_swbd than expected. But there is no such issue for the
+err_map_data path. To fix this off-by-one issue and make the two error
+handling consistent, the increment of 'i' and 'count' remain in sync
+and enetc_unwind_tx_frame() is called for error handling.
+
+Fixes: fb8629e2cbfc ("net: enetc: add support for software TSO")
+Cc: stable@vger.kernel.org
+Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-9-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -591,8 +591,13 @@ static int enetc_map_tx_tso_buffs(struct
+ err = enetc_map_tx_tso_data(tx_ring, skb, tx_swbd, txbd,
+ tso.data, size,
+ size == data_len);
+- if (err)
++ if (err) {
++ if (i == 0)
++ i = tx_ring->bd_count;
++ i--;
++
+ goto err_map_data;
++ }
+
+ data_len -= size;
+ count++;
+@@ -621,13 +626,7 @@ err_map_data:
+ dev_err(tx_ring->dev, "DMA map error");
+
+ err_chained_bd:
+- do {
+- tx_swbd = &tx_ring->tx_swbd[i];
+- enetc_free_tx_frame(tx_ring, tx_swbd);
+- if (i == 0)
+- i = tx_ring->bd_count;
+- i--;
+- } while (count--);
++ enetc_unwind_tx_frame(tx_ring, count, i);
+
+ return 0;
+ }
--- /dev/null
+From da291996b16ebd10626d4b20288327b743aff110 Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:45 +0800
+Subject: net: enetc: keep track of correct Tx BD count in enetc_map_tx_tso_buffs()
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit da291996b16ebd10626d4b20288327b743aff110 upstream.
+
+When creating a TSO header, if the skb is VLAN tagged, the extended BD
+will be used and the 'count' should be increased by 2 instead of 1.
+Otherwise, when an error occurs, less tx_swbd will be freed than the
+actual number.
+
+Fixes: fb8629e2cbfc ("net: enetc: add support for software TSO")
+Cc: stable@vger.kernel.org
+Suggested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Claudiu Manoil <claudiu.manoil@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-3-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -352,14 +352,15 @@ dma_err:
+ return 0;
+ }
+
+-static void enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
+- struct enetc_tx_swbd *tx_swbd,
+- union enetc_tx_bd *txbd, int *i, int hdr_len,
+- int data_len)
++static int enetc_map_tx_tso_hdr(struct enetc_bdr *tx_ring, struct sk_buff *skb,
++ struct enetc_tx_swbd *tx_swbd,
++ union enetc_tx_bd *txbd, int *i, int hdr_len,
++ int data_len)
+ {
+ union enetc_tx_bd txbd_tmp;
+ u8 flags = 0, e_flags = 0;
+ dma_addr_t addr;
++ int count = 1;
+
+ enetc_clear_tx_bd(&txbd_tmp);
+ addr = tx_ring->tso_headers_dma + *i * TSO_HEADER_SIZE;
+@@ -402,7 +403,10 @@ static void enetc_map_tx_tso_hdr(struct
+ /* Write the BD */
+ txbd_tmp.ext.e_flags = e_flags;
+ *txbd = txbd_tmp;
++ count++;
+ }
++
++ return count;
+ }
+
+ static int enetc_map_tx_tso_data(struct enetc_bdr *tx_ring, struct sk_buff *skb,
+@@ -534,9 +538,9 @@ static int enetc_map_tx_tso_buffs(struct
+
+ /* compute the csum over the L4 header */
+ csum = enetc_tso_hdr_csum(&tso, skb, hdr, hdr_len, &pos);
+- enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd, &i, hdr_len, data_len);
++ count += enetc_map_tx_tso_hdr(tx_ring, skb, tx_swbd, txbd,
++ &i, hdr_len, data_len);
+ bd_data_num = 0;
+- count++;
+
+ while (data_len > 0) {
+ int size;
--- /dev/null
+From 119049b66b883c7e7e575a0b69dc6e3d211662cc Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:50 +0800
+Subject: net: enetc: remove the mm_lock from the ENETC v4 driver
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit 119049b66b883c7e7e575a0b69dc6e3d211662cc upstream.
+
+Currently, the ENETC v4 driver has not added the MAC merge layer support
+in the upstream, so the mm_lock is not initialized and used, so remove
+the mm_lock from the driver.
+
+Fixes: 99100d0d9922 ("net: enetc: add preliminary support for i.MX95 ENETC PF")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-8-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc4_pf.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c
+@@ -672,7 +672,6 @@ err_link_init:
+ err_alloc_msix:
+ err_config_si:
+ err_clk_get:
+- mutex_destroy(&priv->mm_lock);
+ free_netdev(ndev);
+
+ return err;
--- /dev/null
+From bbcbc906ab7b5834c1219cd17a38d78dba904aa0 Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:48 +0800
+Subject: net: enetc: update UDP checksum when updating originTimestamp field
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit bbcbc906ab7b5834c1219cd17a38d78dba904aa0 upstream.
+
+There is an issue with one-step timestamp based on UDP/IP. The peer will
+discard the sync packet because of the wrong UDP checksum. For ENETC v1,
+the software needs to update the UDP checksum when updating the
+originTimestamp field, so that the hardware can correctly update the UDP
+checksum when updating the correction field. Otherwise, the UDP checksum
+in the sync packet will be wrong.
+
+Fixes: 7294380c5211 ("enetc: support PTP Sync packet one-step timestamping")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-6-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 41 ++++++++++++++++++++++-----
+ 1 file changed, 34 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -254,9 +254,11 @@ static int enetc_map_tx_buffs(struct ene
+ }
+
+ if (do_onestep_tstamp) {
+- u32 lo, hi, val;
+- u64 sec, nsec;
++ __be32 new_sec_l, new_nsec;
++ u32 lo, hi, nsec, val;
++ __be16 new_sec_h;
+ u8 *data;
++ u64 sec;
+
+ lo = enetc_rd_hot(hw, ENETC_SICTR0);
+ hi = enetc_rd_hot(hw, ENETC_SICTR1);
+@@ -270,13 +272,38 @@ static int enetc_map_tx_buffs(struct ene
+ /* Update originTimestamp field of Sync packet
+ * - 48 bits seconds field
+ * - 32 bits nanseconds field
++ *
++ * In addition, the UDP checksum needs to be updated
++ * by software after updating originTimestamp field,
++ * otherwise the hardware will calculate the wrong
++ * checksum when updating the correction field and
++ * update it to the packet.
+ */
+ data = skb_mac_header(skb);
+- *(__be16 *)(data + offset2) =
+- htons((sec >> 32) & 0xffff);
+- *(__be32 *)(data + offset2 + 2) =
+- htonl(sec & 0xffffffff);
+- *(__be32 *)(data + offset2 + 6) = htonl(nsec);
++ new_sec_h = htons((sec >> 32) & 0xffff);
++ new_sec_l = htonl(sec & 0xffffffff);
++ new_nsec = htonl(nsec);
++ if (udp) {
++ struct udphdr *uh = udp_hdr(skb);
++ __be32 old_sec_l, old_nsec;
++ __be16 old_sec_h;
++
++ old_sec_h = *(__be16 *)(data + offset2);
++ inet_proto_csum_replace2(&uh->check, skb, old_sec_h,
++ new_sec_h, false);
++
++ old_sec_l = *(__be32 *)(data + offset2 + 2);
++ inet_proto_csum_replace4(&uh->check, skb, old_sec_l,
++ new_sec_l, false);
++
++ old_nsec = *(__be32 *)(data + offset2 + 6);
++ inet_proto_csum_replace4(&uh->check, skb, old_nsec,
++ new_nsec, false);
++ }
++
++ *(__be16 *)(data + offset2) = new_sec_h;
++ *(__be32 *)(data + offset2 + 2) = new_sec_l;
++ *(__be32 *)(data + offset2 + 6) = new_nsec;
+
+ /* Configure single-step register */
+ val = ENETC_PM0_SINGLE_STEP_EN;
--- /dev/null
+From a562d0c4a893eae3ea51d512c4d90ab858a6b7ec Mon Sep 17 00:00:00 2001
+From: Wei Fang <wei.fang@nxp.com>
+Date: Mon, 24 Feb 2025 19:12:47 +0800
+Subject: net: enetc: VFs do not support HWTSTAMP_TX_ONESTEP_SYNC
+
+From: Wei Fang <wei.fang@nxp.com>
+
+commit a562d0c4a893eae3ea51d512c4d90ab858a6b7ec upstream.
+
+Actually ENETC VFs do not support HWTSTAMP_TX_ONESTEP_SYNC because only
+ENETC PF can access PMa_SINGLE_STEP registers. And there will be a crash
+if VFs are used to test one-step timestamp, the crash log as follows.
+
+[ 129.110909] Unable to handle kernel paging request at virtual address 00000000000080c0
+[ 129.287769] Call trace:
+[ 129.290219] enetc_port_mac_wr+0x30/0xec (P)
+[ 129.294504] enetc_start_xmit+0xda4/0xe74
+[ 129.298525] enetc_xmit+0x70/0xec
+[ 129.301848] dev_hard_start_xmit+0x98/0x118
+
+Fixes: 41514737ecaa ("enetc: add get_ts_info interface for ethtool")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wei Fang <wei.fang@nxp.com>
+Reviewed-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250224111251.1061098-5-wei.fang@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/freescale/enetc/enetc.c | 3 +++
+ drivers/net/ethernet/freescale/enetc/enetc_ethtool.c | 7 +++++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/enetc/enetc.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc.c
+@@ -2954,6 +2954,9 @@ static int enetc_hwtstamp_set(struct net
+ new_offloads |= ENETC_F_TX_TSTAMP;
+ break;
+ case HWTSTAMP_TX_ONESTEP_SYNC:
++ if (!enetc_si_is_pf(priv->si))
++ return -EOPNOTSUPP;
++
+ new_offloads &= ~ENETC_F_TX_TSTAMP_MASK;
+ new_offloads |= ENETC_F_TX_ONESTEP_SYNC_TSTAMP;
+ break;
+--- a/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
++++ b/drivers/net/ethernet/freescale/enetc/enetc_ethtool.c
+@@ -832,6 +832,7 @@ static int enetc_set_coalesce(struct net
+ static int enetc_get_ts_info(struct net_device *ndev,
+ struct kernel_ethtool_ts_info *info)
+ {
++ struct enetc_ndev_priv *priv = netdev_priv(ndev);
+ int *phc_idx;
+
+ phc_idx = symbol_get(enetc_phc_index);
+@@ -852,8 +853,10 @@ static int enetc_get_ts_info(struct net_
+ SOF_TIMESTAMPING_TX_SOFTWARE;
+
+ info->tx_types = (1 << HWTSTAMP_TX_OFF) |
+- (1 << HWTSTAMP_TX_ON) |
+- (1 << HWTSTAMP_TX_ONESTEP_SYNC);
++ (1 << HWTSTAMP_TX_ON);
++
++ if (enetc_si_is_pf(priv->si))
++ info->tx_types |= (1 << HWTSTAMP_TX_ONESTEP_SYNC);
+
+ info->rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
+ (1 << HWTSTAMP_FILTER_ALL);
--- /dev/null
+From 992ee3ed6e9fdd0be83a7daa5ff738e3cf86047f Mon Sep 17 00:00:00 2001
+From: George Moussalem <george.moussalem@outlook.com>
+Date: Wed, 19 Feb 2025 14:09:21 +0100
+Subject: net: phy: qcom: qca807x fix condition for DAC_DSP_BIAS_CURRENT
+
+From: George Moussalem <george.moussalem@outlook.com>
+
+commit 992ee3ed6e9fdd0be83a7daa5ff738e3cf86047f upstream.
+
+While setting the DAC value, the wrong boolean value is evaluated to set
+the DSP bias current. So let's correct the conditional statement and use
+the right boolean value read from the DTS set in the priv.
+
+Cc: stable@vger.kernel.org
+Fixes: d1cb613efbd3 ("net: phy: qcom: add support for QCA807x PHY Family")
+Signed-off-by: George Moussalem <george.moussalem@outlook.com>
+Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Link: https://patch.msgid.link/20250219130923.7216-1-ansuelsmth@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/phy/qcom/qca807x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/phy/qcom/qca807x.c
++++ b/drivers/net/phy/qcom/qca807x.c
+@@ -774,7 +774,7 @@ static int qca807x_config_init(struct ph
+ control_dac &= ~QCA807X_CONTROL_DAC_MASK;
+ if (!priv->dac_full_amplitude)
+ control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE;
+- if (!priv->dac_full_amplitude)
++ if (!priv->dac_full_bias_current)
+ control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT;
+ if (!priv->dac_disable_bias_current_tweak)
+ control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK;
--- /dev/null
+From f06e4bfd010faefa637689d2df2c727dbf6e1d27 Mon Sep 17 00:00:00 2001
+From: Qunqin Zhao <zhaoqunqin@loongson.cn>
+Date: Wed, 19 Feb 2025 10:07:01 +0800
+Subject: net: stmmac: dwmac-loongson: Add fix_soc_reset() callback
+
+From: Qunqin Zhao <zhaoqunqin@loongson.cn>
+
+commit f06e4bfd010faefa637689d2df2c727dbf6e1d27 upstream.
+
+Loongson's DWMAC device may take nearly two seconds to complete DMA reset,
+however, the default waiting time for reset is 200 milliseconds.
+Therefore, the following error message may appear:
+
+[14.427169] dwmac-loongson-pci 0000:00:03.2: Failed to reset the dma
+
+Fixes: 803fc61df261 ("net: stmmac: dwmac-loongson: Add Loongson Multi-channels GMAC support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Qunqin Zhao <zhaoqunqin@loongson.cn>
+Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Acked-by: Yanteng Si <si.yanteng@linux.dev>
+Link: https://patch.msgid.link/20250219020701.15139-1-zhaoqunqin@loongson.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c
+@@ -516,6 +516,19 @@ static int loongson_dwmac_acpi_config(st
+ return 0;
+ }
+
++/* Loongson's DWMAC device may take nearly two seconds to complete DMA reset */
++static int loongson_dwmac_fix_reset(void *priv, void __iomem *ioaddr)
++{
++ u32 value = readl(ioaddr + DMA_BUS_MODE);
++
++ value |= DMA_BUS_MODE_SFT_RESET;
++ writel(value, ioaddr + DMA_BUS_MODE);
++
++ return readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
++ !(value & DMA_BUS_MODE_SFT_RESET),
++ 10000, 2000000);
++}
++
+ static int loongson_dwmac_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+ struct plat_stmmacenet_data *plat;
+@@ -566,6 +579,7 @@ static int loongson_dwmac_probe(struct p
+
+ plat->bsp_priv = ld;
+ plat->setup = loongson_dwmac_setup;
++ plat->fix_soc_reset = loongson_dwmac_fix_reset;
+ ld->dev = &pdev->dev;
+ ld->loongson_id = readl(res.addr + GMAC_VERSION) & 0xff;
+
--- /dev/null
+From 0fe8813baf4b2e865d3b2c735ce1a15b86002c74 Mon Sep 17 00:00:00 2001
+From: Breno Leitao <leitao@debian.org>
+Date: Fri, 17 Jan 2025 06:41:07 -0800
+Subject: perf/core: Add RCU read lock protection to perf_iterate_ctx()
+
+From: Breno Leitao <leitao@debian.org>
+
+commit 0fe8813baf4b2e865d3b2c735ce1a15b86002c74 upstream.
+
+The perf_iterate_ctx() function performs RCU list traversal but
+currently lacks RCU read lock protection. This causes lockdep warnings
+when running perf probe with unshare(1) under CONFIG_PROVE_RCU_LIST=y:
+
+ WARNING: suspicious RCU usage
+ kernel/events/core.c:8168 RCU-list traversed in non-reader section!!
+
+ Call Trace:
+ lockdep_rcu_suspicious
+ ? perf_event_addr_filters_apply
+ perf_iterate_ctx
+ perf_event_exec
+ begin_new_exec
+ ? load_elf_phdrs
+ load_elf_binary
+ ? lock_acquire
+ ? find_held_lock
+ ? bprm_execve
+ bprm_execve
+ do_execveat_common.isra.0
+ __x64_sys_execve
+ do_syscall_64
+ entry_SYSCALL_64_after_hwframe
+
+This protection was previously present but was removed in commit
+bd2756811766 ("perf: Rewrite core context handling"). Add back the
+necessary rcu_read_lock()/rcu_read_unlock() pair around
+perf_iterate_ctx() call in perf_event_exec().
+
+[ mingo: Use scoped_guard() as suggested by Peter ]
+
+Fixes: bd2756811766 ("perf: Rewrite core context handling")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250117-fix_perf_rcu-v1-1-13cb9210fc6a@debian.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/events/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -8284,7 +8284,8 @@ void perf_event_exec(void)
+
+ perf_event_enable_on_exec(ctx);
+ perf_event_remove_on_exec(ctx);
+- perf_iterate_ctx(ctx, perf_event_addr_filters_exec, NULL, true);
++ scoped_guard(rcu)
++ perf_iterate_ctx(ctx, perf_event_addr_filters_exec, NULL, true);
+
+ perf_unpin_context(ctx);
+ put_ctx(ctx);
--- /dev/null
+From 0d39844150546fa1415127c5fbae26db64070dd3 Mon Sep 17 00:00:00 2001
+From: Kan Liang <kan.liang@linux.intel.com>
+Date: Fri, 17 Jan 2025 07:19:12 -0800
+Subject: perf/core: Fix low freq setting via IOC_PERIOD
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+commit 0d39844150546fa1415127c5fbae26db64070dd3 upstream.
+
+A low attr::freq value cannot be set via IOC_PERIOD on some platforms.
+
+The perf_event_check_period() introduced in:
+
+ 81ec3f3c4c4d ("perf/x86: Add check_period PMU callback")
+
+was intended to check the period, rather than the frequency.
+A low frequency may be mistakenly rejected by limit_period().
+
+Fix it.
+
+Fixes: 81ec3f3c4c4d ("perf/x86: Add check_period PMU callback")
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250117151913.3043942-2-kan.liang@linux.intel.com
+Closes: https://lore.kernel.org/lkml/20250115154949.3147-1-ravi.bangoria@amd.com/
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/events/core.c | 17 +++++++++--------
+ 1 file changed, 9 insertions(+), 8 deletions(-)
+
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -5969,14 +5969,15 @@ static int _perf_event_period(struct per
+ if (!value)
+ return -EINVAL;
+
+- if (event->attr.freq && value > sysctl_perf_event_sample_rate)
+- return -EINVAL;
+-
+- if (perf_event_check_period(event, value))
+- return -EINVAL;
+-
+- if (!event->attr.freq && (value & (1ULL << 63)))
+- return -EINVAL;
++ if (event->attr.freq) {
++ if (value > sysctl_perf_event_sample_rate)
++ return -EINVAL;
++ } else {
++ if (perf_event_check_period(event, value))
++ return -EINVAL;
++ if (value & (1ULL << 63))
++ return -EINVAL;
++ }
+
+ event_function_call(event, __perf_event_period, &value);
+
--- /dev/null
+From 88ec7eedbbd21cad38707620ad6c48a4e9a87c18 Mon Sep 17 00:00:00 2001
+From: Kan Liang <kan.liang@linux.intel.com>
+Date: Fri, 17 Jan 2025 07:19:11 -0800
+Subject: perf/x86: Fix low freqency setting issue
+
+From: Kan Liang <kan.liang@linux.intel.com>
+
+commit 88ec7eedbbd21cad38707620ad6c48a4e9a87c18 upstream.
+
+Perf doesn't work at low frequencies:
+
+ $ perf record -e cpu_core/instructions/ppp -F 120
+ Error:
+ The sys_perf_event_open() syscall returned with 22 (Invalid argument)
+ for event (cpu_core/instructions/ppp).
+ "dmesg | grep -i perf" may provide additional information.
+
+The limit_period() check avoids a low sampling period on a counter. It
+doesn't intend to limit the frequency.
+
+The check in the x86_pmu_hw_config() should be limited to non-freq mode.
+The attr.sample_period and attr.sample_freq are union. The
+attr.sample_period should not be used to indicate the frequency mode.
+
+Fixes: c46e665f0377 ("perf/x86: Add INST_RETIRED.ALL workarounds")
+Signed-off-by: Kan Liang <kan.liang@linux.intel.com>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250117151913.3043942-1-kan.liang@linux.intel.com
+Closes: https://lore.kernel.org/lkml/20250115154949.3147-1-ravi.bangoria@amd.com/
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/events/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -628,7 +628,7 @@ int x86_pmu_hw_config(struct perf_event
+ if (event->attr.type == event->pmu->type)
+ event->hw.config |= x86_pmu_get_event_config(event);
+
+- if (event->attr.sample_period && x86_pmu.limit_period) {
++ if (!event->attr.freq && x86_pmu.limit_period) {
+ s64 left = event->attr.sample_period;
+ x86_pmu.limit_period(event, &left);
+ if (left > event->attr.sample_period)
--- /dev/null
+From e2158c953c973adb49383ddea2504faf08d375b7 Mon Sep 17 00:00:00 2001
+From: Kaustabh Chakraborty <kauschluss@disroot.org>
+Date: Sun, 9 Feb 2025 00:29:30 +0530
+Subject: phy: exynos5-usbdrd: fix MPLL_MULTIPLIER and SSC_REFCLKSEL masks in refclk
+
+From: Kaustabh Chakraborty <kauschluss@disroot.org>
+
+commit e2158c953c973adb49383ddea2504faf08d375b7 upstream.
+
+In exynos5_usbdrd_{pipe3,utmi}_set_refclk(), the masks
+PHYCLKRST_MPLL_MULTIPLIER_MASK and PHYCLKRST_SSC_REFCLKSEL_MASK are not
+inverted when applied to the register values. Fix it.
+
+Cc: stable@vger.kernel.org
+Fixes: 59025887fb08 ("phy: Add new Exynos5 USB 3.0 PHY driver")
+Signed-off-by: Kaustabh Chakraborty <kauschluss@disroot.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Anand Moon <linux.amoon@gmail.com>
+Link: https://lore.kernel.org/r/20250209-exynos5-usbdrd-masks-v1-1-4f7f83f323d7@disroot.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/samsung/phy-exynos5-usbdrd.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
++++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
+@@ -488,9 +488,9 @@ exynos5_usbdrd_pipe3_set_refclk(struct p
+ reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK;
+
+ /* FSEL settings corresponding to reference clock */
+- reg &= ~PHYCLKRST_FSEL_PIPE_MASK |
+- PHYCLKRST_MPLL_MULTIPLIER_MASK |
+- PHYCLKRST_SSC_REFCLKSEL_MASK;
++ reg &= ~(PHYCLKRST_FSEL_PIPE_MASK |
++ PHYCLKRST_MPLL_MULTIPLIER_MASK |
++ PHYCLKRST_SSC_REFCLKSEL_MASK);
+ switch (phy_drd->extrefclk) {
+ case EXYNOS5_FSEL_50MHZ:
+ reg |= (PHYCLKRST_MPLL_MULTIPLIER_50M_REF |
+@@ -532,9 +532,9 @@ exynos5_usbdrd_utmi_set_refclk(struct ph
+ reg &= ~PHYCLKRST_REFCLKSEL_MASK;
+ reg |= PHYCLKRST_REFCLKSEL_EXT_REFCLK;
+
+- reg &= ~PHYCLKRST_FSEL_UTMI_MASK |
+- PHYCLKRST_MPLL_MULTIPLIER_MASK |
+- PHYCLKRST_SSC_REFCLKSEL_MASK;
++ reg &= ~(PHYCLKRST_FSEL_UTMI_MASK |
++ PHYCLKRST_MPLL_MULTIPLIER_MASK |
++ PHYCLKRST_SSC_REFCLKSEL_MASK);
+ reg |= PHYCLKRST_FSEL(phy_drd->extrefclk);
+
+ return reg;
--- /dev/null
+From 8789b4296aa796f658a19cac7d27365012893de1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andr=C3=A9=20Draszik?= <andre.draszik@linaro.org>
+Date: Thu, 5 Dec 2024 10:22:00 +0000
+Subject: phy: exynos5-usbdrd: gs101: ensure power is gated to SS phy in phy_exit()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: André Draszik <andre.draszik@linaro.org>
+
+commit 8789b4296aa796f658a19cac7d27365012893de1 upstream.
+
+We currently don't gate the power to the SS phy in phy_exit().
+
+Shuffle the code slightly to ensure the power is gated to the SS phy as
+well.
+
+Fixes: 32267c29bc7d ("phy: exynos5-usbdrd: support Exynos USBDRD 3.1 combo phy (HS & SS)")
+CC: stable@vger.kernel.org # 6.11+
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Reviewed-by: Peter Griffin <peter.griffin@linaro.org>
+Signed-off-by: André Draszik <andre.draszik@linaro.org>
+Link: https://lore.kernel.org/r/20241205-gs101-usb-phy-fix-v4-1-0278809fb810@linaro.org
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/samsung/phy-exynos5-usbdrd.c | 13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/drivers/phy/samsung/phy-exynos5-usbdrd.c
++++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c
+@@ -1296,14 +1296,17 @@ static int exynos5_usbdrd_gs101_phy_exit
+ struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst);
+ int ret;
+
++ if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) {
++ ret = exynos850_usbdrd_phy_exit(phy);
++ if (ret)
++ return ret;
++ }
++
++ exynos5_usbdrd_phy_isol(inst, true);
++
+ if (inst->phy_cfg->id != EXYNOS5_DRDPHY_UTMI)
+ return 0;
+
+- ret = exynos850_usbdrd_phy_exit(phy);
+- if (ret)
+- return ret;
+-
+- exynos5_usbdrd_phy_isol(inst, true);
+ return regulator_bulk_disable(phy_drd->drv_data->n_regulators,
+ phy_drd->regulators);
+ }
--- /dev/null
+From 55f1a5f7c97c3c92ba469e16991a09274410ceb7 Mon Sep 17 00:00:00 2001
+From: BH Hsieh <bhsieh@nvidia.com>
+Date: Wed, 22 Jan 2025 18:59:43 +0800
+Subject: phy: tegra: xusb: reset VBUS & ID OVERRIDE
+
+From: BH Hsieh <bhsieh@nvidia.com>
+
+commit 55f1a5f7c97c3c92ba469e16991a09274410ceb7 upstream.
+
+Observed VBUS_OVERRIDE & ID_OVERRIDE might be programmed
+with unexpected value prior to XUSB PADCTL driver, this
+could also occur in virtualization scenario.
+
+For example, UEFI firmware programs ID_OVERRIDE=GROUNDED to set
+a type-c port to host mode and keeps the value to kernel.
+If the type-c port is connected a usb host, below errors can be
+observed right after usb host mode driver gets probed. The errors
+would keep until usb role class driver detects the type-c port
+as device mode and notifies usb device mode driver to set both
+ID_OVERRIDE and VBUS_OVERRIDE to correct value by XUSB PADCTL
+driver.
+
+[ 173.765814] usb usb3-port2: Cannot enable. Maybe the USB cable is bad?
+[ 173.765837] usb usb3-port2: config error
+
+Taking virtualization into account, asserting XUSB PADCTL
+reset would break XUSB functions used by other guest OS,
+hence only reset VBUS & ID OVERRIDE of the port in
+utmi_phy_init.
+
+Fixes: bbf711682cd5 ("phy: tegra: xusb: Add Tegra186 support")
+Cc: stable@vger.kernel.org
+Change-Id: Ic63058d4d49b4a1f8f9ab313196e20ad131cc591
+Signed-off-by: BH Hsieh <bhsieh@nvidia.com>
+Signed-off-by: Henry Lin <henryl@nvidia.com>
+Link: https://lore.kernel.org/r/20250122105943.8057-1-henryl@nvidia.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/tegra/xusb-tegra186.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/phy/tegra/xusb-tegra186.c
++++ b/drivers/phy/tegra/xusb-tegra186.c
+@@ -928,6 +928,7 @@ static int tegra186_utmi_phy_init(struct
+ unsigned int index = lane->index;
+ struct device *dev = padctl->dev;
+ int err;
++ u32 reg;
+
+ port = tegra_xusb_find_usb2_port(padctl, index);
+ if (!port) {
+@@ -935,6 +936,16 @@ static int tegra186_utmi_phy_init(struct
+ return -ENODEV;
+ }
+
++ if (port->mode == USB_DR_MODE_OTG ||
++ port->mode == USB_DR_MODE_PERIPHERAL) {
++ /* reset VBUS&ID OVERRIDE */
++ reg = padctl_readl(padctl, USB2_VBUS_ID);
++ reg &= ~VBUS_OVERRIDE;
++ reg &= ~ID_OVERRIDE(~0);
++ reg |= ID_OVERRIDE_FLOATING;
++ padctl_writel(padctl, reg, USB2_VBUS_ID);
++ }
++
+ if (port->supply && port->mode == USB_DR_MODE_HOST) {
+ err = regulator_enable(port->supply);
+ if (err) {
--- /dev/null
+From b9a49520679e98700d3d89689cc91c08a1c88c1d Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sun, 19 Jan 2025 00:55:32 +0100
+Subject: rcuref: Plug slowpath race in rcuref_put()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit b9a49520679e98700d3d89689cc91c08a1c88c1d upstream.
+
+Kernel test robot reported an "imbalanced put" in the rcuref_put() slow
+path, which turned out to be a false positive. Consider the following race:
+
+ ref = 0 (via rcuref_init(ref, 1))
+ T1 T2
+ rcuref_put(ref)
+ -> atomic_add_negative_release(-1, ref) # ref -> 0xffffffff
+ -> rcuref_put_slowpath(ref)
+ rcuref_get(ref)
+ -> atomic_add_negative_relaxed(1, &ref->refcnt)
+ -> return true; # ref -> 0
+
+ rcuref_put(ref)
+ -> atomic_add_negative_release(-1, ref) # ref -> 0xffffffff
+ -> rcuref_put_slowpath()
+
+ -> cnt = atomic_read(&ref->refcnt); # cnt -> 0xffffffff / RCUREF_NOREF
+ -> atomic_try_cmpxchg_release(&ref->refcnt, &cnt, RCUREF_DEAD)) # ref -> 0xe0000000 / RCUREF_DEAD
+ -> return true
+ -> cnt = atomic_read(&ref->refcnt); # cnt -> 0xe0000000 / RCUREF_DEAD
+ -> if (cnt > RCUREF_RELEASED) # 0xe0000000 > 0xc0000000
+ -> WARN_ONCE(cnt >= RCUREF_RELEASED, "rcuref - imbalanced put()")
+
+The problem is the additional read in the slow path (after it
+decremented to RCUREF_NOREF) which can happen after the counter has been
+marked RCUREF_DEAD.
+
+Prevent this by reusing the return value of the decrement. Now every "final"
+put uses RCUREF_NOREF in the slow path and attempts the final cmpxchg() to
+RCUREF_DEAD.
+
+[ bigeasy: Add changelog ]
+
+Fixes: ee1ee6db07795 ("atomics: Provide rcuref - scalable reference counting")
+Reported-by: kernel test robot <oliver.sang@intel.com>
+Debugged-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Cc: stable@vger.kernel.org
+Closes: https://lore.kernel.org/oe-lkp/202412311453.9d7636a2-lkp@intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/rcuref.h | 9 ++++++---
+ lib/rcuref.c | 5 ++---
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+--- a/include/linux/rcuref.h
++++ b/include/linux/rcuref.h
+@@ -71,27 +71,30 @@ static inline __must_check bool rcuref_g
+ return rcuref_get_slowpath(ref);
+ }
+
+-extern __must_check bool rcuref_put_slowpath(rcuref_t *ref);
++extern __must_check bool rcuref_put_slowpath(rcuref_t *ref, unsigned int cnt);
+
+ /*
+ * Internal helper. Do not invoke directly.
+ */
+ static __always_inline __must_check bool __rcuref_put(rcuref_t *ref)
+ {
++ int cnt;
++
+ RCU_LOCKDEP_WARN(!rcu_read_lock_held() && preemptible(),
+ "suspicious rcuref_put_rcusafe() usage");
+ /*
+ * Unconditionally decrease the reference count. The saturation and
+ * dead zones provide enough tolerance for this.
+ */
+- if (likely(!atomic_add_negative_release(-1, &ref->refcnt)))
++ cnt = atomic_sub_return_release(1, &ref->refcnt);
++ if (likely(cnt >= 0))
+ return false;
+
+ /*
+ * Handle the last reference drop and cases inside the saturation
+ * and dead zones.
+ */
+- return rcuref_put_slowpath(ref);
++ return rcuref_put_slowpath(ref, cnt);
+ }
+
+ /**
+--- a/lib/rcuref.c
++++ b/lib/rcuref.c
+@@ -220,6 +220,7 @@ EXPORT_SYMBOL_GPL(rcuref_get_slowpath);
+ /**
+ * rcuref_put_slowpath - Slowpath of __rcuref_put()
+ * @ref: Pointer to the reference count
++ * @cnt: The resulting value of the fastpath decrement
+ *
+ * Invoked when the reference count is outside of the valid zone.
+ *
+@@ -233,10 +234,8 @@ EXPORT_SYMBOL_GPL(rcuref_get_slowpath);
+ * with a concurrent get()/put() pair. Caller is not allowed to
+ * deconstruct the protected object.
+ */
+-bool rcuref_put_slowpath(rcuref_t *ref)
++bool rcuref_put_slowpath(rcuref_t *ref, unsigned int cnt)
+ {
+- unsigned int cnt = atomic_read(&ref->refcnt);
+-
+ /* Did this drop the last reference? */
+ if (likely(cnt == RCUREF_NOREF)) {
+ /*
--- /dev/null
+From 1898300abf3508bca152e65b36cce5bf93d7e63e Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Thu, 30 Jan 2025 10:25:38 +0100
+Subject: riscv/atomic: Do proper sign extension also for unsigned in arch_cmpxchg
+
+From: Andreas Schwab <schwab@suse.de>
+
+commit 1898300abf3508bca152e65b36cce5bf93d7e63e upstream.
+
+Sign extend also an unsigned compare value to match what lr.w is doing.
+Otherwise try_cmpxchg may spuriously return true when used on a u32 value
+that has the sign bit set, as it happens often in inode_set_ctime_current.
+
+Do this in three conversion steps. The first conversion to long is needed
+to avoid a -Wpointer-to-int-cast warning when arch_cmpxchg is used with a
+pointer type. Then convert to int and back to long to always sign extend
+the 32-bit value to 64-bit.
+
+Fixes: 6c58f25e6938 ("riscv/atomic: Fix sign extension for RV64I")
+Signed-off-by: Andreas Schwab <schwab@suse.de>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
+Tested-by: Xi Ruoyao <xry111@xry111.site>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/mvmed0k4prh.fsf@suse.de
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/include/asm/cmpxchg.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/riscv/include/asm/cmpxchg.h
++++ b/arch/riscv/include/asm/cmpxchg.h
+@@ -231,7 +231,7 @@
+ __arch_cmpxchg(".w", ".w" sc_sfx, ".w" cas_sfx, \
+ sc_prepend, sc_append, \
+ cas_prepend, cas_append, \
+- __ret, __ptr, (long), __old, __new); \
++ __ret, __ptr, (long)(int)(long), __old, __new); \
+ break; \
+ case 8: \
+ __arch_cmpxchg(".d", ".d" sc_sfx, ".d" cas_sfx, \
--- /dev/null
+From fb8179ce2996bffaa36a04e2b6262843b01b7565 Mon Sep 17 00:00:00 2001
+From: Rob Herring <robh@kernel.org>
+Date: Mon, 4 Nov 2024 13:03:13 -0600
+Subject: riscv: cacheinfo: Use of_property_present() for non-boolean properties
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Rob Herring <robh@kernel.org>
+
+commit fb8179ce2996bffaa36a04e2b6262843b01b7565 upstream.
+
+The use of of_property_read_bool() for non-boolean properties is
+deprecated in favor of of_property_present() when testing for property
+presence.
+
+Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
+Reviewed-by: Clément Léger <cleger@rivosinc.com>
+Cc: stable@vger.kernel.org
+Fixes: 76d2a0493a17 ("RISC-V: Init and Halt Code")
+Link: https://lore.kernel.org/r/20241104190314.270095-1-robh@kernel.org
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/cacheinfo.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/arch/riscv/kernel/cacheinfo.c
++++ b/arch/riscv/kernel/cacheinfo.c
+@@ -108,11 +108,11 @@ int populate_cache_leaves(unsigned int c
+ if (!np)
+ return -ENOENT;
+
+- if (of_property_read_bool(np, "cache-size"))
++ if (of_property_present(np, "cache-size"))
+ ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
+- if (of_property_read_bool(np, "i-cache-size"))
++ if (of_property_present(np, "i-cache-size"))
+ ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
+- if (of_property_read_bool(np, "d-cache-size"))
++ if (of_property_present(np, "d-cache-size"))
+ ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
+
+ prev = np;
+@@ -125,11 +125,11 @@ int populate_cache_leaves(unsigned int c
+ break;
+ if (level <= levels)
+ break;
+- if (of_property_read_bool(np, "cache-size"))
++ if (of_property_present(np, "cache-size"))
+ ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
+- if (of_property_read_bool(np, "i-cache-size"))
++ if (of_property_present(np, "i-cache-size"))
+ ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
+- if (of_property_read_bool(np, "d-cache-size"))
++ if (of_property_present(np, "d-cache-size"))
+ ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
+ levels = level;
+ }
--- /dev/null
+From c6ec1e1b078d8e2ecd075e46db6197a14930a3fc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= <cleger@rivosinc.com>
+Date: Mon, 10 Feb 2025 16:56:14 +0100
+Subject: riscv: cpufeature: use bitmap_equal() instead of memcmp()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Clément Léger <cleger@rivosinc.com>
+
+commit c6ec1e1b078d8e2ecd075e46db6197a14930a3fc upstream.
+
+Comparison of bitmaps should be done using bitmap_equal(), not memcmp(),
+use the former one to compare isa bitmaps.
+
+Signed-off-by: Clément Léger <cleger@rivosinc.com>
+Fixes: 625034abd52a8c ("riscv: add ISA extensions validation callback")
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250210155615.1545738-1-cleger@rivosinc.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/cpufeature.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/riscv/kernel/cpufeature.c
++++ b/arch/riscv/kernel/cpufeature.c
+@@ -475,7 +475,7 @@ static void __init riscv_resolve_isa(uns
+ if (bit < RISCV_ISA_EXT_BASE)
+ *this_hwcap |= isa2hwcap[bit];
+ }
+- } while (loop && memcmp(prev_resolved_isa, resolved_isa, sizeof(prev_resolved_isa)));
++ } while (loop && !bitmap_equal(prev_resolved_isa, resolved_isa, RISCV_ISA_EXT_MAX));
+ }
+
+ static void __init match_isa_ext(const char *name, const char *name_end, unsigned long *bitmap)
--- /dev/null
+From 599c44cd21f4967774e0acf58f734009be4aea9a Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@suse.de>
+Date: Mon, 3 Feb 2025 11:06:00 +0100
+Subject: riscv/futex: sign extend compare value in atomic cmpxchg
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Andreas Schwab <schwab@suse.de>
+
+commit 599c44cd21f4967774e0acf58f734009be4aea9a upstream.
+
+Make sure the compare value in the lr/sc loop is sign extended to match
+what lr.w does. Fortunately, due to the compiler keeping the register
+contents sign extended anyway the lack of the explicit extension didn't
+result in wrong code so far, but this cannot be relied upon.
+
+Fixes: b90edb33010b ("RISC-V: Add futex support.")
+Signed-off-by: Andreas Schwab <schwab@suse.de>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/mvmfrkv2vhz.fsf@suse.de
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/include/asm/futex.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/riscv/include/asm/futex.h
++++ b/arch/riscv/include/asm/futex.h
+@@ -93,7 +93,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval,
+ _ASM_EXTABLE_UACCESS_ERR(1b, 3b, %[r]) \
+ _ASM_EXTABLE_UACCESS_ERR(2b, 3b, %[r]) \
+ : [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr), [t] "=&r" (tmp)
+- : [ov] "Jr" (oldval), [nv] "Jr" (newval)
++ : [ov] "Jr" ((long)(int)oldval), [nv] "Jr" (newval)
+ : "memory");
+ __disable_user_access();
+
--- /dev/null
+From aa49bc2ca8524186ceb0811c23a7f00c3dea6987 Mon Sep 17 00:00:00 2001
+From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Date: Fri, 20 Dec 2024 16:39:23 +0800
+Subject: riscv: signal: fix signal frame size
+
+From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+
+commit aa49bc2ca8524186ceb0811c23a7f00c3dea6987 upstream.
+
+The signal context of certain RISC-V extensions will be appended after
+struct __riscv_extra_ext_header, which already includes an empty context
+header. Therefore, there is no need to preserve a separate hdr for the
+END of signal context.
+
+Fixes: 8ee0b41898fa ("riscv: signal: Add sigcontext save/restore for vector")
+Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Reviewed-by: Zong Li <zong.li@sifive.com>
+Reviewed-by: Andy Chiu <AndybnAC@gmail.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20241220083926.19453-2-yongxuan.wang@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/signal.c | 6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/arch/riscv/kernel/signal.c
++++ b/arch/riscv/kernel/signal.c
+@@ -215,12 +215,6 @@ static size_t get_rt_frame_size(bool cal
+ if (cal_all || riscv_v_vstate_query(task_pt_regs(current)))
+ total_context_size += riscv_v_sc_size;
+ }
+- /*
+- * Preserved a __riscv_ctx_hdr for END signal context header if an
+- * extension uses __riscv_extra_ext_header
+- */
+- if (total_context_size)
+- total_context_size += sizeof(struct __riscv_ctx_hdr);
+
+ frame_size += total_context_size;
+
--- /dev/null
+From 564fc8eb6f78e01292ff10801f318feae6153fdd Mon Sep 17 00:00:00 2001
+From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Date: Fri, 20 Dec 2024 16:39:24 +0800
+Subject: riscv: signal: fix signal_minsigstksz
+
+From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+
+commit 564fc8eb6f78e01292ff10801f318feae6153fdd upstream.
+
+The init_rt_signal_env() funciton is called before the alternative patch
+is applied, so using the alternative-related API to check the availability
+of an extension within this function doesn't have the intended effect.
+This patch reorders the init_rt_signal_env() and apply_boot_alternatives()
+to get the correct signal_minsigstksz.
+
+Fixes: e92f469b0771 ("riscv: signal: Report signal frame size to userspace via auxv")
+Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
+Reviewed-by: Zong Li <zong.li@sifive.com>
+Reviewed-by: Andy Chiu <andybnac@gmail.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20241220083926.19453-3-yongxuan.wang@sifive.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/riscv/kernel/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/riscv/kernel/setup.c
++++ b/arch/riscv/kernel/setup.c
+@@ -324,8 +324,8 @@ void __init setup_arch(char **cmdline_p)
+
+ riscv_init_cbo_blocksizes();
+ riscv_fill_hwcap();
+- init_rt_signal_env();
+ apply_boot_alternatives();
++ init_rt_signal_env();
+
+ if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
+ riscv_isa_extension_available(NULL, ZICBOM))
--- /dev/null
+From 713e788c0e07e185fd44dd581f74855ef149722f Mon Sep 17 00:00:00 2001
+From: Stafford Horne <shorne@gmail.com>
+Date: Tue, 14 Jan 2025 17:07:21 +0000
+Subject: rseq/selftests: Fix riscv rseq_offset_deref_addv inline asm
+
+From: Stafford Horne <shorne@gmail.com>
+
+commit 713e788c0e07e185fd44dd581f74855ef149722f upstream.
+
+When working on OpenRISC support for restartable sequences I noticed
+and fixed these two issues with the riscv support bits.
+
+ 1 The 'inc' argument to RSEQ_ASM_OP_R_DEREF_ADDV was being implicitly
+ passed to the macro. Fix this by adding 'inc' to the list of macro
+ arguments.
+ 2 The inline asm input constraints for 'inc' and 'off' use "er", The
+ riscv gcc port does not have an "e" constraint, this looks to be
+ copied from the x86 port. Fix this by just using an "r" constraint.
+
+I have compile tested this only for riscv. However, the same fixes I
+use in the OpenRISC rseq selftests and everything passes with no issues.
+
+Fixes: 171586a6ab66 ("selftests/rseq: riscv: Template memory ordering and percpu access mode")
+Signed-off-by: Stafford Horne <shorne@gmail.com>
+Tested-by: Charlie Jenkins <charlie@rivosinc.com>
+Reviewed-by: Charlie Jenkins <charlie@rivosinc.com>
+Reviewed-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Acked-by: Shuah Khan <skhan@linuxfoundation.org>
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/r/20250114170721.3613280-1-shorne@gmail.com
+Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/rseq/rseq-riscv-bits.h | 6 +++---
+ tools/testing/selftests/rseq/rseq-riscv.h | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/tools/testing/selftests/rseq/rseq-riscv-bits.h
++++ b/tools/testing/selftests/rseq/rseq-riscv-bits.h
+@@ -243,7 +243,7 @@ int RSEQ_TEMPLATE_IDENTIFIER(rseq_offset
+ #ifdef RSEQ_COMPARE_TWICE
+ RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, "%l[error1]")
+ #endif
+- RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, 3)
++ RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, inc, 3)
+ RSEQ_INJECT_ASM(4)
+ RSEQ_ASM_DEFINE_ABORT(4, abort)
+ : /* gcc asm goto does not allow outputs */
+@@ -251,8 +251,8 @@ int RSEQ_TEMPLATE_IDENTIFIER(rseq_offset
+ [current_cpu_id] "m" (rseq_get_abi()->RSEQ_TEMPLATE_CPU_ID_FIELD),
+ [rseq_cs] "m" (rseq_get_abi()->rseq_cs.arch.ptr),
+ [ptr] "r" (ptr),
+- [off] "er" (off),
+- [inc] "er" (inc)
++ [off] "r" (off),
++ [inc] "r" (inc)
+ RSEQ_INJECT_INPUT
+ : "memory", RSEQ_ASM_TMP_REG_1
+ RSEQ_INJECT_CLOBBER
+--- a/tools/testing/selftests/rseq/rseq-riscv.h
++++ b/tools/testing/selftests/rseq/rseq-riscv.h
+@@ -158,7 +158,7 @@ do { \
+ "bnez " RSEQ_ASM_TMP_REG_1 ", 222b\n" \
+ "333:\n"
+
+-#define RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, post_commit_label) \
++#define RSEQ_ASM_OP_R_DEREF_ADDV(ptr, off, inc, post_commit_label) \
+ "mv " RSEQ_ASM_TMP_REG_1 ", %[" __rseq_str(ptr) "]\n" \
+ RSEQ_ASM_OP_R_ADD(off) \
+ REG_L RSEQ_ASM_TMP_REG_1 ", 0(" RSEQ_ASM_TMP_REG_1 ")\n" \
--- /dev/null
+From 82c387ef7568c0d96a918a5a78d9cad6256cfa15 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Mon, 16 Dec 2024 14:20:56 +0100
+Subject: sched/core: Prevent rescheduling when interrupts are disabled
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 82c387ef7568c0d96a918a5a78d9cad6256cfa15 upstream.
+
+David reported a warning observed while loop testing kexec jump:
+
+ Interrupts enabled after irqrouter_resume+0x0/0x50
+ WARNING: CPU: 0 PID: 560 at drivers/base/syscore.c:103 syscore_resume+0x18a/0x220
+ kernel_kexec+0xf6/0x180
+ __do_sys_reboot+0x206/0x250
+ do_syscall_64+0x95/0x180
+
+The corresponding interrupt flag trace:
+
+ hardirqs last enabled at (15573): [<ffffffffa8281b8e>] __up_console_sem+0x7e/0x90
+ hardirqs last disabled at (15580): [<ffffffffa8281b73>] __up_console_sem+0x63/0x90
+
+That means __up_console_sem() was invoked with interrupts enabled. Further
+instrumentation revealed that in the interrupt disabled section of kexec
+jump one of the syscore_suspend() callbacks woke up a task, which set the
+NEED_RESCHED flag. A later callback in the resume path invoked
+cond_resched() which in turn led to the invocation of the scheduler:
+
+ __cond_resched+0x21/0x60
+ down_timeout+0x18/0x60
+ acpi_os_wait_semaphore+0x4c/0x80
+ acpi_ut_acquire_mutex+0x3d/0x100
+ acpi_ns_get_node+0x27/0x60
+ acpi_ns_evaluate+0x1cb/0x2d0
+ acpi_rs_set_srs_method_data+0x156/0x190
+ acpi_pci_link_set+0x11c/0x290
+ irqrouter_resume+0x54/0x60
+ syscore_resume+0x6a/0x200
+ kernel_kexec+0x145/0x1c0
+ __do_sys_reboot+0xeb/0x240
+ do_syscall_64+0x95/0x180
+
+This is a long standing problem, which probably got more visible with
+the recent printk changes. Something does a task wakeup and the
+scheduler sets the NEED_RESCHED flag. cond_resched() sees it set and
+invokes schedule() from a completely bogus context. The scheduler
+enables interrupts after context switching, which causes the above
+warning at the end.
+
+Quite some of the code paths in syscore_suspend()/resume() can result in
+triggering a wakeup with the exactly same consequences. They might not
+have done so yet, but as they share a lot of code with normal operations
+it's just a question of time.
+
+The problem only affects the PREEMPT_NONE and PREEMPT_VOLUNTARY scheduling
+models. Full preemption is not affected as cond_resched() is disabled and
+the preemption check preemptible() takes the interrupt disabled flag into
+account.
+
+Cure the problem by adding a corresponding check into cond_resched().
+
+Reported-by: David Woodhouse <dwmw@amazon.co.uk>
+Suggested-by: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Tested-by: David Woodhouse <dwmw@amazon.co.uk>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: stable@vger.kernel.org
+Closes: https://lore.kernel.org/all/7717fe2ac0ce5f0a2c43fdab8b11f4483d54a2a4.camel@infradead.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sched/core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -7278,7 +7278,7 @@ out_unlock:
+ #if !defined(CONFIG_PREEMPTION) || defined(CONFIG_PREEMPT_DYNAMIC)
+ int __sched __cond_resched(void)
+ {
+- if (should_resched(0)) {
++ if (should_resched(0) && !irqs_disabled()) {
+ preempt_schedule_common();
+ return 1;
+ }
--- /dev/null
+From 8fef0a3b17bb258130a4fcbcb5addf94b25e9ec5 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Tue, 25 Feb 2025 06:02:23 -1000
+Subject: sched_ext: Fix pick_task_scx() picking non-queued tasks when it's called without balance()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 8fef0a3b17bb258130a4fcbcb5addf94b25e9ec5 upstream.
+
+a6250aa251ea ("sched_ext: Handle cases where pick_task_scx() is called
+without preceding balance_scx()") added a workaround to handle the cases
+where pick_task_scx() is called without prececing balance_scx() which is due
+to a fair class bug where pick_taks_fair() may return NULL after a true
+return from balance_fair().
+
+The workaround detects when pick_task_scx() is called without preceding
+balance_scx() and emulates SCX_RQ_BAL_KEEP and triggers kicking to avoid
+stalling. Unfortunately, the workaround code was testing whether @prev was
+on SCX to decide whether to keep the task running. This is incorrect as the
+task may be on SCX but no longer runnable.
+
+This could lead to a non-runnable task to be returned from pick_task_scx()
+which cause interesting confusions and failures. e.g. A common failure mode
+is the task ending up with (!on_rq && on_cpu) state which can cause
+potential wakers to busy loop, which can easily lead to deadlocks.
+
+Fix it by testing whether @prev has SCX_TASK_QUEUED set. This makes
+@prev_on_scx only used in one place. Open code the usage and improve the
+comment while at it.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Pat Cody <patcody@meta.com>
+Fixes: a6250aa251ea ("sched_ext: Handle cases where pick_task_scx() is called without preceding balance_scx()")
+Cc: stable@vger.kernel.org # v6.12+
+Acked-by: Andrea Righi <arighi@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/sched/ext.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/kernel/sched/ext.c
++++ b/kernel/sched/ext.c
+@@ -3097,7 +3097,6 @@ static struct task_struct *pick_task_scx
+ {
+ struct task_struct *prev = rq->curr;
+ struct task_struct *p;
+- bool prev_on_scx = prev->sched_class == &ext_sched_class;
+ bool keep_prev = rq->scx.flags & SCX_RQ_BAL_KEEP;
+ bool kick_idle = false;
+
+@@ -3117,14 +3116,18 @@ static struct task_struct *pick_task_scx
+ * if pick_task_scx() is called without preceding balance_scx().
+ */
+ if (unlikely(rq->scx.flags & SCX_RQ_BAL_PENDING)) {
+- if (prev_on_scx) {
++ if (prev->scx.flags & SCX_TASK_QUEUED) {
+ keep_prev = true;
+ } else {
+ keep_prev = false;
+ kick_idle = true;
+ }
+- } else if (unlikely(keep_prev && !prev_on_scx)) {
+- /* only allowed during transitions */
++ } else if (unlikely(keep_prev &&
++ prev->sched_class != &ext_sched_class)) {
++ /*
++ * Can happen while enabling as SCX_RQ_BAL_PENDING assertion is
++ * conditional on scx_enabled() and may have been skipped.
++ */
+ WARN_ON_ONCE(scx_ops_enable_state() == SCX_OPS_ENABLED);
+ keep_prev = false;
+ }
--- /dev/null
+From f27a95845b01e86d67c8b014b4f41bd3327daa63 Mon Sep 17 00:00:00 2001
+From: Arthur Simchaev <arthur.simchaev@sandisk.com>
+Date: Thu, 20 Feb 2025 16:20:39 +0200
+Subject: scsi: ufs: core: bsg: Fix crash when arpmb command fails
+
+From: Arthur Simchaev <arthur.simchaev@sandisk.com>
+
+commit f27a95845b01e86d67c8b014b4f41bd3327daa63 upstream.
+
+If the device doesn't support arpmb we'll crash due to copying user data in
+bsg_transport_sg_io_fn().
+
+In the case where ufs_bsg_exec_advanced_rpmb_req() returns an error, do not
+set the job's reply_len.
+
+Memory crash backtrace:
+3,1290,531166405,-;ufshcd 0000:00:12.5: ARPMB OP failed: error code -22
+
+4,1308,531166555,-;Call Trace:
+
+4,1309,531166559,-; <TASK>
+
+4,1310,531166565,-; ? show_regs+0x6d/0x80
+
+4,1311,531166575,-; ? die+0x37/0xa0
+
+4,1312,531166583,-; ? do_trap+0xd4/0xf0
+
+4,1313,531166593,-; ? do_error_trap+0x71/0xb0
+
+4,1314,531166601,-; ? usercopy_abort+0x6c/0x80
+
+4,1315,531166610,-; ? exc_invalid_op+0x52/0x80
+
+4,1316,531166622,-; ? usercopy_abort+0x6c/0x80
+
+4,1317,531166630,-; ? asm_exc_invalid_op+0x1b/0x20
+
+4,1318,531166643,-; ? usercopy_abort+0x6c/0x80
+
+4,1319,531166652,-; __check_heap_object+0xe3/0x120
+
+4,1320,531166661,-; check_heap_object+0x185/0x1d0
+
+4,1321,531166670,-; __check_object_size.part.0+0x72/0x150
+
+4,1322,531166679,-; __check_object_size+0x23/0x30
+
+4,1323,531166688,-; bsg_transport_sg_io_fn+0x314/0x3b0
+
+Fixes: 6ff265fc5ef6 ("scsi: ufs: core: bsg: Add advanced RPMB support in ufs_bsg")
+Cc: stable@vger.kernel.org
+Reviewed-by: Bean Huo <beanhuo@micron.com>
+Signed-off-by: Arthur Simchaev <arthur.simchaev@sandisk.com>
+Link: https://lore.kernel.org/r/20250220142039.250992-1-arthur.simchaev@sandisk.com
+Reviewed-by: Bart Van Assche <bvanassche@acm.org>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/ufs/core/ufs_bsg.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/ufs/core/ufs_bsg.c
++++ b/drivers/ufs/core/ufs_bsg.c
+@@ -194,10 +194,12 @@ out:
+ ufshcd_rpm_put_sync(hba);
+ kfree(buff);
+ bsg_reply->result = ret;
+- job->reply_len = !rpmb ? sizeof(struct ufs_bsg_reply) : sizeof(struct ufs_rpmb_reply);
+ /* complete the job here only if no error */
+- if (ret == 0)
++ if (ret == 0) {
++ job->reply_len = rpmb ? sizeof(struct ufs_rpmb_reply) :
++ sizeof(struct ufs_bsg_reply);
+ bsg_job_done(job, ret, bsg_reply->reply_payload_rcv_len);
++ }
+
+ return ret;
+ }
--- /dev/null
+From f5534d511bcd273720f168386de74af76e148a9b Mon Sep 17 00:00:00 2001
+From: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+Date: Wed, 5 Feb 2025 17:36:50 +0800
+Subject: selftests/landlock: Test TCP accesses with protocol=IPPROTO_TCP
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+
+commit f5534d511bcd273720f168386de74af76e148a9b upstream.
+
+Extend protocol_variant structure with protocol field (Cf. socket(2)).
+
+Extend protocol fixture with TCP test suits with protocol=IPPROTO_TCP
+which can be used as an alias for IPPROTO_IP (=0) in socket(2).
+
+Signed-off-by: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+Link: https://lore.kernel.org/r/20250205093651.1424339-3-ivanov.mikhail1@huawei-partners.com
+Cc: <stable@vger.kernel.org> # 6.7.x
+Signed-off-by: Mickaël Salaün <mic@digikod.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/landlock/common.h | 1
+ tools/testing/selftests/landlock/net_test.c | 80 +++++++++++++++++++++++-----
+ 2 files changed, 67 insertions(+), 14 deletions(-)
+
+--- a/tools/testing/selftests/landlock/common.h
++++ b/tools/testing/selftests/landlock/common.h
+@@ -234,6 +234,7 @@ enforce_ruleset(struct __test_metadata *
+ struct protocol_variant {
+ int domain;
+ int type;
++ int protocol;
+ };
+
+ struct service_fixture {
+--- a/tools/testing/selftests/landlock/net_test.c
++++ b/tools/testing/selftests/landlock/net_test.c
+@@ -85,18 +85,18 @@ static void setup_loopback(struct __test
+ clear_ambient_cap(_metadata, CAP_NET_ADMIN);
+ }
+
++static bool prot_is_tcp(const struct protocol_variant *const prot)
++{
++ return (prot->domain == AF_INET || prot->domain == AF_INET6) &&
++ prot->type == SOCK_STREAM &&
++ (prot->protocol == IPPROTO_TCP || prot->protocol == IPPROTO_IP);
++}
++
+ static bool is_restricted(const struct protocol_variant *const prot,
+ const enum sandbox_type sandbox)
+ {
+- switch (prot->domain) {
+- case AF_INET:
+- case AF_INET6:
+- switch (prot->type) {
+- case SOCK_STREAM:
+- return sandbox == TCP_SANDBOX;
+- }
+- break;
+- }
++ if (sandbox == TCP_SANDBOX)
++ return prot_is_tcp(prot);
+ return false;
+ }
+
+@@ -105,7 +105,7 @@ static int socket_variant(const struct s
+ int ret;
+
+ ret = socket(srv->protocol.domain, srv->protocol.type | SOCK_CLOEXEC,
+- 0);
++ srv->protocol.protocol);
+ if (ret < 0)
+ return -errno;
+ return ret;
+@@ -290,22 +290,48 @@ FIXTURE_TEARDOWN(protocol)
+ }
+
+ /* clang-format off */
+-FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp) {
++FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp1) {
++ /* clang-format on */
++ .sandbox = NO_SANDBOX,
++ .prot = {
++ .domain = AF_INET,
++ .type = SOCK_STREAM,
++ /* IPPROTO_IP == 0 */
++ .protocol = IPPROTO_IP,
++ },
++};
++
++/* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp2) {
+ /* clang-format on */
+ .sandbox = NO_SANDBOX,
+ .prot = {
+ .domain = AF_INET,
+ .type = SOCK_STREAM,
++ .protocol = IPPROTO_TCP,
++ },
++};
++
++/* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp1) {
++ /* clang-format on */
++ .sandbox = NO_SANDBOX,
++ .prot = {
++ .domain = AF_INET6,
++ .type = SOCK_STREAM,
++ /* IPPROTO_IP == 0 */
++ .protocol = IPPROTO_IP,
+ },
+ };
+
+ /* clang-format off */
+-FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp) {
++FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp2) {
+ /* clang-format on */
+ .sandbox = NO_SANDBOX,
+ .prot = {
+ .domain = AF_INET6,
+ .type = SOCK_STREAM,
++ .protocol = IPPROTO_TCP,
+ },
+ };
+
+@@ -372,22 +398,48 @@ FIXTURE_VARIANT_ADD(protocol, no_sandbox
+ };
+
+ /* clang-format off */
+-FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp) {
++FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp1) {
++ /* clang-format on */
++ .sandbox = TCP_SANDBOX,
++ .prot = {
++ .domain = AF_INET,
++ .type = SOCK_STREAM,
++ /* IPPROTO_IP == 0 */
++ .protocol = IPPROTO_IP,
++ },
++};
++
++/* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp2) {
+ /* clang-format on */
+ .sandbox = TCP_SANDBOX,
+ .prot = {
+ .domain = AF_INET,
+ .type = SOCK_STREAM,
++ .protocol = IPPROTO_TCP,
++ },
++};
++
++/* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp1) {
++ /* clang-format on */
++ .sandbox = TCP_SANDBOX,
++ .prot = {
++ .domain = AF_INET6,
++ .type = SOCK_STREAM,
++ /* IPPROTO_IP == 0 */
++ .protocol = IPPROTO_IP,
+ },
+ };
+
+ /* clang-format off */
+-FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp) {
++FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp2) {
+ /* clang-format on */
+ .sandbox = TCP_SANDBOX,
+ .prot = {
+ .domain = AF_INET6,
+ .type = SOCK_STREAM,
++ .protocol = IPPROTO_TCP,
+ },
+ };
+
--- /dev/null
+From 3d4033985ff508ef587ca11f1c8361ba57c7e09f Mon Sep 17 00:00:00 2001
+From: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+Date: Wed, 5 Feb 2025 17:36:51 +0800
+Subject: selftests/landlock: Test that MPTCP actions are not restricted
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+
+commit 3d4033985ff508ef587ca11f1c8361ba57c7e09f upstream.
+
+Extend protocol fixture with test suits for MPTCP protocol.
+Add CONFIG_MPTCP and CONFIG_MPTCP_IPV6 options in config.
+
+Signed-off-by: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
+Link: https://lore.kernel.org/r/20250205093651.1424339-4-ivanov.mikhail1@huawei-partners.com
+Cc: <stable@vger.kernel.org> # 6.7.x
+Signed-off-by: Mickaël Salaün <mic@digikod.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/landlock/config | 2 +
+ tools/testing/selftests/landlock/net_test.c | 44 ++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+)
+
+--- a/tools/testing/selftests/landlock/config
++++ b/tools/testing/selftests/landlock/config
+@@ -3,6 +3,8 @@ CONFIG_CGROUP_SCHED=y
+ CONFIG_INET=y
+ CONFIG_IPV6=y
+ CONFIG_KEYS=y
++CONFIG_MPTCP=y
++CONFIG_MPTCP_IPV6=y
+ CONFIG_NET=y
+ CONFIG_NET_NS=y
+ CONFIG_OVERLAY_FS=y
+--- a/tools/testing/selftests/landlock/net_test.c
++++ b/tools/testing/selftests/landlock/net_test.c
+@@ -310,6 +310,17 @@ FIXTURE_VARIANT_ADD(protocol, no_sandbox
+ };
+
+ /* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_mptcp) {
++ /* clang-format on */
++ .sandbox = NO_SANDBOX,
++ .prot = {
++ .domain = AF_INET,
++ .type = SOCK_STREAM,
++ .protocol = IPPROTO_MPTCP,
++ },
++};
++
++/* clang-format off */
+ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_udp) {
+ /* clang-format on */
+ .sandbox = NO_SANDBOX,
+@@ -330,6 +341,17 @@ FIXTURE_VARIANT_ADD(protocol, no_sandbox
+ };
+
+ /* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_mptcp) {
++ /* clang-format on */
++ .sandbox = NO_SANDBOX,
++ .prot = {
++ .domain = AF_INET6,
++ .type = SOCK_STREAM,
++ .protocol = IPPROTO_MPTCP,
++ },
++};
++
++/* clang-format off */
+ FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_unix_stream) {
+ /* clang-format on */
+ .sandbox = NO_SANDBOX,
+@@ -390,6 +412,17 @@ FIXTURE_VARIANT_ADD(protocol, tcp_sandbo
+ };
+
+ /* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_mptcp) {
++ /* clang-format on */
++ .sandbox = TCP_SANDBOX,
++ .prot = {
++ .domain = AF_INET,
++ .type = SOCK_STREAM,
++ .protocol = IPPROTO_MPTCP,
++ },
++};
++
++/* clang-format off */
+ FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_unix_stream) {
+ /* clang-format on */
+ .sandbox = TCP_SANDBOX,
+@@ -399,6 +432,17 @@ FIXTURE_VARIANT_ADD(protocol, tcp_sandbo
+ },
+ };
+
++/* clang-format off */
++FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_mptcp) {
++ /* clang-format on */
++ .sandbox = TCP_SANDBOX,
++ .prot = {
++ .domain = AF_INET6,
++ .type = SOCK_STREAM,
++ .protocol = IPPROTO_MPTCP,
++ },
++};
++
+ /* clang-format off */
+ FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_unix_datagram) {
+ /* clang-format on */
riscv-kvm-fix-hart-suspend_type-use.patch
riscv-kvm-fix-sbi-ipi-error-generation.patch
riscv-kvm-fix-sbi-time-error-generation.patch
+tracing-fix-bad-hist-from-corrupting-named_triggers-list.patch
+ftrace-avoid-potential-division-by-zero-in-function_stat_show.patch
+alsa-usb-audio-re-add-sample-rate-quirk-for-pioneer-djm-900nxs2.patch
+alsa-hda-realtek-fix-microphone-regression-on-asus-n705ud.patch
+kvm-arm64-ensure-a-vmid-is-allocated-before-programming-vttbr_el2.patch
+kvm-nvmx-process-events-on-nested-vm-exit-if-injectable-irq-or-nmi-is-pending.patch
+perf-core-add-rcu-read-lock-protection-to-perf_iterate_ctx.patch
+perf-x86-fix-low-freqency-setting-issue.patch
+perf-core-fix-low-freq-setting-via-ioc_period.patch
+drm-xe-regs-remove-a-duplicate-definition-for-ring_ctl_size-size.patch
+drm-xe-userptr-restore-invalidation-list-on-error.patch
+drm-xe-userptr-fix-efault-handling.patch
+drm-fbdev-dma-add-shadow-buffering-for-deferred-i-o.patch
+drm-amdkfd-preserve-cp_hqd_pq_control-on-update_mqd.patch
+drm-amdgpu-disable-bar-resize-on-dell-g5-se.patch
+drm-amdgpu-init-return-value-in-amdgpu_ttm_clear_buffer.patch
+drm-amd-display-disable-psr-su-on-edp-panels.patch
+drm-amd-display-add-a-quirk-to-enable-edp0-on-dp1.patch
+drm-amd-display-fix-hpd-after-gpu-reset.patch
+arm64-mm-fix-boot-panic-on-ampere-altra.patch
+arm64-hugetlb-fix-huge_ptep_get_and_clear-for-non-present-ptes.patch
+arm64-hugetlb-fix-flush_hugetlb_tlb_range-invalidation-level.patch
+block-remove-zone-write-plugs-when-handling-native-zone-append-writes.patch
+btrfs-skip-inodes-without-loaded-extent-maps-when-shrinking-extent-maps.patch
+btrfs-do-regular-iput-instead-of-delayed-iput-during-extent-map-shrinking.patch
+btrfs-fix-use-after-free-on-inode-when-scanning-root-during-em-shrinking.patch
+btrfs-fix-data-overwriting-bug-during-buffered-write-when-block-size-page-size.patch
+i2c-npcm-disable-interrupt-enable-bit-before-devm_request_irq.patch
+i2c-ls2x-fix-frequency-division-register-access.patch
+i2c-amd-asf-fix-eoi-register-write-to-enable-successive-interrupts.patch
+usbnet-gl620a-fix-endpoint-checking-in-genelink_bind.patch
+net-stmmac-dwmac-loongson-add-fix_soc_reset-callback.patch
+net-phy-qcom-qca807x-fix-condition-for-dac_dsp_bias_current.patch
+net-enetc-fix-the-off-by-one-issue-in-enetc_map_tx_buffs.patch
+net-enetc-keep-track-of-correct-tx-bd-count-in-enetc_map_tx_tso_buffs.patch
+net-enetc-vfs-do-not-support-hwtstamp_tx_onestep_sync.patch
+net-enetc-update-udp-checksum-when-updating-origintimestamp-field.patch
+net-enetc-correct-the-xdp_tx-statistics.patch
+net-enetc-remove-the-mm_lock-from-the-enetc-v4-driver.patch
+net-enetc-fix-the-off-by-one-issue-in-enetc_map_tx_tso_buffs.patch
+net-enetc-add-missing-enetc4_link_deinit.patch
+phy-tegra-xusb-reset-vbus-id-override.patch
+phy-exynos5-usbdrd-fix-mpll_multiplier-and-ssc_refclksel-masks-in-refclk.patch
+phy-exynos5-usbdrd-gs101-ensure-power-is-gated-to-ss-phy-in-phy_exit.patch
+gve-unlink-old-napi-when-stopping-a-queue-using-queue-api.patch
+iommu-vt-d-remove-device-comparison-in-context_setup_pass_through_cb.patch
+iommu-vt-d-fix-suspicious-rcu-usage.patch
+amdgpu-pm-legacy-fix-suspend-resume-issues.patch
+intel_idle-handle-older-cpus-which-stop-the-tsc-in-deeper-c-states-correctly.patch
+mptcp-always-handle-address-removal-under-msk-socket-lock.patch
+mptcp-reset-when-mptcp-opts-are-dropped-after-join.patch
+selftests-landlock-test-that-mptcp-actions-are-not-restricted.patch
+efi-don-t-map-the-entire-mokvar-table-to-determine-its-size.patch
+vmlinux.lds-ensure-that-const-vars-with-relocations-are-mapped-r-o.patch
+rcuref-plug-slowpath-race-in-rcuref_put.patch
+sched-core-prevent-rescheduling-when-interrupts-are-disabled.patch
+sched_ext-fix-pick_task_scx-picking-non-queued-tasks-when-it-s-called-without-balance.patch
+selftests-landlock-test-tcp-accesses-with-protocol-ipproto_tcp.patch
+fuse-revert-back-to-__readahead_folio-for-readahead.patch
+dm-integrity-avoid-divide-by-zero-in-table-status-in-inline-mode.patch
+dm-vdo-add-missing-spin_lock_init.patch
+ima-reset-ima_nonaction_rule_flags-after-post_setattr.patch
+scsi-ufs-core-bsg-fix-crash-when-arpmb-command-fails.patch
+rseq-selftests-fix-riscv-rseq_offset_deref_addv-inline-asm.patch
+riscv-atomic-do-proper-sign-extension-also-for-unsigned-in-arch_cmpxchg.patch
+riscv-futex-sign-extend-compare-value-in-atomic-cmpxchg.patch
+riscv-signal-fix-signal-frame-size.patch
+riscv-cacheinfo-use-of_property_present-for-non-boolean-properties.patch
+riscv-signal-fix-signal_minsigstksz.patch
+riscv-cpufeature-use-bitmap_equal-instead-of-memcmp.patch
--- /dev/null
+From 6f86bdeab633a56d5c6dccf1a2c5989b6a5e323e Mon Sep 17 00:00:00 2001
+From: Steven Rostedt <rostedt@goodmis.org>
+Date: Thu, 27 Feb 2025 16:39:44 -0500
+Subject: tracing: Fix bad hist from corrupting named_triggers list
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+commit 6f86bdeab633a56d5c6dccf1a2c5989b6a5e323e upstream.
+
+The following commands causes a crash:
+
+ ~# cd /sys/kernel/tracing/events/rcu/rcu_callback
+ ~# echo 'hist:name=bad:keys=common_pid:onmax(bogus).save(common_pid)' > trigger
+ bash: echo: write error: Invalid argument
+ ~# echo 'hist:name=bad:keys=common_pid' > trigger
+
+Because the following occurs:
+
+event_trigger_write() {
+ trigger_process_regex() {
+ event_hist_trigger_parse() {
+
+ data = event_trigger_alloc(..);
+
+ event_trigger_register(.., data) {
+ cmd_ops->reg(.., data, ..) [hist_register_trigger()] {
+ data->ops->init() [event_hist_trigger_init()] {
+ save_named_trigger(name, data) {
+ list_add(&data->named_list, &named_triggers);
+ }
+ }
+ }
+ }
+
+ ret = create_actions(); (return -EINVAL)
+ if (ret)
+ goto out_unreg;
+[..]
+ ret = hist_trigger_enable(data, ...) {
+ list_add_tail_rcu(&data->list, &file->triggers); <<<---- SKIPPED!!! (this is important!)
+[..]
+ out_unreg:
+ event_hist_unregister(.., data) {
+ cmd_ops->unreg(.., data, ..) [hist_unregister_trigger()] {
+ list_for_each_entry(iter, &file->triggers, list) {
+ if (!hist_trigger_match(data, iter, named_data, false)) <- never matches
+ continue;
+ [..]
+ test = iter;
+ }
+ if (test && test->ops->free) <<<-- test is NULL
+
+ test->ops->free(test) [event_hist_trigger_free()] {
+ [..]
+ if (data->name)
+ del_named_trigger(data) {
+ list_del(&data->named_list); <<<<-- NEVER gets removed!
+ }
+ }
+ }
+ }
+
+ [..]
+ kfree(data); <<<-- frees item but it is still on list
+
+The next time a hist with name is registered, it causes an u-a-f bug and
+the kernel can crash.
+
+Move the code around such that if event_trigger_register() succeeds, the
+next thing called is hist_trigger_enable() which adds it to the list.
+
+A bunch of actions is called if get_named_trigger_data() returns false.
+But that doesn't need to be called after event_trigger_register(), so it
+can be moved up, allowing event_trigger_register() to be called just
+before hist_trigger_enable() keeping them together and allowing the
+file->triggers to be properly populated.
+
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/20250227163944.1c37f85f@gandalf.local.home
+Fixes: 067fe038e70f6 ("tracing: Add variable reference handling to hist triggers")
+Reported-by: Tomas Glozar <tglozar@redhat.com>
+Tested-by: Tomas Glozar <tglozar@redhat.com>
+Reviewed-by: Tom Zanussi <zanussi@kernel.org>
+Closes: https://lore.kernel.org/all/CAP4=nvTsxjckSBTz=Oe_UYh8keD9_sZC4i++4h72mJLic4_W4A@mail.gmail.com/
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_hist.c | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -6649,27 +6649,27 @@ static int event_hist_trigger_parse(stru
+ if (existing_hist_update_only(glob, trigger_data, file))
+ goto out_free;
+
+- ret = event_trigger_register(cmd_ops, file, glob, trigger_data);
+- if (ret < 0)
+- goto out_free;
++ if (!get_named_trigger_data(trigger_data)) {
+
+- if (get_named_trigger_data(trigger_data))
+- goto enable;
++ ret = create_actions(hist_data);
++ if (ret)
++ goto out_free;
+
+- ret = create_actions(hist_data);
+- if (ret)
+- goto out_unreg;
++ if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
++ ret = save_hist_vars(hist_data);
++ if (ret)
++ goto out_free;
++ }
+
+- if (has_hist_vars(hist_data) || hist_data->n_var_refs) {
+- ret = save_hist_vars(hist_data);
++ ret = tracing_map_init(hist_data->map);
+ if (ret)
+- goto out_unreg;
++ goto out_free;
+ }
+
+- ret = tracing_map_init(hist_data->map);
+- if (ret)
+- goto out_unreg;
+-enable:
++ ret = event_trigger_register(cmd_ops, file, glob, trigger_data);
++ if (ret < 0)
++ goto out_free;
++
+ ret = hist_trigger_enable(trigger_data, file);
+ if (ret)
+ goto out_unreg;
--- /dev/null
+From 1cf9631d836b289bd5490776551961c883ae8a4f Mon Sep 17 00:00:00 2001
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Date: Mon, 24 Feb 2025 20:29:17 +0300
+Subject: usbnet: gl620a: fix endpoint checking in genelink_bind()
+
+From: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+
+commit 1cf9631d836b289bd5490776551961c883ae8a4f upstream.
+
+Syzbot reports [1] a warning in usb_submit_urb() triggered by
+inconsistencies between expected and actually present endpoints
+in gl620a driver. Since genelink_bind() does not properly
+verify whether specified eps are in fact provided by the device,
+in this case, an artificially manufactured one, one may get a
+mismatch.
+
+Fix the issue by resorting to a usbnet utility function
+usbnet_get_endpoints(), usually reserved for this very problem.
+Check for endpoints and return early before proceeding further if
+any are missing.
+
+[1] Syzbot report:
+usb 5-1: Manufacturer: syz
+usb 5-1: SerialNumber: syz
+usb 5-1: config 0 descriptor??
+gl620a 5-1:0.23 usb0: register 'gl620a' at usb-dummy_hcd.0-1, ...
+------------[ cut here ]------------
+usb 5-1: BOGUS urb xfer, pipe 3 != type 1
+WARNING: CPU: 2 PID: 1841 at drivers/usb/core/urb.c:503 usb_submit_urb+0xe4b/0x1730 drivers/usb/core/urb.c:503
+Modules linked in:
+CPU: 2 UID: 0 PID: 1841 Comm: kworker/2:2 Not tainted 6.12.0-syzkaller-07834-g06afb0f36106 #0
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014
+Workqueue: mld mld_ifc_work
+RIP: 0010:usb_submit_urb+0xe4b/0x1730 drivers/usb/core/urb.c:503
+...
+Call Trace:
+ <TASK>
+ usbnet_start_xmit+0x6be/0x2780 drivers/net/usb/usbnet.c:1467
+ __netdev_start_xmit include/linux/netdevice.h:5002 [inline]
+ netdev_start_xmit include/linux/netdevice.h:5011 [inline]
+ xmit_one net/core/dev.c:3590 [inline]
+ dev_hard_start_xmit+0x9a/0x7b0 net/core/dev.c:3606
+ sch_direct_xmit+0x1ae/0xc30 net/sched/sch_generic.c:343
+ __dev_xmit_skb net/core/dev.c:3827 [inline]
+ __dev_queue_xmit+0x13d4/0x43e0 net/core/dev.c:4400
+ dev_queue_xmit include/linux/netdevice.h:3168 [inline]
+ neigh_resolve_output net/core/neighbour.c:1514 [inline]
+ neigh_resolve_output+0x5bc/0x950 net/core/neighbour.c:1494
+ neigh_output include/net/neighbour.h:539 [inline]
+ ip6_finish_output2+0xb1b/0x2070 net/ipv6/ip6_output.c:141
+ __ip6_finish_output net/ipv6/ip6_output.c:215 [inline]
+ ip6_finish_output+0x3f9/0x1360 net/ipv6/ip6_output.c:226
+ NF_HOOK_COND include/linux/netfilter.h:303 [inline]
+ ip6_output+0x1f8/0x540 net/ipv6/ip6_output.c:247
+ dst_output include/net/dst.h:450 [inline]
+ NF_HOOK include/linux/netfilter.h:314 [inline]
+ NF_HOOK include/linux/netfilter.h:308 [inline]
+ mld_sendpack+0x9f0/0x11d0 net/ipv6/mcast.c:1819
+ mld_send_cr net/ipv6/mcast.c:2120 [inline]
+ mld_ifc_work+0x740/0xca0 net/ipv6/mcast.c:2651
+ process_one_work+0x9c5/0x1ba0 kernel/workqueue.c:3229
+ process_scheduled_works kernel/workqueue.c:3310 [inline]
+ worker_thread+0x6c8/0xf00 kernel/workqueue.c:3391
+ kthread+0x2c1/0x3a0 kernel/kthread.c:389
+ ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:147
+ ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
+ </TASK>
+
+Reported-by: syzbot+d693c07c6f647e0388d3@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d693c07c6f647e0388d3
+Fixes: 47ee3051c856 ("[PATCH] USB: usbnet (5/9) module for genesys gl620a cables")
+Cc: stable@vger.kernel.org
+Signed-off-by: Nikita Zhandarovich <n.zhandarovich@fintech.ru>
+Link: https://patch.msgid.link/20250224172919.1220522-1-n.zhandarovich@fintech.ru
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/gl620a.c | 4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/drivers/net/usb/gl620a.c
++++ b/drivers/net/usb/gl620a.c
+@@ -179,9 +179,7 @@ static int genelink_bind(struct usbnet *
+ {
+ dev->hard_mtu = GL_RCV_BUF_SIZE;
+ dev->net->hard_header_len += 4;
+- dev->in = usb_rcvbulkpipe(dev->udev, dev->driver_info->in);
+- dev->out = usb_sndbulkpipe(dev->udev, dev->driver_info->out);
+- return 0;
++ return usbnet_get_endpoints(dev, intf);
+ }
+
+ static const struct driver_info genelink_info = {
--- /dev/null
+From 68f3ea7ee199ef77551e090dfef5a49046ea8443 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ardb@kernel.org>
+Date: Fri, 21 Feb 2025 14:57:06 +0100
+Subject: vmlinux.lds: Ensure that const vars with relocations are mapped R/O
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+commit 68f3ea7ee199ef77551e090dfef5a49046ea8443 upstream.
+
+In the kernel, there are architectures (x86, arm64) that perform
+boot-time relocation (for KASLR) without relying on PIE codegen. In this
+case, all const global objects are emitted into .rodata, including const
+objects with fields that will be fixed up by the boot-time relocation
+code. This implies that .rodata (and .text in some cases) need to be
+writable at boot, but they will usually be mapped read-only as soon as
+the boot completes.
+
+When using PIE codegen, the compiler will emit const global objects into
+.data.rel.ro rather than .rodata if the object contains fields that need
+such fixups at boot-time. This permits the linker to annotate such
+regions as requiring read-write access only at load time, but not at
+execution time (in user space), while keeping .rodata truly const (in
+user space, this is important for reducing the CoW footprint of dynamic
+executables).
+
+This distinction does not matter for the kernel, but it does imply that
+const data will end up in writable memory if the .data.rel.ro sections
+are not treated in a special way, as they will end up in the writable
+.data segment by default.
+
+So emit .data.rel.ro into the .rodata segment.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Link: https://lore.kernel.org/r/20250221135704.431269-5-ardb+git@google.com
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/asm-generic/vmlinux.lds.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -457,7 +457,7 @@ defined(CONFIG_AUTOFDO_CLANG) || defined
+ . = ALIGN((align)); \
+ .rodata : AT(ADDR(.rodata) - LOAD_OFFSET) { \
+ __start_rodata = .; \
+- *(.rodata) *(.rodata.*) \
++ *(.rodata) *(.rodata.*) *(.data.rel.ro*) \
+ SCHED_DATA \
+ RO_AFTER_INIT_DATA /* Read only after init */ \
+ . = ALIGN(8); \