From nobody Fri Nov 14 19:47:00 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 1761221329213158.39619462737664; Thu, 23 Oct 2025 05:08:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vBu70-0006Cf-RT; Thu, 23 Oct 2025 08:08:13 -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 1vBu6X-00067d-HD for qemu-devel@nongnu.org; Thu, 23 Oct 2025 08:07:41 -0400 Received: from mail.loongson.cn ([114.242.206.163]) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1vBu6U-0004vu-1V for qemu-devel@nongnu.org; Thu, 23 Oct 2025 08:07:41 -0400 Received: from loongson.cn (unknown [10.2.5.213]) by gateway (Coremail) with SMTP id _____8Cxf9N7Gvpocr0ZAA--.55219S3; Thu, 23 Oct 2025 20:07:23 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.213]) by front1 (Coremail) with SMTP id qMiowJDx_8NuGvporJkDAQ--.47140S14; Thu, 23 Oct 2025 20:07:23 +0800 (CST) From: Bibo Mao To: qemu-devel@nongnu.org Cc: Song Gao Subject: [PULL 12/14] target/loongarch: Add basic hardware PTW support Date: Thu, 23 Oct 2025 20:07:08 +0800 Message-Id: <20251023120710.3086556-13-maobibo@loongson.cn> X-Mailer: git-send-email 2.39.3 In-Reply-To: <20251023120710.3086556-1-maobibo@loongson.cn> References: <20251023120710.3086556-1-maobibo@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJDx_8NuGvporJkDAQ--.47140S14 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: 1761221330860154100 Content-Type: text/plain; charset="utf-8" However with hardware PTW supported, hardware will search page table with TLB miss. Also if there is no TLB miss however bit Present is not set, hardware PTW will happen also. Because there is odd/even page in one TLB entry on LoongArch system, for example in the first time odd TLB entry is valid and even TLB entry is 0. When software accesses with address within even page, there is no TLB miss only that TLB entry is 0. In this condition, hardwre PTW will happen also. Signed-off-by: Bibo Mao Reviewed-by: Song Gao --- target/loongarch/cpu-mmu.h | 2 ++ target/loongarch/cpu_helper.c | 17 ++++++++++++++--- target/loongarch/tcg/tlb_helper.c | 25 +++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h index 3d6ae6cf2c..158bb61429 100644 --- a/target/loongarch/cpu-mmu.h +++ b/target/loongarch/cpu-mmu.h @@ -67,6 +67,8 @@ 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_ptw(CPULoongArchState *env, MMUContext *context, + int access_type, int mmu_idx, int debug); void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base, uint64_t *dir_width, unsigned int 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 caad357adf..55efe44cb4 100644 --- a/target/loongarch/cpu_helper.c +++ b/target/loongarch/cpu_helper.c @@ -107,11 +107,11 @@ TLBRet loongarch_check_pte(CPULoongArchState *env, MM= UContext *context, return TLBRET_MATCH; } =20 -static TLBRet loongarch_ptw(CPULoongArchState *env, MMUContext *context, - int access_type, int mmu_idx, int debug) +TLBRet loongarch_ptw(CPULoongArchState *env, MMUContext *context, + int access_type, int mmu_idx, int debug) { CPUState *cs =3D env_cpu(env); - target_ulong index, phys; + target_ulong index =3D 0, phys =3D 0; uint64_t dir_base, dir_width; uint64_t base; int level; @@ -139,6 +139,8 @@ static TLBRet loongarch_ptw(CPULoongArchState *env, MMU= Context *context, if (level) { if (FIELD_EX64(base, TLBENTRY, HUGE)) { /* base is a huge pte */ + index =3D 0; + dir_base -=3D 1; break; } else { /* Discard high bits with page directory table */ @@ -156,6 +158,15 @@ static TLBRet loongarch_ptw(CPULoongArchState *env, MM= UContext *context, base =3D FIELD_DP64(base, TLBENTRY, HGLOBAL, 0); base =3D FIELD_DP64(base, TLBENTRY, G, 1); } + + context->pte_buddy[index] =3D base; + context->pte_buddy[1 - index] =3D base + BIT_ULL(dir_base); + base +=3D (BIT_ULL(dir_base) & address); + } else 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 92f89841b0..1f3aaaa41d 100644 --- a/target/loongarch/tcg/tlb_helper.c +++ b/target/loongarch/tcg/tlb_helper.c @@ -601,6 +601,18 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *e= nv, } } =20 +static void ptw_update_tlb(CPULoongArchState *env, MMUContext *context) +{ + int index; + + index =3D context->tlb_index; + if (index < 0) { + index =3D get_tlb_random_index(env, context->addr, context->ps); + } + + update_tlb_index(env, context, index); +} + bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr) @@ -613,7 +625,20 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr addres= s, int size, =20 /* Data access */ context.addr =3D address; + context.tlb_index =3D -1; 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_ptw(env, &context, access_type, mmu_idx, 0); + if (ret =3D=3D TLBRET_MATCH) { + ptw_update_tlb(env, &context); + } + } else if (context.tlb_index >=3D 0) { + invalidate_tlb(env, context.tlb_index); + } + } + if (ret =3D=3D TLBRET_MATCH) { physical =3D context.physical; prot =3D context.prot; --=20 2.43.5