From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7B6CA484245 for ; Wed, 29 Jul 2026 12:26:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785327979; cv=none; b=SAOpjWmG5UEgDTPRGWylZSGl3ok6xF/0TJ7nkf9txPalO33lpECyCrrDCcmQ5HDQwkgMfYVSQ6oh2+LRwfHHvc84exslFBpeD1gg1LoP+GIy+jkuM5A/iEaVp2mmjsDWpjlWSSGURPm8hToUqqU5cVkgV7aFbJcV3+wFLIOJVLM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785327979; c=relaxed/simple; bh=g9NV7nRdXqfFL3CF8X7Uv58zGdVCBUS7EOV62bO/WS4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Oy3lpqu41WvJnWdrSV58RgOxmcEzKQShhAnduVirE/TyTqaYdOa08PXZ9R6a7v561OLvZ7RDcP36anMkXWRKPY3SfFGMutdCvhg2nUemOgCMZ2ltHFufPGg4Zt3h8kCu1GTUgMT/YkYMLlEjuaZWYOmjQ7N0aTdR+EL15KgMJb0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=DItmoeNA; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="DItmoeNA" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 630D11688; Wed, 29 Jul 2026 05:26:11 -0700 (PDT) Received: from a085714.blr.arm.com (a085714.arm.com [10.164.19.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id DCEBE3F66F; Wed, 29 Jul 2026 05:26:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785327975; bh=g9NV7nRdXqfFL3CF8X7Uv58zGdVCBUS7EOV62bO/WS4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DItmoeNADsjRN4kC/vUk9pTatICCrxY30uhea8jvosirq9eKyBdxl46nh5vk+JUeK NrIgHuMNJdP2tKiFSAdB4gMWzkdqaUVnEgwQpvOITIxt67Qgeslf1bg6cZLeXUwvCd 4FEx7FaYj9qc2uYRIStTSNKgNPRhbVHuFONaVtGo= From: Anshuman Khandual To: linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org Cc: Anshuman Khandual , Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Lorenzo Stoakes , Andrew Morton , David Hildenbrand , Mike Rapoport , Linu Cherian , linux-kernel@vger.kernel.org Subject: [PATCH 16/17] arm64/mm: Enable TLBIP instruction based TLB flush Date: Wed, 29 Jul 2026 17:54:51 +0530 Message-ID: <20260729122452.3797443-17-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260729122452.3797443-1-anshuman.khandual@arm.com> References: <20260729122452.3797443-1-anshuman.khandual@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Linu Cherian Add TLBIP instruction support for TLB flush operation updating all relevant macros as necessary. This enables back pgtable level hint and address range support during TLB flush operation for D128 translation. Signed-off-by: Linu Cherian Signed-off-by: Anshuman Khandual --- arch/arm64/include/asm/tlbflush.h | 68 +++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 9 deletions(-) diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index c103380ec87e..3b6384b9c200 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -41,6 +41,25 @@ #define __tlbi(op, ...) __TLBI_N(op, ##__VA_ARGS__, 1, 0) +#ifdef CONFIG_ARM64_D128 +#define __tlbip(op, arg) do { \ + asm (ARM64_ASM_PREAMBLE \ + ".arch_extension d128\n\t" \ + "tlbip " #op ", %0, %H0\n" \ + : : "r" (arg.full)); \ +} while (0) + +#define __tlbip_user(op, arg) do { \ + if (arm64_kernel_unmapped_at_el0()) { \ + arg.low |= USER_ASID_FLAG; \ + __tlbip(op, (arg)); \ + } \ +} while (0) + +#endif + +#define TLBI_ASID_MASK GENMASK_ULL(63, 48) + #define __tlbi_user(op, arg) do { \ if (arm64_kernel_unmapped_at_el0()) \ __tlbi(op, (arg) | USER_ASID_FLAG); \ @@ -130,9 +149,15 @@ static inline void sme_dvmsync_batch(void) #define TLBI_TTL_UNKNOWN INT_MAX +#ifdef CONFIG_ARM64_D128 +typedef union __u128_halves tlbi_arg_t; +#define __tlbi_wrapper(op, arg) __tlbip(op, arg) +#define __tlbi_user_wrapper(op, arg) __tlbip_user(op, arg) +#else typedef u64 tlbi_arg_t; #define __tlbi_wrapper(op, arg) __tlbi(op, arg) #define __tlbi_user_wrapper(op, arg) __tlbi_user(op, arg) +#endif typedef void (*tlbi_op)(tlbi_arg_t arg); @@ -179,17 +204,28 @@ static __always_inline void ipas2e1is(tlbi_arg_t arg) __tlbi_wrapper(ipas2e1is, arg); } -static __always_inline void __tlbi_level_asid(tlbi_op op, u64 addr, u32 level, - u16 asid) +static __always_inline void __tlbi_update_level(u32 level, u64 *arg) { - u64 arg = __TLBI_VADDR(addr, asid); - if (alternative_has_cap_unlikely(ARM64_HAS_ARMv8_4_TTL) && level <= 3) { u64 ttl = level | (get_trans_granule() << 2); - FIELD_MODIFY(TLBI_TTL_MASK, &arg, ttl); + FIELD_MODIFY(TLBI_TTL_MASK, arg, ttl); } +} + +static __always_inline void __tlbi_level_asid(tlbi_op op, u64 addr, u32 level, u16 asid) +{ +#ifdef CONFIG_ARM64_D128 + union __u128_halves arg; + + arg.low = FIELD_PREP(TLBI_ASID_MASK, asid); + __tlbi_update_level(level, &arg.low); + arg.high = addr >> 12; +#else + u64 arg = __TLBI_VADDR(addr, asid); + __tlbi_update_level(level, &arg); +#endif op(arg); } @@ -475,19 +511,33 @@ static __always_inline void ripas2e1is(tlbi_arg_t arg) __tlbi_wrapper(ripas2e1is, arg); } -static __always_inline void __tlbi_range(tlbi_op op, u64 addr, - u16 asid, int scale, int num, - u32 level, bool lpa2) +static __always_inline u64 __tlbi_range_args_encode_comm(u16 asid, int scale, int num, u32 level) { u64 arg = 0; - arg |= FIELD_PREP(TLBIR_BADDR_MASK, addr >> (lpa2 ? 16 : PAGE_SHIFT)); arg |= FIELD_PREP(TLBIR_TTL_MASK, level > 3 ? 0 : level); arg |= FIELD_PREP(TLBIR_NUM_MASK, num); arg |= FIELD_PREP(TLBIR_SCALE_MASK, scale); arg |= FIELD_PREP(TLBIR_TG_MASK, get_trans_granule()); arg |= FIELD_PREP(TLBIR_ASID_MASK, asid); + return arg; +} + +static __always_inline void __tlbi_range(tlbi_op op, u64 addr, + u16 asid, int scale, int num, + u32 level, bool lpa2) +{ +#ifdef CONFIG_ARM64_D128 + union __u128_halves arg; + + arg.low = __tlbi_range_args_encode_comm(asid, scale, num, level); + arg.high = addr >> 12; +#else + u64 arg = __tlbi_range_args_encode_comm(asid, scale, num, level); + + arg |= FIELD_PREP(TLBIR_BADDR_MASK, addr >> (lpa2 ? 16 : PAGE_SHIFT)); +#endif op(arg); } -- 2.43.0