--- /dev/null
+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();
+
--- /dev/null
+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)
--- /dev/null
+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;
+ }
+
--- /dev/null
+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;
--- /dev/null
+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;
--- /dev/null
+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 */
--- /dev/null
+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;
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