* [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu
@ 2025-07-25 1:37 Bibo Mao
2025-07-25 1:37 ` [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory Bibo Mao
` (16 more replies)
0 siblings, 17 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
There is some enhance about LoongArch mmu tcg emulation, add new
header file cpu-mmu.h and function loongarch_check_pte(). Function
loongarch_check_pte() can work on both TLB entry and pte entry.
This patchset mainly is code cleanup and enhancement, its main
purpose is to work for hardware page table walk emluation in future.
---
v2 ... v3:
1. Track user space page accessed in kernel mode, since mmu idx usage
is different between QEMU TLB and LoongArch TLB emulation.
2. Add 48 bit to 64 bit signed extension conversion with virtual address,
since QEMU TLB use 64 bit address, LoongArch TLB is 48 bit.
3. Optimization with LoongArch TLB update, do not flush QEMU TLB if
updated TLB entry is the same or invalid.
4. Optimization with new LoongArch TLB entry selection, invalid entry
or different ASID with higher priority than the random method.
v1 ... v2:
1. Rename structure name pte_context with mmu_context, since it
can be extended to get DMW or DA mmu idx and window size
2. Add fine-grained tlb flush method
3. Fix some issues in function invalidate_tlb_entry() to flush tlb,
such as bitmap method with mmu idx, page size and address
calculation
---
Bibo Mao (17):
target/loongarch: Move some function definition to kvm directory
target/loongarch: Define function loongarch_cpu_post_init as static
target/loongarch: Set page size in TLB misc with STLB
target/loongarch: Add header file cpu-mmu.h
target/loongarch: Add common function loongarch_check_pte()
target/loongarch: Use loongarch_check_pte() with page table walking
target/loongarch: Add parameter mmu_context with
loongarch_page_table_walker
target/loongarch: Add parameter mmu_context with
loongarch_map_tlb_entry
target/loongarch: Add parameter mmu_context with
loongarch_get_addr_from_tlb
target/loongarch: Add parameter mmu_context with loongarch_map_address
target/loongarch: Add parameter mmu_context with get_physical_address
target/loongarch: Track user mode address accessed in kernel mode
target/loongarch: Use correct address when flush tlb
target/loongarch: Use mmu idx bitmap method when flush tlb
target/loongarch: Add parameter tlb pointer with fill_tlb_entry
target/loongarch: Reduce TLB flush with helper_tlbwr
target/loongarch: Update TLB index selection method
hw/loongarch/virt.c | 1 +
target/loongarch/cpu-mmu.h | 41 ++++
target/loongarch/cpu.c | 181 +++++++++---------
target/loongarch/cpu.h | 22 +--
target/loongarch/cpu_helper.c | 131 ++++++++-----
target/loongarch/internals.h | 20 --
target/loongarch/kvm/kvm_loongarch.h | 4 +-
target/loongarch/tcg/csr_helper.c | 1 +
target/loongarch/tcg/tcg_loongarch.h | 4 +-
target/loongarch/tcg/tlb_helper.c | 272 ++++++++++++++++-----------
10 files changed, 395 insertions(+), 282 deletions(-)
create mode 100644 target/loongarch/cpu-mmu.h
base-commit: 9e601684dc24a521bb1d23215a63e5c6e79ea0bb
--
2.39.3
^ permalink raw reply [flat|nested] 34+ messages in thread
* [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 23:37 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 02/17] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
` (15 subsequent siblings)
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
Move function definition specified with kvm to the corresponding
directory. Also remove header file "cpu.h" including outside of
macro QEMU_KVM_LOONGARCH_H.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
hw/loongarch/virt.c | 1 +
target/loongarch/cpu.h | 9 ---------
target/loongarch/kvm/kvm_loongarch.h | 4 ++--
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b15ada2078..31215b7785 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -46,6 +46,7 @@
#include "hw/block/flash.h"
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
+#include "kvm/kvm_loongarch.h"
static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 9538e8d61d..bbe6db33f1 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -496,13 +496,4 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
void loongarch_cpu_post_init(Object *obj);
-#ifdef CONFIG_KVM
-void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu);
-#else
-static inline void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu)
-{
-}
-#endif
-void kvm_loongarch_init_irq_routing(void);
-
#endif /* LOONGARCH_CPU_H */
diff --git a/target/loongarch/kvm/kvm_loongarch.h b/target/loongarch/kvm/kvm_loongarch.h
index 1051a341ec..51475675d6 100644
--- a/target/loongarch/kvm/kvm_loongarch.h
+++ b/target/loongarch/kvm/kvm_loongarch.h
@@ -5,11 +5,11 @@
* Copyright (c) 2023 Loongson Technology Corporation Limited
*/
-#include "cpu.h"
-
#ifndef QEMU_KVM_LOONGARCH_H
#define QEMU_KVM_LOONGARCH_H
+void kvm_loongarch_cpu_post_init(LoongArchCPU *cpu);
+void kvm_loongarch_init_irq_routing(void);
int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level);
void kvm_arch_reset_vcpu(CPUState *cs);
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 02/17] target/loongarch: Define function loongarch_cpu_post_init as static
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
2025-07-25 1:37 ` [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 23:38 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 03/17] target/loongarch: Set page size in TLB misc with STLB Bibo Mao
` (14 subsequent siblings)
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
Function loongarch_cpu_post_init() is implemented and used in the
same file target/loongarch/cpu.c, it can be defined as static function.
This patch moves implementation about function loongarch_cpu_post_init()
before it is referenced. And it is only code movement, no function
change.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu.c | 180 ++++++++++++++++++++---------------------
target/loongarch/cpu.h | 2 -
2 files changed, 90 insertions(+), 92 deletions(-)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index abad84c054..b96429ffb1 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -422,6 +422,96 @@ static void loongarch_la464_init_csr(Object *obj)
#endif
}
+static bool loongarch_get_lsx(Object *obj, Error **errp)
+{
+ return LOONGARCH_CPU(obj)->lsx != ON_OFF_AUTO_OFF;
+}
+
+static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+ uint32_t val;
+
+ cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+ if (cpu->lsx == ON_OFF_AUTO_OFF) {
+ cpu->lasx = ON_OFF_AUTO_OFF;
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
+ error_setg(errp, "Failed to disable LSX since LASX is enabled");
+ return;
+ }
+ }
+
+ if (kvm_enabled()) {
+ /* kvm feature detection in function kvm_arch_init_vcpu */
+ return;
+ }
+
+ /* LSX feature detection in TCG mode */
+ val = cpu->env.cpucfg[2];
+ if (cpu->lsx == ON_OFF_AUTO_ON) {
+ if (FIELD_EX32(val, CPUCFG2, LSX) == 0) {
+ error_setg(errp, "Failed to enable LSX in TCG mode");
+ return;
+ }
+ } else {
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, 0);
+ val = cpu->env.cpucfg[2];
+ }
+
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
+}
+
+static bool loongarch_get_lasx(Object *obj, Error **errp)
+{
+ return LOONGARCH_CPU(obj)->lasx != ON_OFF_AUTO_OFF;
+}
+
+static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+ uint32_t val;
+
+ cpu->lasx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+ if ((cpu->lsx == ON_OFF_AUTO_OFF) && (cpu->lasx == ON_OFF_AUTO_ON)) {
+ error_setg(errp, "Failed to enable LASX since lSX is disabled");
+ return;
+ }
+
+ if (kvm_enabled()) {
+ /* kvm feature detection in function kvm_arch_init_vcpu */
+ return;
+ }
+
+ /* LASX feature detection in TCG mode */
+ val = cpu->env.cpucfg[2];
+ if (cpu->lasx == ON_OFF_AUTO_ON) {
+ if (FIELD_EX32(val, CPUCFG2, LASX) == 0) {
+ error_setg(errp, "Failed to enable LASX in TCG mode");
+ return;
+ }
+ }
+
+ cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
+}
+
+static void loongarch_cpu_post_init(Object *obj)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+ cpu->lbt = ON_OFF_AUTO_OFF;
+ cpu->pmu = ON_OFF_AUTO_OFF;
+ cpu->lsx = ON_OFF_AUTO_AUTO;
+ cpu->lasx = ON_OFF_AUTO_AUTO;
+ object_property_add_bool(obj, "lsx", loongarch_get_lsx,
+ loongarch_set_lsx);
+ object_property_add_bool(obj, "lasx", loongarch_get_lasx,
+ loongarch_set_lasx);
+ /* lbt is enabled only in kvm mode, not supported in tcg mode */
+ if (kvm_enabled()) {
+ kvm_loongarch_cpu_post_init(cpu);
+ }
+}
+
static void loongarch_la464_initfn(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -683,96 +773,6 @@ static void loongarch_cpu_unrealizefn(DeviceState *dev)
lacc->parent_unrealize(dev);
}
-static bool loongarch_get_lsx(Object *obj, Error **errp)
-{
- return LOONGARCH_CPU(obj)->lsx != ON_OFF_AUTO_OFF;
-}
-
-static void loongarch_set_lsx(Object *obj, bool value, Error **errp)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
- uint32_t val;
-
- cpu->lsx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
- if (cpu->lsx == ON_OFF_AUTO_OFF) {
- cpu->lasx = ON_OFF_AUTO_OFF;
- if (cpu->lasx == ON_OFF_AUTO_ON) {
- error_setg(errp, "Failed to disable LSX since LASX is enabled");
- return;
- }
- }
-
- if (kvm_enabled()) {
- /* kvm feature detection in function kvm_arch_init_vcpu */
- return;
- }
-
- /* LSX feature detection in TCG mode */
- val = cpu->env.cpucfg[2];
- if (cpu->lsx == ON_OFF_AUTO_ON) {
- if (FIELD_EX32(val, CPUCFG2, LSX) == 0) {
- error_setg(errp, "Failed to enable LSX in TCG mode");
- return;
- }
- } else {
- cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, 0);
- val = cpu->env.cpucfg[2];
- }
-
- cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LSX, value);
-}
-
-static bool loongarch_get_lasx(Object *obj, Error **errp)
-{
- return LOONGARCH_CPU(obj)->lasx != ON_OFF_AUTO_OFF;
-}
-
-static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
- uint32_t val;
-
- cpu->lasx = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
- if ((cpu->lsx == ON_OFF_AUTO_OFF) && (cpu->lasx == ON_OFF_AUTO_ON)) {
- error_setg(errp, "Failed to enable LASX since lSX is disabled");
- return;
- }
-
- if (kvm_enabled()) {
- /* kvm feature detection in function kvm_arch_init_vcpu */
- return;
- }
-
- /* LASX feature detection in TCG mode */
- val = cpu->env.cpucfg[2];
- if (cpu->lasx == ON_OFF_AUTO_ON) {
- if (FIELD_EX32(val, CPUCFG2, LASX) == 0) {
- error_setg(errp, "Failed to enable LASX in TCG mode");
- return;
- }
- }
-
- cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
-}
-
-void loongarch_cpu_post_init(Object *obj)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(obj);
-
- cpu->lbt = ON_OFF_AUTO_OFF;
- cpu->pmu = ON_OFF_AUTO_OFF;
- cpu->lsx = ON_OFF_AUTO_AUTO;
- cpu->lasx = ON_OFF_AUTO_AUTO;
- object_property_add_bool(obj, "lsx", loongarch_get_lsx,
- loongarch_set_lsx);
- object_property_add_bool(obj, "lasx", loongarch_get_lasx,
- loongarch_set_lasx);
- /* lbt is enabled only in kvm mode, not supported in tcg mode */
- if (kvm_enabled()) {
- kvm_loongarch_cpu_post_init(cpu);
- }
-}
-
static void loongarch_cpu_init(Object *obj)
{
#ifndef CONFIG_USER_ONLY
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index bbe6db33f1..7731f6acdc 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -494,6 +494,4 @@ static inline void set_pc(CPULoongArchState *env, uint64_t value)
#define CPU_RESOLVING_TYPE TYPE_LOONGARCH_CPU
-void loongarch_cpu_post_init(Object *obj);
-
#endif /* LOONGARCH_CPU_H */
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 03/17] target/loongarch: Set page size in TLB misc with STLB
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
2025-07-25 1:37 ` [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory Bibo Mao
2025-07-25 1:37 ` [PATCH v3 02/17] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h Bibo Mao
` (13 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With VTLB different TLB entry may have different page size, and
page size is set in PS field of TLB misc. However with STLB, all the
TLB entries have the same page size, page size comes from register
CSR_STLBPS, PS field of TLB misc is not used.
Here PS field of TLB misc is used with all TLB entries, even with
STLB, it is convenient with TLB maintainance operation.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 41 ++++++++-----------------------
1 file changed, 10 insertions(+), 31 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 8872593ff0..3ea0e153b1 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -110,11 +110,8 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
if (!tlb_e) {
return;
}
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
@@ -173,11 +170,8 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
lo1 = env->CSR_TLBELO1;
}
- /* Only MTLB has the ps fields */
- if (index >= LOONGARCH_STLB) {
- tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
- }
-
+ /* Store page size in field PS */
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1);
csr_asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
@@ -283,12 +277,7 @@ void helper_tlbrd(CPULoongArchState *env)
index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
tlb = &env->tlb[index];
-
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
if (!tlb_e) {
@@ -476,11 +465,8 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -509,11 +495,8 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
if (!tlb_e) {
continue;
}
- if (i >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
vpn = (addr & TARGET_VIRT_MASK) >> (tlb_ps + 1);
compare_shift = tlb_ps + 1 - R_TLB_MISC_VPPN_SHIFT;
@@ -673,11 +656,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
uint64_t tlb_entry, tlb_ppn;
uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
- if (index >= LOONGARCH_STLB) {
- tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
- } else {
- tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
- }
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
n = (address >> tlb_ps) & 0x1;/* Odd or even */
tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (2 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 03/17] target/loongarch: Set page size in TLB misc with STLB Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-26 1:10 ` Richard Henderson
2025-07-26 1:16 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
` (12 subsequent siblings)
16 siblings, 2 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
New header file cpu-mmu.h is added and move mmu relative function
declaration to this file.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu-mmu.h | 30 ++++++++++++++++++++++++++++++
target/loongarch/cpu.c | 1 +
target/loongarch/cpu_helper.c | 1 +
target/loongarch/internals.h | 20 --------------------
target/loongarch/tcg/csr_helper.c | 1 +
target/loongarch/tcg/tlb_helper.c | 1 +
6 files changed, 34 insertions(+), 20 deletions(-)
create mode 100644 target/loongarch/cpu-mmu.h
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
new file mode 100644
index 0000000000..4c5cbd7425
--- /dev/null
+++ b/target/loongarch/cpu-mmu.h
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch CPU parameters for QEMU.
+ *
+ * Copyright (c) 2025 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_CPU_MMU_H
+#define LOONGARCH_CPU_MMU_H
+
+enum {
+ TLBRET_MATCH = 0,
+ TLBRET_BADADDR = 1,
+ TLBRET_NOMATCH = 2,
+ TLBRET_INVALID = 3,
+ TLBRET_DIRTY = 4,
+ TLBRET_RI = 5,
+ TLBRET_XI = 6,
+ TLBRET_PE = 7,
+};
+
+bool check_ps(CPULoongArchState *ent, uint8_t ps);
+int get_physical_address(CPULoongArchState *env, hwaddr *physical,
+ int *prot, target_ulong address,
+ MMUAccessType access_type, int mmu_idx, int is_debug);
+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);
+
+#endif /* LOONGARCH_CPU_MMU_H */
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index b96429ffb1..990985708e 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -17,6 +17,7 @@
#include "hw/qdev-properties.h"
#include "exec/translation-block.h"
#include "cpu.h"
+#include "cpu-mmu.h"
#include "internals.h"
#include "fpu/softfloat-helpers.h"
#include "csr.h"
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index e172b11ce1..2e8d3d7cfb 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -13,6 +13,7 @@
#include "exec/target_page.h"
#include "internals.h"
#include "cpu-csr.h"
+#include "cpu-mmu.h"
#include "tcg/tcg_loongarch.h"
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index a7384b0d31..e50d109767 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -32,19 +32,6 @@ void restore_fp_status(CPULoongArchState *env);
#endif
#ifndef CONFIG_USER_ONLY
-enum {
- TLBRET_MATCH = 0,
- TLBRET_BADADDR = 1,
- TLBRET_NOMATCH = 2,
- TLBRET_INVALID = 3,
- TLBRET_DIRTY = 4,
- TLBRET_RI = 5,
- TLBRET_XI = 6,
- TLBRET_PE = 7,
-};
-
-bool check_ps(CPULoongArchState *ent, uint8_t ps);
-
extern const VMStateDescription vmstate_loongarch_cpu;
void loongarch_cpu_set_irq(void *opaque, int irq, int level);
@@ -54,13 +41,6 @@ uint64_t cpu_loongarch_get_constant_timer_counter(LoongArchCPU *cpu);
uint64_t cpu_loongarch_get_constant_timer_ticks(LoongArchCPU *cpu);
void cpu_loongarch_store_constant_timer_config(LoongArchCPU *cpu,
uint64_t value);
-int get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
- MMUAccessType access_type, int mmu_idx, int is_debug);
-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);
-
#endif /* !CONFIG_USER_ONLY */
uint64_t read_fcc(CPULoongArchState *env);
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
index 28b1bb86bd..0d99e2c92b 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -16,6 +16,7 @@
#include "accel/tcg/cpu-ldst.h"
#include "hw/irq.h"
#include "cpu-csr.h"
+#include "cpu-mmu.h"
target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
{
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 3ea0e153b1..1f49619e7f 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -10,6 +10,7 @@
#include "qemu/guest-random.h"
#include "cpu.h"
+#include "cpu-mmu.h"
#include "internals.h"
#include "exec/helper-proto.h"
#include "exec/cputlb.h"
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte()
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (3 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-26 1:19 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 06/17] target/loongarch: Use loongarch_check_pte() with page table walking Bibo Mao
` (11 subsequent siblings)
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
Common function loongarch_check_pte() is to check tlb entry, return
the physical address and access priviledge. Also it can be used with
page table entry, which is used in page table walker.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu-mmu.h | 10 +++++
target/loongarch/cpu_helper.c | 62 ++++++++++++++++++++++++++++++
target/loongarch/tcg/tlb_helper.c | 63 ++++++-------------------------
3 files changed, 84 insertions(+), 51 deletions(-)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index 4c5cbd7425..62b3acfbc7 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -19,7 +19,17 @@ enum {
TLBRET_PE = 7,
};
+typedef struct mmu_context {
+ target_ulong vaddr;
+ uint64_t pte;
+ hwaddr physical;
+ int ps; /* page size shift */
+ int prot;
+} mmu_context;
+
bool check_ps(CPULoongArchState *ent, uint8_t ps);
+int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
+ int access_type, int mmu_idx);
int get_physical_address(CPULoongArchState *env, hwaddr *physical,
int *prot, target_ulong address,
MMUAccessType access_type, int mmu_idx, int is_debug);
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 2e8d3d7cfb..1b3dfaf15d 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -44,6 +44,68 @@ void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
}
}
+int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
+ int access_type, int mmu_idx)
+{
+ uint64_t plv = mmu_idx;
+ uint64_t tlb_entry, tlb_ppn;
+ uint8_t tlb_ps, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
+
+ tlb_entry = context->pte;
+ tlb_ps = context->ps;
+ tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
+ tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
+ tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
+ if (is_la64(env)) {
+ tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
+ tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
+ tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
+ tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
+ } else {
+ tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
+ tlb_nx = 0;
+ tlb_nr = 0;
+ tlb_rplv = 0;
+ }
+
+ /* Check access rights */
+ if (!tlb_v) {
+ return TLBRET_INVALID;
+ }
+
+ if (access_type == MMU_INST_FETCH && tlb_nx) {
+ return TLBRET_XI;
+ }
+
+ if (access_type == MMU_DATA_LOAD && tlb_nr) {
+ return TLBRET_RI;
+ }
+
+ if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
+ ((tlb_rplv == 1) && (plv != tlb_plv))) {
+ return TLBRET_PE;
+ }
+
+ if ((access_type == MMU_DATA_STORE) && !tlb_d) {
+ return TLBRET_DIRTY;
+ }
+
+ /* Remove sw bit between bit12 -- bit PS*/
+ tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) - 1));
+ context->physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
+ (context->vaddr & MAKE_64BIT_MASK(0, tlb_ps));
+ context->prot = PAGE_READ;
+ if (tlb_d) {
+ context->prot |= PAGE_WRITE;
+ }
+
+ if (!tlb_nx) {
+ context->prot |= PAGE_EXEC;
+ }
+
+ return TLBRET_MATCH;
+}
+
static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
int *prot, target_ulong address)
{
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 1f49619e7f..dd99a063cc 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -653,64 +653,25 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
int access_type, int index, int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
- uint64_t plv = mmu_idx;
- uint64_t tlb_entry, tlb_ppn;
- uint8_t tlb_ps, n, tlb_v, tlb_d, tlb_plv, tlb_nx, tlb_nr, tlb_rplv;
+ uint64_t tlb_entry;
+ uint8_t tlb_ps, n;
+ mmu_context context;
+ int ret;
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
n = (address >> tlb_ps) & 0x1;/* Odd or even */
tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
- tlb_v = FIELD_EX64(tlb_entry, TLBENTRY, V);
- tlb_d = FIELD_EX64(tlb_entry, TLBENTRY, D);
- tlb_plv = FIELD_EX64(tlb_entry, TLBENTRY, PLV);
- if (is_la64(env)) {
- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_64, PPN);
- tlb_nx = FIELD_EX64(tlb_entry, TLBENTRY_64, NX);
- tlb_nr = FIELD_EX64(tlb_entry, TLBENTRY_64, NR);
- tlb_rplv = FIELD_EX64(tlb_entry, TLBENTRY_64, RPLV);
- } else {
- tlb_ppn = FIELD_EX64(tlb_entry, TLBENTRY_32, PPN);
- tlb_nx = 0;
- tlb_nr = 0;
- tlb_rplv = 0;
- }
-
- /* Remove sw bit between bit12 -- bit PS*/
- tlb_ppn = tlb_ppn & ~(((0x1UL << (tlb_ps - 12)) - 1));
-
- /* Check access rights */
- if (!tlb_v) {
- return TLBRET_INVALID;
- }
-
- if (access_type == MMU_INST_FETCH && tlb_nx) {
- return TLBRET_XI;
- }
-
- if (access_type == MMU_DATA_LOAD && tlb_nr) {
- return TLBRET_RI;
- }
-
- if (((tlb_rplv == 0) && (plv > tlb_plv)) ||
- ((tlb_rplv == 1) && (plv != tlb_plv))) {
- return TLBRET_PE;
- }
-
- if ((access_type == MMU_DATA_STORE) && !tlb_d) {
- return TLBRET_DIRTY;
+ context.vaddr = address;
+ context.ps = tlb_ps;
+ context.pte = tlb_entry;
+ ret = loongarch_check_pte(env, &context, access_type, mmu_idx);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
}
- *physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
- (address & MAKE_64BIT_MASK(0, tlb_ps));
- *prot = PAGE_READ;
- if (tlb_d) {
- *prot |= PAGE_WRITE;
- }
- if (!tlb_nx) {
- *prot |= PAGE_EXEC;
- }
- return TLBRET_MATCH;
+ return ret;
}
int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 06/17] target/loongarch: Use loongarch_check_pte() with page table walking
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (4 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-26 1:20 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker Bibo Mao
` (10 subsequent siblings)
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
Function loongarch_check_pte() can get physical address and access
priviledge, it works on both TLB entry and pte entry. It can be used
at page table walking.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu_helper.c | 38 +++++++++++++----------------------
1 file changed, 14 insertions(+), 24 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 1b3dfaf15d..9e6de2908f 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -107,13 +107,15 @@ int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
}
static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address)
+ int *prot, target_ulong address,
+ int access_type, int mmu_idx)
{
CPUState *cs = env_cpu(env);
target_ulong index, phys;
uint64_t dir_base, dir_width;
uint64_t base;
- int level;
+ int level, ret;
+ mmu_context context;
if ((address >> 63) & 0x1) {
base = env->CSR_PGDH;
@@ -156,29 +158,16 @@ static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
base = ldq_phys(cs->as, phys);
}
- /* TODO: check plv and other bits? */
-
- /* base is pte, in normal pte format */
- if (!FIELD_EX64(base, TLBENTRY, V)) {
- return TLBRET_NOMATCH;
+ context.vaddr = address;
+ context.ps = dir_base;
+ context.pte = base;
+ ret = loongarch_check_pte(env, &context, access_type, mmu_idx);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
}
- if (!FIELD_EX64(base, TLBENTRY, D)) {
- *prot = PAGE_READ;
- } else {
- *prot = PAGE_READ | PAGE_WRITE;
- }
-
- /* get TARGET_PAGE_SIZE aligned physical address */
- base += (address & TARGET_PHYS_MASK) & ((1 << dir_base) - 1);
- /* mask RPLV, NX, NR bits */
- base = FIELD_DP64(base, TLBENTRY_64, RPLV, 0);
- base = FIELD_DP64(base, TLBENTRY_64, NX, 0);
- base = FIELD_DP64(base, TLBENTRY_64, NR, 0);
- /* mask other attribute bits */
- *physical = base & TARGET_PAGE_MASK;
-
- return 0;
+ return ret;
}
static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
@@ -202,7 +191,8 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
* legal mapping, even if the mapping is not yet in TLB. return 0 if
* there is a valid map, else none zero.
*/
- return loongarch_page_table_walker(env, physical, prot, address);
+ return loongarch_page_table_walker(env, physical, prot, address,
+ access_type, mmu_idx);
}
return TLBRET_NOMATCH;
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (5 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 06/17] target/loongarch: Use loongarch_check_pte() with page table walking Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-26 1:31 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 08/17] target/loongarch: Add parameter mmu_context with loongarch_map_tlb_entry Bibo Mao
` (9 subsequent siblings)
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function loongarch_page_table_walker(), some output parameters
such as physical address and prot can be moved to structure mmu_context.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu_helper.c | 27 +++++++++++----------------
1 file changed, 11 insertions(+), 16 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 9e6de2908f..a26bb8b11b 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -106,17 +106,18 @@ int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
return TLBRET_MATCH;
}
-static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+static int loongarch_page_table_walker(CPULoongArchState *env,
+ mmu_context *context,
int access_type, int mmu_idx)
{
CPUState *cs = env_cpu(env);
target_ulong index, phys;
uint64_t dir_base, dir_width;
uint64_t base;
- int level, ret;
- mmu_context context;
+ int level;
+ target_ulong address;
+ address = context->vaddr;
if ((address >> 63) & 0x1) {
base = env->CSR_PGDH;
} else {
@@ -158,16 +159,9 @@ static int loongarch_page_table_walker(CPULoongArchState *env, hwaddr *physical,
base = ldq_phys(cs->as, phys);
}
- context.vaddr = address;
- context.ps = dir_base;
- context.pte = base;
- ret = loongarch_check_pte(env, &context, access_type, mmu_idx);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
-
- return ret;
+ context->ps = dir_base;
+ context->pte = base;
+ return loongarch_check_pte(env, context, access_type, mmu_idx);
}
static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
@@ -176,7 +170,9 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
int is_debug)
{
int ret;
+ mmu_context context;
+ context.vaddr = address;
if (tcg_enabled()) {
ret = loongarch_get_addr_from_tlb(env, physical, prot, address,
access_type, mmu_idx);
@@ -191,8 +187,7 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
* legal mapping, even if the mapping is not yet in TLB. return 0 if
* there is a valid map, else none zero.
*/
- return loongarch_page_table_walker(env, physical, prot, address,
- access_type, mmu_idx);
+ return loongarch_page_table_walker(env, &context, access_type, mmu_idx);
}
return TLBRET_NOMATCH;
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 08/17] target/loongarch: Add parameter mmu_context with loongarch_map_tlb_entry
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (6 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 09/17] target/loongarch: Add parameter mmu_context with loongarch_get_addr_from_tlb Bibo Mao
` (8 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function loongarch_map_tlb_entry(), parameter mmu_context is added
and remove parameter physical and prot.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index dd99a063cc..460e7c00c5 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -648,30 +648,22 @@ void helper_ldpte(CPULoongArchState *env, target_ulong base, target_ulong odd,
env->CSR_TLBREHI = FIELD_DP64(env->CSR_TLBREHI, CSR_TLBREHI, PS, ps);
}
-static int loongarch_map_tlb_entry(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+static int loongarch_map_tlb_entry(CPULoongArchState *env, mmu_context *context,
int access_type, int index, int mmu_idx)
{
LoongArchTLB *tlb = &env->tlb[index];
uint64_t tlb_entry;
uint8_t tlb_ps, n;
- mmu_context context;
- int ret;
+ target_ulong address;
+ address = context->vaddr;
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
n = (address >> tlb_ps) & 0x1;/* Odd or even */
tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
- context.vaddr = address;
- context.ps = tlb_ps;
- context.pte = tlb_entry;
- ret = loongarch_check_pte(env, &context, access_type, mmu_idx);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
-
- return ret;
+ context->ps = tlb_ps;
+ context->pte = tlb_entry;
+ return loongarch_check_pte(env, context, access_type, mmu_idx);
}
int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
@@ -679,11 +671,18 @@ int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
MMUAccessType access_type, int mmu_idx)
{
int index, match;
+ mmu_context context;
+ context.vaddr = address;
match = loongarch_tlb_search(env, address, &index);
if (match) {
- return loongarch_map_tlb_entry(env, physical, prot,
- address, access_type, index, mmu_idx);
+ match = loongarch_map_tlb_entry(env, &context,
+ access_type, index, mmu_idx);
+ if (match == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
+ return match;
}
return TLBRET_NOMATCH;
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 09/17] target/loongarch: Add parameter mmu_context with loongarch_get_addr_from_tlb
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (7 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 08/17] target/loongarch: Add parameter mmu_context with loongarch_map_tlb_entry Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 10/17] target/loongarch: Add parameter mmu_context with loongarch_map_address Bibo Mao
` (7 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function loongarch_get_addr_from_tlb(), parameter mmu_context
is added and remove parameter physical and prot.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu_helper.c | 7 +++++--
target/loongarch/tcg/tcg_loongarch.h | 4 ++--
target/loongarch/tcg/tlb_helper.c | 16 ++++------------
3 files changed, 11 insertions(+), 16 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index a26bb8b11b..1e97687e1f 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -174,9 +174,12 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
context.vaddr = address;
if (tcg_enabled()) {
- ret = loongarch_get_addr_from_tlb(env, physical, prot, address,
- access_type, mmu_idx);
+ ret = loongarch_get_addr_from_tlb(env, &context, access_type, mmu_idx);
if (ret != TLBRET_NOMATCH) {
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
return ret;
}
}
diff --git a/target/loongarch/tcg/tcg_loongarch.h b/target/loongarch/tcg/tcg_loongarch.h
index fd4e116022..a27d77c5ba 100644
--- a/target/loongarch/tcg/tcg_loongarch.h
+++ b/target/loongarch/tcg/tcg_loongarch.h
@@ -7,6 +7,7 @@
#ifndef TARGET_LOONGARCH_TCG_LOONGARCH_H
#define TARGET_LOONGARCH_TCG_LOONGARCH_H
#include "cpu.h"
+#include "cpu-mmu.h"
void loongarch_csr_translate_init(void);
@@ -14,8 +15,7 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
-int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+int loongarch_get_addr_from_tlb(CPULoongArchState *env, mmu_context *context,
MMUAccessType access_type, int mmu_idx);
#endif /* TARGET_LOONGARCH_TCG_LOONGARCH_H */
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 460e7c00c5..a875ac251e 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -666,23 +666,15 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, mmu_context *context,
return loongarch_check_pte(env, context, access_type, mmu_idx);
}
-int loongarch_get_addr_from_tlb(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+int loongarch_get_addr_from_tlb(CPULoongArchState *env, mmu_context *context,
MMUAccessType access_type, int mmu_idx)
{
int index, match;
- mmu_context context;
- context.vaddr = address;
- match = loongarch_tlb_search(env, address, &index);
+ match = loongarch_tlb_search(env, context->vaddr, &index);
if (match) {
- match = loongarch_map_tlb_entry(env, &context,
- access_type, index, mmu_idx);
- if (match == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
- return match;
+ return loongarch_map_tlb_entry(env, context,
+ access_type, index, mmu_idx);
}
return TLBRET_NOMATCH;
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 10/17] target/loongarch: Add parameter mmu_context with loongarch_map_address
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (8 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 09/17] target/loongarch: Add parameter mmu_context with loongarch_get_addr_from_tlb Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 11/17] target/loongarch: Add parameter mmu_context with get_physical_address Bibo Mao
` (6 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function loongarch_map_address(), parameter mmu_context is added
and remove parameter address, prot and address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu_helper.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 1e97687e1f..6abd7aa152 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -164,22 +164,15 @@ static int loongarch_page_table_walker(CPULoongArchState *env,
return loongarch_check_pte(env, context, access_type, mmu_idx);
}
-static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+static int loongarch_map_address(CPULoongArchState *env, mmu_context *context,
MMUAccessType access_type, int mmu_idx,
int is_debug)
{
int ret;
- mmu_context context;
- context.vaddr = address;
if (tcg_enabled()) {
- ret = loongarch_get_addr_from_tlb(env, &context, access_type, mmu_idx);
+ ret = loongarch_get_addr_from_tlb(env, context, access_type, mmu_idx);
if (ret != TLBRET_NOMATCH) {
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
return ret;
}
}
@@ -190,7 +183,7 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
* legal mapping, even if the mapping is not yet in TLB. return 0 if
* there is a valid map, else none zero.
*/
- return loongarch_page_table_walker(env, &context, access_type, mmu_idx);
+ return loongarch_page_table_walker(env, context, access_type, mmu_idx);
}
return TLBRET_NOMATCH;
@@ -218,8 +211,11 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical,
int64_t addr_high;
uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
+ mmu_context context;
+ int ret;
/* Check PG and DA */
+ context.vaddr = address;
if (da & !pg) {
*physical = address & TARGET_PHYS_MASK;
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -253,8 +249,12 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical,
}
/* Mapped address */
- return loongarch_map_address(env, physical, prot, address,
- access_type, mmu_idx, is_debug);
+ ret = loongarch_map_address(env, &context, access_type, mmu_idx, is_debug);
+ if (ret == TLBRET_MATCH) {
+ *physical = context.physical;
+ *prot = context.prot;
+ }
+ return ret;
}
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 11/17] target/loongarch: Add parameter mmu_context with get_physical_address
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (9 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 10/17] target/loongarch: Add parameter mmu_context with loongarch_map_address Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 12/17] target/loongarch: Track user mode address accessed in kernel mode Bibo Mao
` (5 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function get_physical_address(), parameter mmu_context is added
and remove parameter address, prot and address.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu-mmu.h | 3 +--
target/loongarch/cpu_helper.c | 31 ++++++++++++-------------------
target/loongarch/tcg/tlb_helper.c | 8 +++++---
3 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index 62b3acfbc7..9d909d36ec 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -30,8 +30,7 @@ typedef struct mmu_context {
bool check_ps(CPULoongArchState *ent, uint8_t ps);
int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
int access_type, int mmu_idx);
-int get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+int get_physical_address(CPULoongArchState *env, mmu_context *context,
MMUAccessType access_type, int mmu_idx, int is_debug);
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
uint64_t *dir_width, target_ulong level);
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 6abd7aa152..9f64cb40cf 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -201,8 +201,7 @@ static hwaddr dmw_va2pa(CPULoongArchState *env, target_ulong va,
}
}
-int get_physical_address(CPULoongArchState *env, hwaddr *physical,
- int *prot, target_ulong address,
+int get_physical_address(CPULoongArchState *env, mmu_context *context,
MMUAccessType access_type, int mmu_idx, int is_debug)
{
int user_mode = mmu_idx == MMU_USER_IDX;
@@ -211,14 +210,13 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical,
int64_t addr_high;
uint8_t da = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, DA);
uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
- mmu_context context;
- int ret;
+ target_ulong address;
/* Check PG and DA */
- context.vaddr = address;
+ address = context->vaddr;
if (da & !pg) {
- *physical = address & TARGET_PHYS_MASK;
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ context->physical = address & TARGET_PHYS_MASK;
+ context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TLBRET_MATCH;
}
@@ -236,8 +234,8 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical,
base_c = FIELD_EX64(env->CSR_DMW[i], CSR_DMW_32, VSEG);
}
if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
- *physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
- *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ context->physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
+ context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
return TLBRET_MATCH;
}
}
@@ -249,23 +247,18 @@ int get_physical_address(CPULoongArchState *env, hwaddr *physical,
}
/* Mapped address */
- ret = loongarch_map_address(env, &context, access_type, mmu_idx, is_debug);
- if (ret == TLBRET_MATCH) {
- *physical = context.physical;
- *prot = context.prot;
- }
- return ret;
+ return loongarch_map_address(env, context, access_type, mmu_idx, is_debug);
}
hwaddr loongarch_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
{
CPULoongArchState *env = cpu_env(cs);
- hwaddr phys_addr;
- int prot;
+ mmu_context context;
- if (get_physical_address(env, &phys_addr, &prot, addr, MMU_DATA_LOAD,
+ context.vaddr = addr;
+ if (get_physical_address(env, &context, MMU_DATA_LOAD,
cpu_mmu_index(cs, false), 1) != 0) {
return -1;
}
- return phys_addr;
+ return context.physical;
}
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index a875ac251e..d1d19c5e70 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -515,15 +515,17 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
bool probe, uintptr_t retaddr)
{
CPULoongArchState *env = cpu_env(cs);
+ mmu_context context;
hwaddr physical;
int prot;
int ret;
/* Data access */
- ret = get_physical_address(env, &physical, &prot, address,
- access_type, mmu_idx, 0);
-
+ context.vaddr = address;
+ ret = get_physical_address(env, &context, access_type, mmu_idx, 0);
if (ret == TLBRET_MATCH) {
+ physical = context.physical;
+ prot = context.prot;
tlb_set_page(cs, address & TARGET_PAGE_MASK,
physical & TARGET_PAGE_MASK, prot,
mmu_idx, TARGET_PAGE_SIZE);
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 12/17] target/loongarch: Track user mode address accessed in kernel mode
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (10 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 11/17] target/loongarch: Add parameter mmu_context with get_physical_address Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb Bibo Mao
` (4 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
The concept of mmu idx between QEMU TLB and LoongArch TLB emulation
is different:
mmu idx in QEMU TLB comes from currently working mode of vCPU
mmu idx from LoongArch TLB is page priviledge level
With copy_from_user() executed in system, vCPU is in kernel mode
however PLV of PTE is user mode.
Here field KM is added in TLB MISC to track whether the lo0/lo1 pte
entry is accessed in kernel mode. If set, when LoongArch TLB is
flushed, need flush QEMU TLB with mmu idx MMU_KERNEL_IDX.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/cpu-mmu.h | 2 ++
target/loongarch/cpu.h | 11 +++++++++++
target/loongarch/cpu_helper.c | 3 +++
target/loongarch/tcg/tlb_helper.c | 26 ++++++++++++++++++++++++++
4 files changed, 42 insertions(+)
diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
index 9d909d36ec..3de707dd56 100644
--- a/target/loongarch/cpu-mmu.h
+++ b/target/loongarch/cpu-mmu.h
@@ -25,6 +25,8 @@ typedef struct mmu_context {
hwaddr physical;
int ps; /* page size shift */
int prot;
+ int tlb_index;
+ int mmu_index;
} mmu_context;
bool check_ps(CPULoongArchState *ent, uint8_t ps);
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 7731f6acdc..2ae5f655a6 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -253,6 +253,17 @@ FIELD(TLB_MISC, E, 0, 1)
FIELD(TLB_MISC, ASID, 1, 10)
FIELD(TLB_MISC, VPPN, 13, 35)
FIELD(TLB_MISC, PS, 48, 6)
+/*
+ * Used by QEMU software, concept of mmu idx between QEMU TLB and LoongArch
+ * TLB emulation is different:
+ * mmu idx in QEMU TLB is current working mode of vCPU
+ * mmu idx in LoongArch TLB is PLV access level
+ * When funtion copy_from_user() executed with system emulation method,
+ * vCPU is in kernel mode however accessed address is user memory space.
+ *
+ * TLB lo0/lo1 entry mask with PLV MMU_USER_IDX accessed in kernel mode
+ */
+FIELD(TLB_MISC, KM, 54, 2)
#define LSX_LEN (128)
#define LASX_LEN (256)
diff --git a/target/loongarch/cpu_helper.c b/target/loongarch/cpu_helper.c
index 9f64cb40cf..afdf05649b 100644
--- a/target/loongarch/cpu_helper.c
+++ b/target/loongarch/cpu_helper.c
@@ -95,6 +95,7 @@ int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
context->physical = (tlb_ppn << R_TLBENTRY_64_PPN_SHIFT) |
(context->vaddr & MAKE_64BIT_MASK(0, tlb_ps));
context->prot = PAGE_READ;
+ context->mmu_index = tlb_plv;
if (tlb_d) {
context->prot |= PAGE_WRITE;
}
@@ -217,6 +218,7 @@ int get_physical_address(CPULoongArchState *env, mmu_context *context,
if (da & !pg) {
context->physical = address & TARGET_PHYS_MASK;
context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ context->mmu_index = MMU_DA_IDX;
return TLBRET_MATCH;
}
@@ -236,6 +238,7 @@ int get_physical_address(CPULoongArchState *env, mmu_context *context,
if ((plv & env->CSR_DMW[i]) && (base_c == base_v)) {
context->physical = dmw_va2pa(env, address, env->CSR_DMW[i]);
context->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+ context->mmu_index = MMU_DA_IDX;
return TLBRET_MATCH;
}
}
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index d1d19c5e70..715c5a20da 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -172,6 +172,7 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
}
/* Store page size in field PS */
+ tlb->tlb_misc = 0;
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, csr_ps);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, VPPN, csr_vppn);
tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, E, 1);
@@ -510,6 +511,24 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
tlb_flush(env_cpu(env));
}
+/*
+ * Record tlb entry with virtual address from user mode accessed from
+ * vCPU kernel mode.
+ *
+ * If set, when LoongArch TLB is flushed, need flush QEMU TLB with mmu
+ * idx MMU_KERNEL_IDX
+ */
+static inline void tlb_set_accessed(CPULoongArchState *env, vaddr address,
+ int index)
+{
+ LoongArchTLB *tlb = &env->tlb[index];
+ uint8_t tlb_ps, n;
+
+ tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
+ n = (address >> tlb_ps) & 0x1;/* Odd or even */
+ tlb->tlb_misc |= BIT_ULL(R_TLB_MISC_KM_SHIFT + n);
+}
+
bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr)
@@ -529,6 +548,12 @@ bool loongarch_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
tlb_set_page(cs, address & TARGET_PAGE_MASK,
physical & TARGET_PAGE_MASK, prot,
mmu_idx, TARGET_PAGE_SIZE);
+
+ /* user mode address space is accessed in vCPU kernel mode */
+ if (mmu_idx == MMU_KERNEL_IDX && context.mmu_index == MMU_USER_IDX) {
+ tlb_set_accessed(env, address, context.tlb_index);
+ }
+
qemu_log_mask(CPU_LOG_MMU,
"%s address=%" VADDR_PRIx " physical " HWADDR_FMT_plx
" prot %d\n", __func__, address, physical, prot);
@@ -665,6 +690,7 @@ static int loongarch_map_tlb_entry(CPULoongArchState *env, mmu_context *context,
tlb_entry = n ? tlb->tlb_entry1 : tlb->tlb_entry0;
context->ps = tlb_ps;
context->pte = tlb_entry;
+ context->tlb_index = index;
return loongarch_check_pte(env, context, access_type, mmu_idx);
}
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (11 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 12/17] target/loongarch: Track user mode address accessed in kernel mode Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-26 1:45 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 14/17] target/loongarch: Use mmu idx bitmap method " Bibo Mao
` (3 subsequent siblings)
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With tlb_flush_range_by_mmuidx(), the virtual address is 64 bit.
However on LoongArch TLB emulation system, virtual address is
48 bit. It is necessary to convert 48 bit address to 64 bit when
flush tlb, also fix address calculation issue with odd page.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 715c5a20da..61cc19610e 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -96,6 +96,15 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
}
}
+/* Convert 48 bit virtual address from LoongArch TLB to 64 bit VA */
+static inline target_ulong __vaddr(target_ulong addr)
+{
+ target_ulong high;
+
+ high = -(addr >> (TARGET_VIRT_ADDR_SPACE_BITS - 1));
+ return addr + (high << TARGET_VIRT_ADDR_SPACE_BITS);
+}
+
static void invalidate_tlb_entry(CPULoongArchState *env, int index)
{
target_ulong addr, mask, pagesize;
@@ -115,16 +124,15 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
+ addr = __vaddr((tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask);
if (tlb_v0) {
- addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask; /* even */
tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
if (tlb_v1) {
- addr = (tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & pagesize; /* odd */
- tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
+ tlb_flush_range_by_mmuidx(env_cpu(env), addr + pagesize, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
}
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 14/17] target/loongarch: Use mmu idx bitmap method when flush tlb
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (12 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb Bibo Mao
@ 2025-07-25 1:37 ` Bibo Mao
2025-07-25 1:47 ` [PATCH v3 15/17] target/loongarch: Add parameter tlb pointer with fill_tlb_entry Bibo Mao
` (2 subsequent siblings)
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:37 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With API tlb_flush_range_by_mmuidx(), bitmap method of mmu idx should
be used rather than itself. And mmu idx comes from page table entry
information rather current running mode.
Also field KM in TLB misc records bitmap mask of TLB entry which
is access in kernel mode. If set, MMU_KERNEL_IDX should be added
to flush tlb.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 61cc19610e..d18b382e56 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -110,12 +110,12 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
target_ulong addr, mask, pagesize;
uint8_t tlb_ps;
LoongArchTLB *tlb = &env->tlb[index];
-
- int mmu_idx = cpu_mmu_index(env_cpu(env), false);
+ int mmu_idx;
uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
+ uint16_t tlb_g, tlb_km;
if (!tlb_e) {
return;
@@ -125,13 +125,28 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
pagesize = MAKE_64BIT_MASK(tlb_ps, 1);
mask = MAKE_64BIT_MASK(0, tlb_ps + 1);
addr = __vaddr((tlb_vppn << R_TLB_MISC_VPPN_SHIFT) & ~mask);
+ tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
+ tlb_km = FIELD_EX64(tlb->tlb_misc, TLB_MISC, KM);
+ if (tlb_g) {
+ mmu_idx = BIT(MMU_KERNEL_IDX);
+ } else {
+ mmu_idx = BIT(MMU_USER_IDX);
+ }
if (tlb_v0) {
+ /* Even page is accessed in kernel mode */
+ if (tlb_km & 0x1) {
+ mmu_idx |= BIT(MMU_KERNEL_IDX);
+ }
tlb_flush_range_by_mmuidx(env_cpu(env), addr, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
if (tlb_v1) {
+ /* Odd page is accessed in kernel mode */
+ if (tlb_km & 0x2) {
+ mmu_idx |= BIT(MMU_KERNEL_IDX);
+ }
tlb_flush_range_by_mmuidx(env_cpu(env), addr + pagesize, pagesize,
mmu_idx, TARGET_LONG_BITS);
}
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 15/17] target/loongarch: Add parameter tlb pointer with fill_tlb_entry
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (13 preceding siblings ...)
2025-07-25 1:37 ` [PATCH v3 14/17] target/loongarch: Use mmu idx bitmap method " Bibo Mao
@ 2025-07-25 1:47 ` Bibo Mao
2025-07-26 1:47 ` Richard Henderson
2025-07-25 1:47 ` [PATCH v3 16/17] target/loongarch: Reduce TLB flush with helper_tlbwr Bibo Mao
2025-07-25 1:48 ` [PATCH v3 17/17] target/loongarch: Update TLB index selection method Bibo Mao
16 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:47 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function fill_tlb_entry(), it will update LoongArch emulated
TLB information. Here parameter tlb pointer is added so that TLB
entry will be updated based on relative TLB CSR registers.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index d18b382e56..1ed2471e0a 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -167,9 +167,8 @@ static void invalidate_tlb(CPULoongArchState *env, int index)
invalidate_tlb_entry(env, index);
}
-static void fill_tlb_entry(CPULoongArchState *env, int index)
+static void fill_tlb_entry(CPULoongArchState *env, LoongArchTLB *tlb)
{
- LoongArchTLB *tlb = &env->tlb[index];
uint64_t lo0, lo1, csr_vppn;
uint16_t csr_asid;
uint8_t csr_ps;
@@ -337,7 +336,7 @@ void helper_tlbwr(CPULoongArchState *env)
return;
}
- fill_tlb_entry(env, index);
+ fill_tlb_entry(env, env->tlb + index);
}
void helper_tlbfill(CPULoongArchState *env)
@@ -375,7 +374,7 @@ void helper_tlbfill(CPULoongArchState *env)
}
invalidate_tlb(env, index);
- fill_tlb_entry(env, index);
+ fill_tlb_entry(env, env->tlb + index);
}
void helper_tlbclr(CPULoongArchState *env)
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 16/17] target/loongarch: Reduce TLB flush with helper_tlbwr
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (14 preceding siblings ...)
2025-07-25 1:47 ` [PATCH v3 15/17] target/loongarch: Add parameter tlb pointer with fill_tlb_entry Bibo Mao
@ 2025-07-25 1:47 ` Bibo Mao
2025-07-25 1:48 ` [PATCH v3 17/17] target/loongarch: Update TLB index selection method Bibo Mao
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:47 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function helper_tlbwr(), specified LoongArch TLB entry will be
updated. There are two PTE pages in one TLB entry, it is not
necessary to flush QEMU TLB when one PTE page keeps unchanged and
ther other PTE page is newly added.
Here check whether PTE page is the same or not, TLB flush can be
skipped if both are the same or newly added.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 36 ++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 1ed2471e0a..6ac102862b 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -327,16 +327,42 @@ void helper_tlbrd(CPULoongArchState *env)
void helper_tlbwr(CPULoongArchState *env)
{
int index = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, INDEX);
+ LoongArchTLB *old, new;
+ int skip_inv = 0;
+ uint8_t tlb_v;
- invalidate_tlb(env, index);
-
+ old = env->tlb + index;
if (FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, NE)) {
- env->tlb[index].tlb_misc = FIELD_DP64(env->tlb[index].tlb_misc,
- TLB_MISC, E, 0);
+ invalidate_tlb(env, index);
+ old->tlb_misc = FIELD_DP64(old->tlb_misc, TLB_MISC, E, 0);
return;
}
- fill_tlb_entry(env, env->tlb + index);
+ new.tlb_misc = 0;
+ new.tlb_entry0 = 0;
+ new.tlb_entry1 = 0;
+ fill_tlb_entry(env, &new);
+ /* Check whether ASID/VPPN is the same */
+ if (old->tlb_misc == new.tlb_misc) {
+ tlb_v = FIELD_EX64(old->tlb_entry0, TLBENTRY, V);
+ /* Check whether even pte the same or invalid */
+ if (!tlb_v || new.tlb_entry0 == old->tlb_entry0) {
+ skip_inv = 1;
+ }
+
+ /* Check whether odd pte the same or invalid */
+ tlb_v = FIELD_EX64(old->tlb_entry1, TLBENTRY, V);
+ if (!tlb_v || new.tlb_entry1 == old->tlb_entry1) {
+ skip_inv &= 1;
+ }
+ }
+
+ if (!skip_inv) {
+ invalidate_tlb(env, index);
+ }
+ old->tlb_misc = new.tlb_misc;
+ old->tlb_entry0 = new.tlb_entry0;
+ old->tlb_entry1 = new.tlb_entry1;
}
void helper_tlbfill(CPULoongArchState *env)
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [PATCH v3 17/17] target/loongarch: Update TLB index selection method
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
` (15 preceding siblings ...)
2025-07-25 1:47 ` [PATCH v3 16/17] target/loongarch: Reduce TLB flush with helper_tlbwr Bibo Mao
@ 2025-07-25 1:48 ` Bibo Mao
16 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-25 1:48 UTC (permalink / raw)
To: Song Gao; +Cc: Jiaxun Yang, qemu-devel
With function helper_tlbfill(), since there is no suitable TLB entry,
new TLB will be added and invalid one old TLB entry. The old TLB
entry index is selected randomly.
Firstly all TLB entries can be searched with such method:
1. invalid TLB entry can be selected at firstly.
2. TLB entry with other ASID can be selected secondly
3. random method is used by last.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
target/loongarch/tcg/tlb_helper.c | 50 ++++++++++++++++++++++++++-----
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index 6ac102862b..99b04550b5 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -368,8 +368,11 @@ void helper_tlbwr(CPULoongArchState *env)
void helper_tlbfill(CPULoongArchState *env)
{
uint64_t address, entryhi;
- int index, set, stlb_idx;
+ int index, i, stlb_idx;
uint16_t pagesize, stlb_ps;
+ uint16_t asid, tlb_asid;
+ LoongArchTLB *tlb;
+ uint8_t tlb_e;
if (FIELD_EX64(env->CSR_TLBRERA, CSR_TLBRERA, ISTLBR)) {
entryhi = env->CSR_TLBREHI;
@@ -383,20 +386,51 @@ void helper_tlbfill(CPULoongArchState *env)
/* Validity of stlb_ps is checked in helper_csrwr_stlbps() */
stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
+ asid = FIELD_EX64(env->CSR_ASID, CSR_ASID, ASID);
+ index = -1;
if (pagesize == stlb_ps) {
/* Only write into STLB bits [47:13] */
address = entryhi & ~MAKE_64BIT_MASK(0, R_CSR_TLBEHI_64_VPPN_SHIFT);
-
- /* Choose one set ramdomly */
- set = get_random_tlb(0, 7);
-
- /* Index in one set */
stlb_idx = (address >> (stlb_ps + 1)) & 0xff; /* [0,255] */
+ for (i = 0; i < 8; ++i) {
+ tlb = &env->tlb[i * 256 + stlb_idx];
+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
+ if (!tlb_e) {
+ index = i;
+ break;
+ }
+
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ if (asid != tlb_asid) {
+ index = i;
+ }
+ }
- index = set * 256 + stlb_idx;
+ /* Choose one set randomly */
+ if (index < 0) {
+ index = get_random_tlb(0, 7);
+ }
+ index = index * 256 + stlb_idx;
} else {
/* Only write into MTLB */
- index = get_random_tlb(LOONGARCH_STLB, LOONGARCH_TLB_MAX - 1);
+ for (i = LOONGARCH_STLB; i < LOONGARCH_TLB_MAX; i++) {
+ tlb = &env->tlb[i];
+ tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
+
+ if (!tlb_e) {
+ index = i;
+ break;
+ }
+
+ tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
+ if (asid != tlb_asid) {
+ index = i;
+ }
+ }
+
+ if (index < 0) {
+ index = get_random_tlb(LOONGARCH_STLB, LOONGARCH_TLB_MAX - 1);
+ }
}
invalidate_tlb(env, index);
--
2.39.3
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory
2025-07-25 1:37 ` [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory Bibo Mao
@ 2025-07-25 23:37 ` Richard Henderson
0 siblings, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2025-07-25 23:37 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> Move function definition specified with kvm to the corresponding
> directory. Also remove header file "cpu.h" including outside of
> macro QEMU_KVM_LOONGARCH_H.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> hw/loongarch/virt.c | 1 +
> target/loongarch/cpu.h | 9 ---------
> target/loongarch/kvm/kvm_loongarch.h | 4 ++--
> 3 files changed, 3 insertions(+), 11 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 02/17] target/loongarch: Define function loongarch_cpu_post_init as static
2025-07-25 1:37 ` [PATCH v3 02/17] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
@ 2025-07-25 23:38 ` Richard Henderson
0 siblings, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2025-07-25 23:38 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> Function loongarch_cpu_post_init() is implemented and used in the
> same file target/loongarch/cpu.c, it can be defined as static function.
>
> This patch moves implementation about function loongarch_cpu_post_init()
> before it is referenced. And it is only code movement, no function
> change.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> target/loongarch/cpu.c | 180 ++++++++++++++++++++---------------------
> target/loongarch/cpu.h | 2 -
> 2 files changed, 90 insertions(+), 92 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h
2025-07-25 1:37 ` [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h Bibo Mao
@ 2025-07-26 1:10 ` Richard Henderson
2025-07-26 1:16 ` Richard Henderson
1 sibling, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:10 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> New header file cpu-mmu.h is added and move mmu relative function
> declaration to this file.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> target/loongarch/cpu-mmu.h | 30 ++++++++++++++++++++++++++++++
> target/loongarch/cpu.c | 1 +
> target/loongarch/cpu_helper.c | 1 +
> target/loongarch/internals.h | 20 --------------------
> target/loongarch/tcg/csr_helper.c | 1 +
> target/loongarch/tcg/tlb_helper.c | 1 +
> 6 files changed, 34 insertions(+), 20 deletions(-)
> create mode 100644 target/loongarch/cpu-mmu.h
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h
2025-07-25 1:37 ` [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h Bibo Mao
2025-07-26 1:10 ` Richard Henderson
@ 2025-07-26 1:16 ` Richard Henderson
2025-07-28 3:08 ` Bibo Mao
1 sibling, 1 reply; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:16 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> +enum {
> + TLBRET_MATCH = 0,
> + TLBRET_BADADDR = 1,
> + TLBRET_NOMATCH = 2,
> + TLBRET_INVALID = 3,
> + TLBRET_DIRTY = 4,
> + TLBRET_RI = 5,
> + TLBRET_XI = 6,
> + TLBRET_PE = 7,
> +};
For a follow-up patch, name this enumeration and use it instead of 'int'.
It would make it self-documenting what a function is computing.
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte()
2025-07-25 1:37 ` [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
@ 2025-07-26 1:19 ` Richard Henderson
2025-07-28 3:15 ` Bibo Mao
0 siblings, 1 reply; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:19 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> Common function loongarch_check_pte() is to check tlb entry, return
> the physical address and access priviledge. Also it can be used with
> page table entry, which is used in page table walker.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> target/loongarch/cpu-mmu.h | 10 +++++
> target/loongarch/cpu_helper.c | 62 ++++++++++++++++++++++++++++++
> target/loongarch/tcg/tlb_helper.c | 63 ++++++-------------------------
> 3 files changed, 84 insertions(+), 51 deletions(-)
>
> diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
> index 4c5cbd7425..62b3acfbc7 100644
> --- a/target/loongarch/cpu-mmu.h
> +++ b/target/loongarch/cpu-mmu.h
> @@ -19,7 +19,17 @@ enum {
> TLBRET_PE = 7,
> };
>
> +typedef struct mmu_context {
> + target_ulong vaddr;
Use the 'vaddr' type.
> + uint64_t pte;
> + hwaddr physical;
> + int ps; /* page size shift */
> + int prot;
> +} mmu_context;
QEMU coding style prefers CamelCase.
> +int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
> + int access_type, int mmu_idx)
Use MMUAccessType access_type.
And fix loongarch_map_tlb_entry in a separate patch.
That's the type from loongarch_get_addr_from_tlb and above.
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 06/17] target/loongarch: Use loongarch_check_pte() with page table walking
2025-07-25 1:37 ` [PATCH v3 06/17] target/loongarch: Use loongarch_check_pte() with page table walking Bibo Mao
@ 2025-07-26 1:20 ` Richard Henderson
0 siblings, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:20 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> Function loongarch_check_pte() can get physical address and access
> priviledge, it works on both TLB entry and pte entry. It can be used
> at page table walking.
>
> Signed-off-by: Bibo Mao<maobibo@loongson.cn>
> ---
> target/loongarch/cpu_helper.c | 38 +++++++++++++----------------------
> 1 file changed, 14 insertions(+), 24 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker
2025-07-25 1:37 ` [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker Bibo Mao
@ 2025-07-26 1:31 ` Richard Henderson
2025-07-28 3:16 ` Bibo Mao
0 siblings, 1 reply; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:31 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> @@ -191,8 +187,7 @@ static int loongarch_map_address(CPULoongArchState *env, hwaddr *physical,
> * legal mapping, even if the mapping is not yet in TLB. return 0 if
> * there is a valid map, else none zero.
> */
> - return loongarch_page_table_walker(env, physical, prot, address,
> - access_type, mmu_idx);
> + return loongarch_page_table_walker(env, &context, access_type, mmu_idx);
> }
You haven't stored to the physical/prot arguments to loongarch_map_address. I'm sure this
gets fixed somewhere in patches 7 through 11, but it means that this patch set isn't
bisectable.
It *might* be easier to start from the other end of the call stack.
Then you can do things like
return loongarch_page_table_walker(env, &context->physical, &context->prot, etc)
in the intermediate steps.
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb
2025-07-25 1:37 ` [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb Bibo Mao
@ 2025-07-26 1:45 ` Richard Henderson
2025-07-28 3:22 ` Bibo Mao
0 siblings, 1 reply; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:45 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:37, Bibo Mao wrote:
> With tlb_flush_range_by_mmuidx(), the virtual address is 64 bit.
> However on LoongArch TLB emulation system, virtual address is
> 48 bit. It is necessary to convert 48 bit address to 64 bit when
> flush tlb, also fix address calculation issue with odd page.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> target/loongarch/tcg/tlb_helper.c | 14 +++++++++++---
> 1 file changed, 11 insertions(+), 3 deletions(-)
>
> diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
> index 715c5a20da..61cc19610e 100644
> --- a/target/loongarch/tcg/tlb_helper.c
> +++ b/target/loongarch/tcg/tlb_helper.c
> @@ -96,6 +96,15 @@ static void raise_mmu_exception(CPULoongArchState *env, target_ulong address,
> }
> }
>
> +/* Convert 48 bit virtual address from LoongArch TLB to 64 bit VA */
> +static inline target_ulong __vaddr(target_ulong addr)
> +{
> + target_ulong high;
> +
> + high = -(addr >> (TARGET_VIRT_ADDR_SPACE_BITS - 1));
> + return addr + (high << TARGET_VIRT_ADDR_SPACE_BITS);
> +}
Don't use __ symbols.
Also, this function is
sextract64(addr, 0, TARGET_VIRT_ADDR_SPACE_BITS - 1)
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 15/17] target/loongarch: Add parameter tlb pointer with fill_tlb_entry
2025-07-25 1:47 ` [PATCH v3 15/17] target/loongarch: Add parameter tlb pointer with fill_tlb_entry Bibo Mao
@ 2025-07-26 1:47 ` Richard Henderson
0 siblings, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2025-07-26 1:47 UTC (permalink / raw)
To: qemu-devel
On 7/24/25 15:47, Bibo Mao wrote:
> With function fill_tlb_entry(), it will update LoongArch emulated
> TLB information. Here parameter tlb pointer is added so that TLB
> entry will be updated based on relative TLB CSR registers.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
> target/loongarch/tcg/tlb_helper.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h
2025-07-26 1:16 ` Richard Henderson
@ 2025-07-28 3:08 ` Bibo Mao
0 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-28 3:08 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 2025/7/26 上午9:16, Richard Henderson wrote:
> On 7/24/25 15:37, Bibo Mao wrote:
>> +enum {
>> + TLBRET_MATCH = 0,
>> + TLBRET_BADADDR = 1,
>> + TLBRET_NOMATCH = 2,
>> + TLBRET_INVALID = 3,
>> + TLBRET_DIRTY = 4,
>> + TLBRET_RI = 5,
>> + TLBRET_XI = 6,
>> + TLBRET_PE = 7,
>> +};
>
> For a follow-up patch, name this enumeration and use it instead of 'int'.
> It would make it self-documenting what a function is computing.
Sure, will remove these assigned sentence and use default enumeration
value in new patch.
Regards
Bibo Mao
>
>
> r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte()
2025-07-26 1:19 ` Richard Henderson
@ 2025-07-28 3:15 ` Bibo Mao
2025-07-28 5:07 ` Richard Henderson
0 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-28 3:15 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 2025/7/26 上午9:19, Richard Henderson wrote:
> On 7/24/25 15:37, Bibo Mao wrote:
>> Common function loongarch_check_pte() is to check tlb entry, return
>> the physical address and access priviledge. Also it can be used with
>> page table entry, which is used in page table walker.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>> target/loongarch/cpu-mmu.h | 10 +++++
>> target/loongarch/cpu_helper.c | 62 ++++++++++++++++++++++++++++++
>> target/loongarch/tcg/tlb_helper.c | 63 ++++++-------------------------
>> 3 files changed, 84 insertions(+), 51 deletions(-)
>>
>> diff --git a/target/loongarch/cpu-mmu.h b/target/loongarch/cpu-mmu.h
>> index 4c5cbd7425..62b3acfbc7 100644
>> --- a/target/loongarch/cpu-mmu.h
>> +++ b/target/loongarch/cpu-mmu.h
>> @@ -19,7 +19,17 @@ enum {
>> TLBRET_PE = 7,
>> };
>> +typedef struct mmu_context {
>> + target_ulong vaddr;
>
> Use the 'vaddr' type.
will do in this way. It is simple and work on 32-bit guest vm on 64-bit
host also.
>
>> + uint64_t pte;
>> + hwaddr physical;
>> + int ps; /* page size shift */
>> + int prot;
>> +} mmu_context;
>
> QEMU coding style prefers CamelCase.
Will do, how about the name MMUContext?
>
>> +int loongarch_check_pte(CPULoongArchState *env, mmu_context *context,
>> + int access_type, int mmu_idx)
>
> Use MMUAccessType access_type.
> And fix loongarch_map_tlb_entry in a separate patch.
Will do this in a new patch.
> That's the type from loongarch_get_addr_from_tlb and above.
Regards
Bibo Mao
>
>
> r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker
2025-07-26 1:31 ` Richard Henderson
@ 2025-07-28 3:16 ` Bibo Mao
0 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-28 3:16 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 2025/7/26 上午9:31, Richard Henderson wrote:
> On 7/24/25 15:37, Bibo Mao wrote:
>> @@ -191,8 +187,7 @@ static int loongarch_map_address(CPULoongArchState
>> *env, hwaddr *physical,
>> * legal mapping, even if the mapping is not yet in TLB.
>> return 0 if
>> * there is a valid map, else none zero.
>> */
>> - return loongarch_page_table_walker(env, physical, prot, address,
>> - access_type, mmu_idx);
>> + return loongarch_page_table_walker(env, &context,
>> access_type, mmu_idx);
>> }
>
> You haven't stored to the physical/prot arguments to
> loongarch_map_address. I'm sure this gets fixed somewhere in patches 7
> through 11, but it means that this patch set isn't bisectable.
>
> It *might* be easier to start from the other end of the call stack.
> Then you can do things like
>
> return loongarch_page_table_walker(env, &context->physical,
> &context->prot, etc)
>
> in the intermediate steps.
Good catch. This patch has problem and will fix it in next round.
Regards
Bibo Mao
>
>
> r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb
2025-07-26 1:45 ` Richard Henderson
@ 2025-07-28 3:22 ` Bibo Mao
2025-07-28 5:09 ` Richard Henderson
0 siblings, 1 reply; 34+ messages in thread
From: Bibo Mao @ 2025-07-28 3:22 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 2025/7/26 上午9:45, Richard Henderson wrote:
> On 7/24/25 15:37, Bibo Mao wrote:
>> With tlb_flush_range_by_mmuidx(), the virtual address is 64 bit.
>> However on LoongArch TLB emulation system, virtual address is
>> 48 bit. It is necessary to convert 48 bit address to 64 bit when
>> flush tlb, also fix address calculation issue with odd page.
>>
>> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
>> ---
>> target/loongarch/tcg/tlb_helper.c | 14 +++++++++++---
>> 1 file changed, 11 insertions(+), 3 deletions(-)
>>
>> diff --git a/target/loongarch/tcg/tlb_helper.c
>> b/target/loongarch/tcg/tlb_helper.c
>> index 715c5a20da..61cc19610e 100644
>> --- a/target/loongarch/tcg/tlb_helper.c
>> +++ b/target/loongarch/tcg/tlb_helper.c
>> @@ -96,6 +96,15 @@ static void raise_mmu_exception(CPULoongArchState
>> *env, target_ulong address,
>> }
>> }
>> +/* Convert 48 bit virtual address from LoongArch TLB to 64 bit VA */
>> +static inline target_ulong __vaddr(target_ulong addr)
>> +{
>> + target_ulong high;
>> +
>> + high = -(addr >> (TARGET_VIRT_ADDR_SPACE_BITS - 1));
>> + return addr + (high << TARGET_VIRT_ADDR_SPACE_BITS);
>> +}
>
> Don't use __ symbols.
> Also, this function is
>
> sextract64(addr, 0, TARGET_VIRT_ADDR_SPACE_BITS - 1)
yeap, sextract64 is simpler and effective. How about
loongarch_vppn_to_vaddr compared with __vaddr about function name?
Regards
Bibo Mao
>
>
> r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte()
2025-07-28 3:15 ` Bibo Mao
@ 2025-07-28 5:07 ` Richard Henderson
0 siblings, 0 replies; 34+ messages in thread
From: Richard Henderson @ 2025-07-28 5:07 UTC (permalink / raw)
To: Bibo Mao, qemu-devel
On 7/27/25 17:15, Bibo Mao wrote:
>>> + uint64_t pte;
>>> + hwaddr physical;
>>> + int ps; /* page size shift */
>>> + int prot;
>>> +} mmu_context;
>>
>> QEMU coding style prefers CamelCase.
> Will do, how about the name MMUContext?
That sounds good.
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb
2025-07-28 3:22 ` Bibo Mao
@ 2025-07-28 5:09 ` Richard Henderson
2025-07-28 6:05 ` Bibo Mao
0 siblings, 1 reply; 34+ messages in thread
From: Richard Henderson @ 2025-07-28 5:09 UTC (permalink / raw)
To: Bibo Mao, qemu-devel
On 7/27/25 17:22, Bibo Mao wrote:
>>> +static inline target_ulong __vaddr(target_ulong addr)
>>> +{
>>> + target_ulong high;
>>> +
>>> + high = -(addr >> (TARGET_VIRT_ADDR_SPACE_BITS - 1));
>>> + return addr + (high << TARGET_VIRT_ADDR_SPACE_BITS);
>>> +}
>>
>> Don't use __ symbols.
>> Also, this function is
>>
>> sextract64(addr, 0, TARGET_VIRT_ADDR_SPACE_BITS - 1)
> yeap, sextract64 is simpler and effective. How about loongarch_vppn_to_vaddr compared with
> __vaddr about function name?
There was one use of __vaddr in this patch. Do you need a separate helper function at
all? Just use sextract64 directly within invalidate_tlb_entry.
r~
^ permalink raw reply [flat|nested] 34+ messages in thread
* Re: [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb
2025-07-28 5:09 ` Richard Henderson
@ 2025-07-28 6:05 ` Bibo Mao
0 siblings, 0 replies; 34+ messages in thread
From: Bibo Mao @ 2025-07-28 6:05 UTC (permalink / raw)
To: Richard Henderson, qemu-devel
On 2025/7/28 下午1:09, Richard Henderson wrote:
> On 7/27/25 17:22, Bibo Mao wrote:
>>>> +static inline target_ulong __vaddr(target_ulong addr)
>>>> +{
>>>> + target_ulong high;
>>>> +
>>>> + high = -(addr >> (TARGET_VIRT_ADDR_SPACE_BITS - 1));
>>>> + return addr + (high << TARGET_VIRT_ADDR_SPACE_BITS);
>>>> +}
>>>
>>> Don't use __ symbols.
>>> Also, this function is
>>>
>>> sextract64(addr, 0, TARGET_VIRT_ADDR_SPACE_BITS - 1)
>> yeap, sextract64 is simpler and effective. How about
>> loongarch_vppn_to_vaddr compared with __vaddr about function name?
>
> There was one use of __vaddr in this patch. Do you need a separate
> helper function at all? Just use sextract64 directly within
> invalidate_tlb_entry.
ok, will remove it directly.
And thanks for your kindly guidance.
Regards
Bibo Mao
>
>
> r~
^ permalink raw reply [flat|nested] 34+ messages in thread
end of thread, other threads:[~2025-07-28 6:09 UTC | newest]
Thread overview: 34+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-25 1:37 [PATCH v3 00/17] target/loongarch: Enhancement about tcg mmu Bibo Mao
2025-07-25 1:37 ` [PATCH v3 01/17] target/loongarch: Move some function definition to kvm directory Bibo Mao
2025-07-25 23:37 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 02/17] target/loongarch: Define function loongarch_cpu_post_init as static Bibo Mao
2025-07-25 23:38 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 03/17] target/loongarch: Set page size in TLB misc with STLB Bibo Mao
2025-07-25 1:37 ` [PATCH v3 04/17] target/loongarch: Add header file cpu-mmu.h Bibo Mao
2025-07-26 1:10 ` Richard Henderson
2025-07-26 1:16 ` Richard Henderson
2025-07-28 3:08 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 05/17] target/loongarch: Add common function loongarch_check_pte() Bibo Mao
2025-07-26 1:19 ` Richard Henderson
2025-07-28 3:15 ` Bibo Mao
2025-07-28 5:07 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 06/17] target/loongarch: Use loongarch_check_pte() with page table walking Bibo Mao
2025-07-26 1:20 ` Richard Henderson
2025-07-25 1:37 ` [PATCH v3 07/17] target/loongarch: Add parameter mmu_context with loongarch_page_table_walker Bibo Mao
2025-07-26 1:31 ` Richard Henderson
2025-07-28 3:16 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 08/17] target/loongarch: Add parameter mmu_context with loongarch_map_tlb_entry Bibo Mao
2025-07-25 1:37 ` [PATCH v3 09/17] target/loongarch: Add parameter mmu_context with loongarch_get_addr_from_tlb Bibo Mao
2025-07-25 1:37 ` [PATCH v3 10/17] target/loongarch: Add parameter mmu_context with loongarch_map_address Bibo Mao
2025-07-25 1:37 ` [PATCH v3 11/17] target/loongarch: Add parameter mmu_context with get_physical_address Bibo Mao
2025-07-25 1:37 ` [PATCH v3 12/17] target/loongarch: Track user mode address accessed in kernel mode Bibo Mao
2025-07-25 1:37 ` [PATCH v3 13/17] target/loongarch: Use correct address when flush tlb Bibo Mao
2025-07-26 1:45 ` Richard Henderson
2025-07-28 3:22 ` Bibo Mao
2025-07-28 5:09 ` Richard Henderson
2025-07-28 6:05 ` Bibo Mao
2025-07-25 1:37 ` [PATCH v3 14/17] target/loongarch: Use mmu idx bitmap method " Bibo Mao
2025-07-25 1:47 ` [PATCH v3 15/17] target/loongarch: Add parameter tlb pointer with fill_tlb_entry Bibo Mao
2025-07-26 1:47 ` Richard Henderson
2025-07-25 1:47 ` [PATCH v3 16/17] target/loongarch: Reduce TLB flush with helper_tlbwr Bibo Mao
2025-07-25 1:48 ` [PATCH v3 17/17] target/loongarch: Update TLB index selection method Bibo Mao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).