From nobody Sat Nov 15 08:48:40 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1755157143566862.0652838126347; Thu, 14 Aug 2025 00:39:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umSW2-0006wi-VH; Thu, 14 Aug 2025 03:36:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1umSVt-0006uF-Fi for qemu-devel@nongnu.org; Thu, 14 Aug 2025 03:36:42 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1umSVq-0004S1-0c for qemu-devel@nongnu.org; Thu, 14 Aug 2025 03:36:40 -0400 Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8CxTOL6kZ1oDqs_AQ--.14533S3; Thu, 14 Aug 2025 15:36:26 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJCxM+T4kZ1oM9xKAA--.22944S9; Thu, 14 Aug 2025 15:36:26 +0800 (CST) From: Bibo Mao To: Song Gao , Richard Henderson Cc: Jiaxun Yang , qemu-devel@nongnu.org Subject: [PATCH 7/9] target/loongarch: Add basic hardware PTW support Date: Thu, 14 Aug 2025 15:36:22 +0800 Message-Id: <20250814073624.430928-8-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20250814073624.430928-1-maobibo@loongson.cn> References: <20250814073624.430928-1-maobibo@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJCxM+T4kZ1oM9xKAA--.22944S9 X-CM-SenderInfo: xpdruxter6z05rqj20fqof0/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=114.242.206.163; envelope-from=maobibo@loongson.cn; helo=mail.loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1755157144953116600 Content-Type: text/plain; charset="utf-8" With software PTW, there is TLB refill exception if there is TLB miss. However with hardware PTW supported, hardware will search page table with TLB miss. Also if Present bit is not set, hardware PTW will take, it is used in odd/even TLB entry. For example in the first time odd TLB entry is valid and even TLB entry is 0. When software accesses with address from even page, there is no TLB miss only that TLB entry is 0. In this condition, hardwre PTW will take also. Signed-off-by: Bibo Mao --- target/loongarch/cpu-mmu.h | 3 +++ target/loongarch/cpu_helper.c | 17 ++++++++++++++--- target/loongarch/tcg/tlb_helper.c | 26 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h index c3e869234a..2e63324abe 100644 --- a/target/loongarch/cpu-mmu.h +++ b/target/loongarch/cpu-mmu.h @@ -67,6 +67,9 @@ TLBRet loongarch_check_pte(CPULoongArchState *env, MMUCon= text *context, TLBRet get_physical_address(CPULoongArchState *env, MMUContext *context, MMUAccessType access_type, int mmu_idx, int is_debug); +TLBRet loongarch_page_table_walker(CPULoongArchState *env, + MMUContext *context, + int access_type, int mmu_idx); void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, uint64_t *dir_width, target_ulong level); hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c index 2e07049425..79c994255f 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -106,9 +106,9 @@ TLBRet loongarch_check_pte(CPULoongArchState *env, MMUC= ontext *context, return TLBRET_MATCH; } =20 -static TLBRet loongarch_page_table_walker(CPULoongArchState *env, - MMUContext *context, - int access_type, int mmu_idx) +TLBRet loongarch_page_table_walker(CPULoongArchState *env, + MMUContext *context, + int access_type, int mmu_idx) { CPUState *cs =3D env_cpu(env); target_ulong index, phys; @@ -151,12 +151,23 @@ static TLBRet loongarch_page_table_walker(CPULoongArc= hState *env, base =3D FIELD_DP64(base, TLBENTRY, HGLOBAL, 0); base =3D FIELD_DP64(base, TLBENTRY, G, 1); } + + dir_base -=3D 1; + context->pte_buddy[0] =3D base; + context->pte_buddy[1] =3D base + BIT_ULL(dir_base); + base +=3D (BIT_ULL(dir_base) & address); } else { /* Normal Page. base points to pte */ get_dir_base_width(env, &dir_base, &dir_width, 0); index =3D (address >> dir_base) & ((1 << dir_width) - 1); phys =3D base | index << 3; base =3D ldq_phys(cs->as, phys); + if (cpu_has_ptw(env)) { + index &=3D 1; + context->pte_buddy[index] =3D base; + context->pte_buddy[1 - index] =3D ldq_phys(cs->as, + phys + 8 * (1 - 2 * index)); + } } =20 context->ps =3D dir_base; diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_h= elper.c index 50c7583c6c..7fdac475b3 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -621,6 +621,20 @@ static inline void tlb_set_accessed(CPULoongArchState = *env, vaddr address, tlb->tlb_misc |=3D TLB_MISC_KM_PTE(n); } =20 +static void ptw_update_tlb(CPULoongArchState *env, MMUContext *context) +{ + int index; + bool match; + + match =3D loongarch_tlb_search(env, context->addr, &index); + if (!match) { + index =3D get_tlb_random_index(env, context->addr, context->ps); + } + + invalidate_tlb(env, index); + fill_tlb_entry(env, env->tlb + index, context); +} + bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr) @@ -634,6 +648,18 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr addres= s, int size, /* Data access */ context.addr =3D address; ret =3D get_physical_address(env, &context, access_type, mmu_idx, 0); + if (ret !=3D TLBRET_MATCH && cpu_has_ptw(env)) { + /* Take HW PTW if TLB missed or bit P is zero */ + if (ret =3D=3D TLBRET_NOMATCH || ret =3D=3D TLBRET_INVALID) { + ret =3D loongarch_page_table_walker(env, &context, access_type= , mmu_idx); + if (ret =3D=3D TLBRET_MATCH) { + ptw_update_tlb(env, &context); + } + } else { + invalidate_tlb(env, context.tlb_index); + } + } + if (ret =3D=3D TLBRET_MATCH) { physical =3D context.physical; prot =3D context.prot; --=20 2.39.3