]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.18-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Jul 2026 10:23:04 +0000 (12:23 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 21 Jul 2026 10:23:04 +0000 (12:23 +0200)
added patches:
kvm-arm64-deduplicate-asid-retrieval-code.patch
kvm-arm64-ensure-level-is-always-initialized-when-relaxing-perms.patch
kvm-arm64-fix-propagation-of-tlbi-level-in-kvm_pgtable_stage2_relax_perms.patch
kvm-arm64-nv-re-translate-vncr-before-injecting-abort.patch
mm-damon-core-always-put-unsuccessfully-committed-target-pids.patch
mm-damon-core-trace-esz-at-first-setup.patch
samples-damon-mtier-fail-early-if-address-range-parameters-are-invalid.patch

queue-6.18/kvm-arm64-deduplicate-asid-retrieval-code.patch [new file with mode: 0644]
queue-6.18/kvm-arm64-ensure-level-is-always-initialized-when-relaxing-perms.patch [new file with mode: 0644]
queue-6.18/kvm-arm64-fix-propagation-of-tlbi-level-in-kvm_pgtable_stage2_relax_perms.patch [new file with mode: 0644]
queue-6.18/kvm-arm64-nv-re-translate-vncr-before-injecting-abort.patch [new file with mode: 0644]
queue-6.18/mm-damon-core-always-put-unsuccessfully-committed-target-pids.patch [new file with mode: 0644]
queue-6.18/mm-damon-core-trace-esz-at-first-setup.patch [new file with mode: 0644]
queue-6.18/samples-damon-mtier-fail-early-if-address-range-parameters-are-invalid.patch [new file with mode: 0644]
queue-6.18/series

diff --git a/queue-6.18/kvm-arm64-deduplicate-asid-retrieval-code.patch b/queue-6.18/kvm-arm64-deduplicate-asid-retrieval-code.patch
new file mode 100644 (file)
index 0000000..6d0bdc7
--- /dev/null
@@ -0,0 +1,158 @@
+From 54e367cb94d6bef941bbc1132d9959dc73bd4b6f Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Wed, 25 Feb 2026 10:47:18 +0000
+Subject: KVM: arm64: Deduplicate ASID retrieval code
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit 54e367cb94d6bef941bbc1132d9959dc73bd4b6f upstream.
+
+We currently have three versions of the ASID retrieval code, one
+in the S1 walker, and two in the VNCR handling (although the last
+two are limited to the EL2&0 translation regime).
+
+Make this code common, and take this opportunity to also simplify
+the code a bit while switching over to the TTBRx_EL1_ASID macro.
+
+Reviewed-by: Joey Gouly <joey.gouly@arm.com>
+Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
+Link: https://patch.msgid.link/20260225104718.14209-1-maz@kernel.org
+[maz: cherry-pick as dependency of bb645aa0a4caeaf7f9cd32e9a948594d434c1a8f]
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/kvm_nested.h |    2 +
+ arch/arm64/kvm/at.c                 |   27 +---------------
+ arch/arm64/kvm/nested.c             |   60 ++++++++++++++++++------------------
+ 3 files changed, 35 insertions(+), 54 deletions(-)
+
+--- a/arch/arm64/include/asm/kvm_nested.h
++++ b/arch/arm64/include/asm/kvm_nested.h
+@@ -371,6 +371,8 @@ int kvm_vcpu_allocate_vncr_tlb(struct kv
+ int kvm_handle_vncr_abort(struct kvm_vcpu *vcpu);
+ void kvm_handle_s1e2_tlbi(struct kvm_vcpu *vcpu, u32 inst, u64 val);
++u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime);
++
+ #define vncr_fixmap(c)                                                \
+       ({                                                      \
+               u32 __c = (c);                                  \
+--- a/arch/arm64/kvm/at.c
++++ b/arch/arm64/kvm/at.c
+@@ -483,31 +483,8 @@ static int walk_s1(struct kvm_vcpu *vcpu
+       wr->pa |= va & GENMASK_ULL(va_bottom - 1, 0);
+       wr->nG = (wi->regime != TR_EL2) && (desc & PTE_NG);
+-      if (wr->nG) {
+-              u64 asid_ttbr, tcr;
+-
+-              switch (wi->regime) {
+-              case TR_EL10:
+-                      tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
+-                      asid_ttbr = ((tcr & TCR_A1) ?
+-                                   vcpu_read_sys_reg(vcpu, TTBR1_EL1) :
+-                                   vcpu_read_sys_reg(vcpu, TTBR0_EL1));
+-                      break;
+-              case TR_EL20:
+-                      tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+-                      asid_ttbr = ((tcr & TCR_A1) ?
+-                                   vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
+-                                   vcpu_read_sys_reg(vcpu, TTBR0_EL2));
+-                      break;
+-              default:
+-                      BUG();
+-              }
+-
+-              wr->asid = FIELD_GET(TTBR_ASID_MASK, asid_ttbr);
+-              if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
+-                  !(tcr & TCR_ASID16))
+-                      wr->asid &= GENMASK(7, 0);
+-      }
++      if (wr->nG)
++              wr->asid = get_asid_by_regime(vcpu, wi->regime);
+       return 0;
+--- a/arch/arm64/kvm/nested.c
++++ b/arch/arm64/kvm/nested.c
+@@ -818,6 +818,33 @@ int kvm_inject_s2_fault(struct kvm_vcpu
+       return kvm_inject_nested_sync(vcpu, esr_el2);
+ }
++u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime)
++{
++      enum vcpu_sysreg ttbr_elx;
++      u64 tcr;
++      u16 asid;
++
++      switch (regime) {
++      case TR_EL10:
++              tcr = vcpu_read_sys_reg(vcpu, TCR_EL1);
++              ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL1 : TTBR0_EL1;
++              break;
++      case TR_EL20:
++              tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
++              ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL2 : TTBR0_EL2;
++              break;
++      default:
++              BUG();
++      }
++
++      asid = FIELD_GET(TTBRx_EL1_ASID, vcpu_read_sys_reg(vcpu, ttbr_elx));
++      if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
++          !(tcr & TCR_ASID16))
++              asid &= GENMASK(7, 0);
++
++      return asid;
++}
++
+ static void invalidate_vncr(struct vncr_tlb *vt)
+ {
+       vt->valid = false;
+@@ -1314,20 +1341,8 @@ static bool kvm_vncr_tlb_lookup(struct k
+       if (read_vncr_el2(vcpu) != vt->gva)
+               return false;
+-      if (vt->wr.nG) {
+-              u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+-              u64 ttbr = ((tcr & TCR_A1) ?
+-                          vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
+-                          vcpu_read_sys_reg(vcpu, TTBR0_EL2));
+-              u16 asid;
+-
+-              asid = FIELD_GET(TTBR_ASID_MASK, ttbr);
+-              if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
+-                  !(tcr & TCR_ASID16))
+-                      asid &= GENMASK(7, 0);
+-
+-              return asid == vt->wr.asid;
+-      }
++      if (vt->wr.nG)
++              return get_asid_by_regime(vcpu, TR_EL20) == vt->wr.asid;
+       return true;
+ }
+@@ -1428,21 +1443,8 @@ static void kvm_map_l1_vncr(struct kvm_v
+       if (read_vncr_el2(vcpu) != vt->gva)
+               return;
+-      if (vt->wr.nG) {
+-              u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2);
+-              u64 ttbr = ((tcr & TCR_A1) ?
+-                          vcpu_read_sys_reg(vcpu, TTBR1_EL2) :
+-                          vcpu_read_sys_reg(vcpu, TTBR0_EL2));
+-              u16 asid;
+-
+-              asid = FIELD_GET(TTBR_ASID_MASK, ttbr);
+-              if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) ||
+-                  !(tcr & TCR_ASID16))
+-                      asid &= GENMASK(7, 0);
+-
+-              if (asid != vt->wr.asid)
+-                      return;
+-      }
++      if (vt->wr.nG && get_asid_by_regime(vcpu, TR_EL20) != vt->wr.asid)
++              return;
+       vt->cpu = smp_processor_id();
diff --git a/queue-6.18/kvm-arm64-ensure-level-is-always-initialized-when-relaxing-perms.patch b/queue-6.18/kvm-arm64-ensure-level-is-always-initialized-when-relaxing-perms.patch
new file mode 100644 (file)
index 0000000..dbdf08d
--- /dev/null
@@ -0,0 +1,39 @@
+From 100baf0184896f859290a684f864b8200d8ac872 Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oupton@kernel.org>
+Date: Wed, 1 Jul 2026 16:16:19 -0700
+Subject: KVM: arm64: Ensure level is always initialized when relaxing perms
+
+From: Oliver Upton <oupton@kernel.org>
+
+commit 100baf0184896f859290a684f864b8200d8ac872 upstream.
+
+stage2_update_leaf_attrs() returns early before writing to @level if the
+table walker returned an error. At the same time,
+kvm_pgtable_stage2_relax_perms() uses the level as a TLBI TTL hint when the
+error was EAGAIN, indicating the vCPU raced with a table update and the TLB
+entry it hit is now stale.
+
+Fall back to an unknown TTL if none was provided by the walk.
+
+Cc: stable@vger.kernel.org
+Fixes: be097997a273 ("KVM: arm64: Always invalidate TLB for stage-2 permission faults")
+Signed-off-by: Oliver Upton <oupton@kernel.org>
+Reviewed-by: Wei-Lin Chang <weilin.chang@arm.com>
+Link: https://patch.msgid.link/20260701231620.3300204-2-oupton@kernel.org
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/hyp/pgtable.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/kvm/hyp/pgtable.c
++++ b/arch/arm64/kvm/hyp/pgtable.c
+@@ -1291,7 +1291,7 @@ int kvm_pgtable_stage2_relax_perms(struc
+                                  enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags)
+ {
+       int ret;
+-      s8 level;
++      s8 level = TLBI_TTL_UNKNOWN;
+       kvm_pte_t set = 0, clr = 0;
+       if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
diff --git a/queue-6.18/kvm-arm64-fix-propagation-of-tlbi-level-in-kvm_pgtable_stage2_relax_perms.patch b/queue-6.18/kvm-arm64-fix-propagation-of-tlbi-level-in-kvm_pgtable_stage2_relax_perms.patch
new file mode 100644 (file)
index 0000000..da6eb4b
--- /dev/null
@@ -0,0 +1,46 @@
+From 8d187d4b33c262c0f3e44842553521151d8629e8 Mon Sep 17 00:00:00 2001
+From: Marc Zyngier <maz@kernel.org>
+Date: Tue, 7 Jul 2026 17:29:35 +0100
+Subject: KVM: arm64: Fix propagation of TLBI level in kvm_pgtable_stage2_relax_perms()
+
+From: Marc Zyngier <maz@kernel.org>
+
+commit 8d187d4b33c262c0f3e44842553521151d8629e8 upstream.
+
+Assigning the invalidation level (an s8 value) with TLBI_TTL_UNKNOWN
+(a 32bit signed value) is not ideal, to say the least. Instead of
+this, only pass TLBI_TTL_UNKNOWN to __kvm_tlb_flush_vmid_ipa_nsh()
+when we know for sure that we don't have a provided level.
+
+Fixes: 100baf0184896 ("KVM: arm64: Ensure level is always initialized when relaxing perms")
+Reported-by: Mark Brown <broonie@kernel.org>
+Reviewed-by: Oliver Upton <oupton@kernel.org>
+Link: https://lore.kernel.org/r/akztC7H2IsEKaq4i@sirena.org.uk
+Link: https://patch.msgid.link/20260707162935.1900874-1-maz@kernel.org
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/hyp/pgtable.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kvm/hyp/pgtable.c
++++ b/arch/arm64/kvm/hyp/pgtable.c
+@@ -1291,7 +1291,7 @@ int kvm_pgtable_stage2_relax_perms(struc
+                                  enum kvm_pgtable_prot prot, enum kvm_pgtable_walk_flags flags)
+ {
+       int ret;
+-      s8 level = TLBI_TTL_UNKNOWN;
++      s8 level;
+       kvm_pte_t set = 0, clr = 0;
+       if (prot & KVM_PTE_LEAF_ATTR_HI_SW)
+@@ -1308,7 +1308,8 @@ int kvm_pgtable_stage2_relax_perms(struc
+       ret = stage2_update_leaf_attrs(pgt, addr, 1, set, clr, NULL, &level, flags);
+       if (!ret || ret == -EAGAIN)
+-              kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr, level);
++              kvm_call_hyp(__kvm_tlb_flush_vmid_ipa_nsh, pgt->mmu, addr,
++                           (ret == -EAGAIN) ? TLBI_TTL_UNKNOWN : level);
+       return ret;
+ }
diff --git a/queue-6.18/kvm-arm64-nv-re-translate-vncr-before-injecting-abort.patch b/queue-6.18/kvm-arm64-nv-re-translate-vncr-before-injecting-abort.patch
new file mode 100644 (file)
index 0000000..78b17e1
--- /dev/null
@@ -0,0 +1,165 @@
+From bb645aa0a4caeaf7f9cd32e9a948594d434c1a8f Mon Sep 17 00:00:00 2001
+From: Oliver Upton <oupton@kernel.org>
+Date: Thu, 18 Jun 2026 16:42:04 -0700
+Subject: KVM: arm64: nv: Re-translate VNCR before injecting abort
+
+From: Oliver Upton <oupton@kernel.org>
+
+commit bb645aa0a4caeaf7f9cd32e9a948594d434c1a8f upstream.
+
+KVM faults in the VNCR page with FOLL_WRITE whenever the guest aborts
+for a write, similar to how a regular stage-2 mapping is handled. It is
+entirely possible that the guest reads from the VNCR before writing to
+it, in which case the PFN could only be read-only.
+
+Invalidate the VNCR TLB and re-fetch the translation upon taking a VNCR
+abort, allowing the host mapping to be faulted in for write the second
+time around. Interestingly enough, this also satisfies the ordering
+requirements of FEAT_ETS2/3 between descriptor updates and MMU faults.
+
+Cc: stable@vger.kernel.org
+Fixes: 2a359e072596 ("KVM: arm64: nv: Handle mapping of VNCR_EL2 at EL2")
+Reported-by: Sashiko <sashiko-bot@kernel.org>
+Signed-off-by: Oliver Upton <oupton@kernel.org>
+Link: https://patch.msgid.link/20260618234207.1063941-4-oupton@kernel.org
+Signed-off-by: Marc Zyngier <maz@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/kvm/nested.c |  115 ++++++++++++++++++------------------------------
+ 1 file changed, 44 insertions(+), 71 deletions(-)
+
+--- a/arch/arm64/kvm/nested.c
++++ b/arch/arm64/kvm/nested.c
+@@ -1329,88 +1329,61 @@ static void handle_vncr_perm(struct kvm_
+       kvm_inject_nested_sync(vcpu, esr);
+ }
+-static bool kvm_vncr_tlb_lookup(struct kvm_vcpu *vcpu)
+-{
+-      struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
+-
+-      lockdep_assert_held_read(&vcpu->kvm->mmu_lock);
+-
+-      if (!vt->valid)
+-              return false;
+-
+-      if (read_vncr_el2(vcpu) != vt->gva)
+-              return false;
+-
+-      if (vt->wr.nG)
+-              return get_asid_by_regime(vcpu, TR_EL20) == vt->wr.asid;
+-
+-      return true;
+-}
+-
+ int kvm_handle_vncr_abort(struct kvm_vcpu *vcpu)
+ {
+       struct vncr_tlb *vt = vcpu->arch.vncr_tlb;
+       u64 esr = kvm_vcpu_get_esr(vcpu);
++      bool is_gmem = false;
++      bool perm;
++      int ret;
+       WARN_ON_ONCE(!(esr & ESR_ELx_VNCR));
+       if (kvm_vcpu_abt_issea(vcpu))
+               return kvm_handle_guest_sea(vcpu);
+-      if (esr_fsc_is_permission_fault(esr)) {
+-              handle_vncr_perm(vcpu);
+-      } else if (esr_fsc_is_translation_fault(esr)) {
+-              bool valid, is_gmem = false;
+-              int ret;
+-
+-              scoped_guard(read_lock, &vcpu->kvm->mmu_lock)
+-                      valid = kvm_vncr_tlb_lookup(vcpu);
+-
+-              if (!valid)
+-                      ret = kvm_translate_vncr(vcpu, &is_gmem);
+-              else
+-                      ret = -EPERM;
+-
+-              switch (ret) {
+-              case -EAGAIN:
+-                      /* Let's try again... */
+-                      break;
+-              case -ENOMEM:
+-                      /*
+-                       * For guest_memfd, this indicates that it failed to
+-                       * create a folio to back the memory. Inform userspace.
+-                       */
+-                      if (is_gmem)
+-                              return 0;
+-                      /* Otherwise, let's try again... */
+-                      break;
+-              case -EFAULT:
+-              case -EIO:
+-              case -EHWPOISON:
+-                      if (is_gmem)
+-                              return 0;
+-                      fallthrough;
+-              case -EINVAL:
+-              case -ENOENT:
+-              case -EACCES:
+-                      /*
+-                       * Translation failed, inject the corresponding
+-                       * exception back to EL2.
+-                       */
+-                      esr &= ~ESR_ELx_FSC;
+-                      esr |= FIELD_PREP(ESR_ELx_FSC, vt->wr.fst);
+-
+-                      kvm_inject_nested_sync(vcpu, esr);
+-                      break;
+-              case -EPERM:
+-                      /* Hack to deal with POE until we get kernel support */
+-                      handle_vncr_perm(vcpu);
+-                      break;
+-              case 0:
+-                      break;
+-              }
+-      } else {
++      if (!esr_fsc_is_translation_fault(esr) && !esr_fsc_is_permission_fault(esr)) {
+               WARN_ONCE(1, "Unhandled VNCR abort, ESR=%llx\n", esr);
++              return 1;
++      }
++
++      ret = kvm_translate_vncr(vcpu, &is_gmem);
++      switch (ret) {
++      case -EAGAIN:
++              /* Let's try again... */
++              return 1;
++      case -ENOMEM:
++              /*
++               * For guest_memfd, this indicates that it failed to
++               * create a folio to back the memory. Inform userspace.
++               */
++              if (is_gmem)
++                      return 0;
++              /* Otherwise, let's try again... */
++              break;
++      case -EFAULT:
++      case -EIO:
++      case -EHWPOISON:
++              if (is_gmem)
++                      return 0;
++              fallthrough;
++      case -EINVAL:
++      case -ENOENT:
++      case -EACCES:
++              /*
++               * Translation failed, inject the corresponding
++               * exception back to EL2.
++               */
++              esr &= ~ESR_ELx_FSC;
++              esr |= FIELD_PREP(ESR_ELx_FSC, vt->wr.fst);
++
++              kvm_inject_nested_sync(vcpu, esr);
++              break;
++      case 0:
++              perm = kvm_is_write_fault(vcpu) ? vt->wr.pw && vt->hpa_writable : vt->wr.pr;
++              if (!perm)
++                      handle_vncr_perm(vcpu);
++              break;
+       }
+       return 1;
diff --git a/queue-6.18/mm-damon-core-always-put-unsuccessfully-committed-target-pids.patch b/queue-6.18/mm-damon-core-always-put-unsuccessfully-committed-target-pids.patch
new file mode 100644 (file)
index 0000000..8b0cce8
--- /dev/null
@@ -0,0 +1,154 @@
+From 6a66c557a2ab2609575bafd15e093669c05f9711 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Thu, 4 Jun 2026 18:38:48 -0700
+Subject: mm/damon/core: always put unsuccessfully committed target pids
+
+From: SeongJae Park <sj@kernel.org>
+
+commit 6a66c557a2ab2609575bafd15e093669c05f9711 upstream.
+
+damon_commit_target() puts and gets the destination and the source target
+pids.  It puts the destination target pid because it will be overwritten
+by the source target pid.  It gets the source pid because the caller is
+supposed to eventually put the pids.  In more detail, the caller will call
+damon_destroy_ctx() after damon_commit_ctx() to destroy the entire source
+context.  And in this case, [f]vaddr operation set's cleanup_target()
+callback will put the pids.
+
+The commit operation is made at the context level.  The operation can fail
+in multiple places including in the middle and after the targets commit
+operations.  For any such failures, immediately the error is returned to
+the damon_commit_ctx() caller.  If some or all of the source target pids
+were committed to the destination during the unsuccessful context commit
+attempt, those pids should be put twice.
+
+The source context will do the put operations using the above explained
+routine.  However, let's suppose the destination context was not
+originally using [f]vaddr operation set and the commit failed before the
+ops of the source context is committed.  The destination does not have the
+cleanup_target() ops callback, so it cannot put the pids via the
+damon_destroy_ctx().
+
+As a result, the pids are leaked.  The issue in the real world would be
+not very common.  The commit feature is for changing parameters of running
+DAMON context while inheriting internal status like the monitoring
+results.  The monitoring results of a physical address range ain't have
+things that are beneficial to be inherited to a virtual address ranges
+monitoring.  So the problem-causing DAMON control would be not very common
+in the real world.  That said, it is a supported feature.  And
+damon_commit_target() failure due to memory allocation is relatively
+realistic [1] if there are a huge number of target regions.
+
+Fix by putting the pids in the commit operation in case of the failures.
+
+The issue was discovered [2] by Sashiko.
+
+Link: https://lore.kernel.org/20260605013849.83750-1-sj@kernel.org
+Link: https://lore.kernel.org/20260603112306.58490-1-akinobu.mita@gmail.com [1]
+Link: https://lore.kernel.org/20260320020056.835-1-sj@kernel.org [2]
+Fixes: 83dc7bbaecae ("mm/damon/sysfs: use damon_commit_ctx()")
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.11.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/core.c |   49 +++++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 43 insertions(+), 6 deletions(-)
+
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -1173,10 +1173,36 @@ static int damon_commit_target(
+       return 0;
+ }
++/*
++ * damon_revert_target_commits() - revert unsuccessful target commits.
++ * @dst:      Commit destination context
++ * @failed:   Commit failed destination target
++ * @src:      Commit source context
++ *
++ * Revert target states that changed by damon_commit_target(), and cannot be
++ * cleaned up by the destination context's ops.cleanup_target().
++ */
++static void damon_revert_target_commits(struct damon_ctx *dst,
++              struct damon_target *failed, struct damon_ctx *src)
++{
++      struct damon_target *target;
++
++      if (!damon_target_has_pid(src))
++              return;
++      if (dst->ops.cleanup_target)
++              return;
++      damon_for_each_target(target, dst) {
++              if (target == failed)
++                      return;
++              put_pid(target->pid);
++      }
++}
++
+ static int damon_commit_targets(
+               struct damon_ctx *dst, struct damon_ctx *src)
+ {
+       struct damon_target *dst_target, *next, *src_target, *new_target;
++      struct damon_target *failed;
+       int i = 0, j = 0, err;
+       damon_for_each_target_safe(dst_target, next, dst) {
+@@ -1186,8 +1212,10 @@ static int damon_commit_targets(
+                                       dst_target, damon_target_has_pid(dst),
+                                       src_target, damon_target_has_pid(src),
+                                       src->min_sz_region);
+-                      if (err)
+-                              return err;
++                      if (err) {
++                              failed = dst_target;
++                              goto out;
++                      }
+               } else {
+                       struct damos *s;
+@@ -1201,22 +1229,29 @@ static int damon_commit_targets(
+               }
+       }
++      failed = NULL;
+       damon_for_each_target_safe(src_target, next, src) {
+               if (j++ < i)
+                       continue;
+               new_target = damon_new_target();
+-              if (!new_target)
+-                      return -ENOMEM;
++              if (!new_target) {
++                      err = -ENOMEM;
++                      goto out;
++              }
+               err = damon_commit_target(new_target, false,
+                               src_target, damon_target_has_pid(src),
+                               src->min_sz_region);
+               if (err) {
+                       damon_destroy_target(new_target, NULL);
+-                      return err;
++                      goto out;
+               }
+               damon_add_target(dst, new_target);
+       }
+       return 0;
++
++out:
++      damon_revert_target_commits(dst, failed, src);
++      return err;
+ }
+ /**
+@@ -1255,8 +1290,10 @@ int damon_commit_ctx(struct damon_ctx *d
+        */
+       if (!damon_attrs_equals(&dst->attrs, &src->attrs)) {
+               err = damon_set_attrs(dst, &src->attrs);
+-              if (err)
++              if (err) {
++                      damon_revert_target_commits(dst, NULL, src);
+                       return err;
++              }
+       }
+       dst->ops = src->ops;
+       dst->addr_unit = src->addr_unit;
diff --git a/queue-6.18/mm-damon-core-trace-esz-at-first-setup.patch b/queue-6.18/mm-damon-core-trace-esz-at-first-setup.patch
new file mode 100644 (file)
index 0000000..8be6879
--- /dev/null
@@ -0,0 +1,56 @@
+From 7e6cc35f5283eab81a14231a64ecd640b690c48c Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Wed, 20 May 2026 08:03:10 -0700
+Subject: mm/damon/core: trace esz at first setup
+
+From: SeongJae Park <sj@kernel.org>
+
+commit 7e6cc35f5283eab81a14231a64ecd640b690c48c upstream.
+
+DAMON traces effective size quota from the second update, only if a change
+has been made by the update.  Tracing only changed updates was an
+intentional decision to avoid unnecessary same value tracing.  Always
+skipping the first value is just an unintended mistake.
+
+The mistake makes the tracepoint based investigation incomplete, because
+the first effective size quota is never traced.  It is not a big issue
+when the 'consist' quota tuner is used, because it keeps changing the
+quota in the usual setup.
+
+However, when the 'temporal' tuner is used, the quota value is not changed
+before the goal achievement status is completely changed.  For example, if
+the DAMOS scheme is started with an under-achieved goal, the quota is set
+to the maximum value, and kept the same value until the goal is achieved.
+Because DAMON skips the first value, the user cannot know what effective
+quota the current scheme is using.  Only after the goal is achieved, the
+effective quota is changed to zero, and traced.
+
+Unconditionally trace the initial quota value to fix this problem.
+
+Note that the 'temporal' quota tuner was introduced by commit af738a6a00c1
+("mm/damon/core: introduce DAMOS_QUOTA_GOAL_TUNER_TEMPORAL"), which was
+added to 7.1-rc1.  But even with the 'consist' quota tuner, the tracing is
+unintentionally incomplete.  Hence this commit marks the introduction of
+the trace event as the broken commit.
+
+Link: https://lore.kernel.org/20260520150311.80925-1-sj@kernel.org
+Fixes: a86d695193bf ("mm/damon: add trace event for effective size quota")
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.17.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/core.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -2237,6 +2237,8 @@ static void damos_adjust_quota(struct da
+       if (!quota->total_charged_sz && !quota->charged_from) {
+               quota->charged_from = jiffies;
+               damos_set_effective_quota(quota, c);
++              if (trace_damos_esz_enabled())
++                      damos_trace_esz(c, s, quota);
+       }
+       /* New charge window starts */
diff --git a/queue-6.18/samples-damon-mtier-fail-early-if-address-range-parameters-are-invalid.patch b/queue-6.18/samples-damon-mtier-fail-early-if-address-range-parameters-are-invalid.patch
new file mode 100644 (file)
index 0000000..c56afb7
--- /dev/null
@@ -0,0 +1,72 @@
+From 7746d72c64054976887928d64d2caf25c5a6dcc0 Mon Sep 17 00:00:00 2001
+From: Zenghui Yu <yuzenghui@huawei.com>
+Date: Mon, 29 Jun 2026 07:44:31 -0700
+Subject: samples/damon/mtier: fail early if address range parameters are invalid
+
+From: Zenghui Yu <yuzenghui@huawei.com>
+
+commit 7746d72c64054976887928d64d2caf25c5a6dcc0 upstream.
+
+The comment on top of `struct damon_region` clearly says that
+
+    For any use case, @ar should be non-zero positive size.
+
+which is now verified in damon_verify_new_region() if the kernel is built
+with DAMON_DEBUG_SANITY.
+
+The WARN_ONCE() can be triggered if the mtier sample module is enabled
+before node{0,1}_{start,end}_addr have been properly initialized, which is
+obviously not good.
+
+ ------------[ cut here ]------------
+ start 0 >= end 0
+ WARNING: mm/damon/core.c:217 at damon_new_region+0xf4/0x118, CPU#59: bash/341468
+ Call trace:
+  damon_new_region+0xf4/0x118 (P)
+  damon_set_regions+0xfc/0x3c0
+  damon_sample_mtier_build_ctx+0xe8/0x3a8
+  damon_sample_mtier_start+0x1c/0x90
+  damon_sample_mtier_enable_store+0x98/0xb0
+  param_attr_store+0xb4/0x128
+  module_attr_store+0x2c/0x50
+  sysfs_kf_write+0x58/0x90
+  kernfs_fop_write_iter+0x16c/0x238
+  vfs_write+0x2c0/0x370
+  ksys_write+0x74/0x118
+  __arm64_sys_write+0x24/0x38
+  invoke_syscall+0xa8/0x118
+  el0_svc_common.constprop.0+0x48/0xf0
+  do_el0_svc+0x24/0x38
+  el0_svc+0x54/0x370
+  el0t_64_sync_handler+0xa0/0xe8
+  el0t_64_sync+0x1ac/0x1b0
+ ---[ end trace 0000000000000000 ]---
+
+Note that the same issue can happen if detect_node_addresses is true, and
+node 0 or 1 is memoryless.  Fix it together by checking the validity of
+parameters right before damon_new_region() and fail early if they're
+invalid.
+
+Link: https://lore.kernel.org/20260629144432.133962-1-sj@kernel.org
+Fixes: 82a08bde3cf7 ("samples/damon: implement a DAMON module for memory tiering")
+Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
+Signed-off-by: SJ Park <sj@kernel.org>
+Reviewed-by: SJ Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.16.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ samples/damon/mtier.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/samples/damon/mtier.c
++++ b/samples/damon/mtier.c
+@@ -120,6 +120,8 @@ static struct damon_ctx *damon_sample_mt
+               addr.end = promote ? node1_end_addr : node0_end_addr;
+       }
++      if (addr.start >= addr.end)
++              goto free_out;
+       region = damon_new_region(addr.start, addr.end);
+       if (!region)
+               goto free_out;
index 236af89c162cf1d93fef0de833ddb3f6e6639aad..43b66aa29bebecff0e3dc8925f8c46ca61e46995 100644 (file)
@@ -1592,3 +1592,10 @@ btrfs-remove-folio-parameter-from-ordered-io-related-functions.patch
 crypto-qat-fix-restarting-state-leak-on-allocation-failure.patch
 btrfs-fix-false-io-failure-after-falling-back-to-buffered-write.patch
 btrfs-fix-incorrect-buffered-io-fallback-for-append-direct-writes.patch
+kvm-arm64-ensure-level-is-always-initialized-when-relaxing-perms.patch
+kvm-arm64-fix-propagation-of-tlbi-level-in-kvm_pgtable_stage2_relax_perms.patch
+mm-damon-core-always-put-unsuccessfully-committed-target-pids.patch
+mm-damon-core-trace-esz-at-first-setup.patch
+samples-damon-mtier-fail-early-if-address-range-parameters-are-invalid.patch
+kvm-arm64-deduplicate-asid-retrieval-code.patch
+kvm-arm64-nv-re-translate-vncr-before-injecting-abort.patch