* [PATCH 1/1] target/loongarch: fix 'make check-functional failed'
@ 2025-02-17 0:54 Song Gao
2025-02-18 6:34 ` bibo mao
0 siblings, 1 reply; 2+ messages in thread
From: Song Gao @ 2025-02-17 0:54 UTC (permalink / raw)
To: qemu-devel, peter.maydell; +Cc: richard.henderson, yangxiaojuan, maobibo
For LoongArch th min tlb_ps is 12(4KB), for TLB code,
the tlb_ps may be 0,this may case UndefinedBehavior
Add a check-tlb_ps fuction to check tlb_ps, when use
csrwr insn to write CRMD PG=1, check the tlb_ps, and when
use csrwr insn to write STLBPS, check the tlb_ps value.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
target/loongarch/helper.h | 2 +
target/loongarch/internals.h | 1 +
target/loongarch/tcg/csr_helper.c | 52 +++++++++++++++++++
.../tcg/insn_trans/trans_privileged.c.inc | 2 +
target/loongarch/tcg/tlb_helper.c | 4 ++
5 files changed, 61 insertions(+)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 943517b5f2..4f1490a465 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -100,6 +100,8 @@ DEF_HELPER_1(rdtime_d, i64, env)
DEF_HELPER_1(csrrd_pgd, i64, env)
DEF_HELPER_1(csrrd_cpuid, i64, env)
DEF_HELPER_1(csrrd_tval, i64, env)
+DEF_HELPER_2(csrwr_crmd, i64, env,tl)
+DEF_HELPER_2(csrwr_stlbps, i64, env, tl)
DEF_HELPER_2(csrwr_estat, i64, env, tl)
DEF_HELPER_2(csrwr_asid, i64, env, tl)
DEF_HELPER_2(csrwr_tcfg, i64, env, tl)
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index 7b254c5f49..bb1644f0a0 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -43,6 +43,7 @@ enum {
TLBRET_PE = 7,
};
+void check_tlb_ps(CPULoongArchState *env);
extern const VMStateDescription vmstate_loongarch_cpu;
void loongarch_cpu_set_irq(void *opaque, int irq, int level);
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
index 6c95be9910..32c9716f42 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -97,6 +97,58 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
return old_v;
}
+void check_tlb_ps(CPULoongArchState *env)
+{
+ for (int i=0; i<LOONGARCH_TLB_MAX; i++)
+ {
+ LoongArchTLB*tlb =&env->tlb[i];
+ uint8_t tlb_ps;
+ if(i >= LOONGARCH_STLB) {
+ tlb_ps = FIELD_EX64(tlb->tlb_misc,TLB_MISC,PS);
+ if (tlb_ps < 12) {
+ tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, 12);
+ }
+ } else {
+ tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS,PS);
+ if (tlb_ps < 12) {
+ env->CSR_STLBPS= FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, 12);
+ }
+ }
+ }
+}
+
+target_ulong helper_csrwr_crmd(CPULoongArchState *env, target_ulong val)
+{
+ uint8_t pg;
+ int64_t old_v = env->CSR_CRMD;
+
+ pg = FIELD_EX64(val, CSR_CRMD, PG);
+ if (pg) {
+ check_tlb_ps(env);
+ }
+ env->CSR_CRMD = val;
+ return old_v;
+}
+
+target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
+{
+ uint8_t tlb_ps;
+ int64_t old_v = env->CSR_STLBPS;
+
+ /*
+ * The real hardware only supports the min tlb_ps is 12
+ * tlb_ps=0 may cause undefined-behavior.
+ */
+ tlb_ps = FIELD_EX64(val, CSR_STLBPS, PS);
+ if (tlb_ps < 12) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Attempted set ps %d\n",tlb_ps);
+ val = FIELD_DP64(val, CSR_STLBPS, PS, 12);
+ }
+ env->CSR_STLBPS = val;
+ return old_v;
+}
+
target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
{
int shift;
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index 3afa23af79..d6b1f8319f 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -74,6 +74,8 @@ static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn,
void loongarch_csr_translate_init(void)
{
+ SET_CSR_FUNC(CRMD, NULL,gen_helper_csrwr_crmd);
+ SET_CSR_FUNC(STLBPS, NULL,gen_helper_csrwr_stlbps);
SET_CSR_FUNC(ESTAT, NULL, gen_helper_csrwr_estat);
SET_CSR_FUNC(ASID, NULL, gen_helper_csrwr_asid);
SET_CSR_FUNC(PGD, gen_helper_csrrd_pgd, NULL);
diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
index a323606e5a..fc9c7823e7 100644
--- a/target/loongarch/tcg/tlb_helper.c
+++ b/target/loongarch/tcg/tlb_helper.c
@@ -449,7 +449,11 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
target_ulong info, target_ulong addr)
{
uint16_t asid = info & 0x3ff;
+ uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
+ if (!pg) {
+ return;
+ }
for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
LoongArchTLB *tlb = &env->tlb[i];
uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
--
2.34.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH 1/1] target/loongarch: fix 'make check-functional failed'
2025-02-17 0:54 [PATCH 1/1] target/loongarch: fix 'make check-functional failed' Song Gao
@ 2025-02-18 6:34 ` bibo mao
0 siblings, 0 replies; 2+ messages in thread
From: bibo mao @ 2025-02-18 6:34 UTC (permalink / raw)
To: Song Gao, qemu-devel, peter.maydell; +Cc: richard.henderson, yangxiaojuan
On 2025/2/17 上午8:54, Song Gao wrote:
> For LoongArch th min tlb_ps is 12(4KB), for TLB code,
> the tlb_ps may be 0,this may case UndefinedBehavior
> Add a check-tlb_ps fuction to check tlb_ps, when use
> csrwr insn to write CRMD PG=1, check the tlb_ps, and when
> use csrwr insn to write STLBPS, check the tlb_ps value.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> target/loongarch/helper.h | 2 +
> target/loongarch/internals.h | 1 +
> target/loongarch/tcg/csr_helper.c | 52 +++++++++++++++++++
> .../tcg/insn_trans/trans_privileged.c.inc | 2 +
> target/loongarch/tcg/tlb_helper.c | 4 ++
> 5 files changed, 61 insertions(+)
>
> diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
> index 943517b5f2..4f1490a465 100644
> --- a/target/loongarch/helper.h
> +++ b/target/loongarch/helper.h
> @@ -100,6 +100,8 @@ DEF_HELPER_1(rdtime_d, i64, env)
> DEF_HELPER_1(csrrd_pgd, i64, env)
> DEF_HELPER_1(csrrd_cpuid, i64, env)
> DEF_HELPER_1(csrrd_tval, i64, env)
> +DEF_HELPER_2(csrwr_crmd, i64, env,tl)
> +DEF_HELPER_2(csrwr_stlbps, i64, env, tl)
> DEF_HELPER_2(csrwr_estat, i64, env, tl)
> DEF_HELPER_2(csrwr_asid, i64, env, tl)
> DEF_HELPER_2(csrwr_tcfg, i64, env, tl)
> diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
> index 7b254c5f49..bb1644f0a0 100644
> --- a/target/loongarch/internals.h
> +++ b/target/loongarch/internals.h
> @@ -43,6 +43,7 @@ enum {
> TLBRET_PE = 7,
> };
>
> +void check_tlb_ps(CPULoongArchState *env);
> extern const VMStateDescription vmstate_loongarch_cpu;
>
> void loongarch_cpu_set_irq(void *opaque, int irq, int level);
> diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
> index 6c95be9910..32c9716f42 100644
> --- a/target/loongarch/tcg/csr_helper.c
> +++ b/target/loongarch/tcg/csr_helper.c
> @@ -97,6 +97,58 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
> return old_v;
> }
>
> +void check_tlb_ps(CPULoongArchState *env)
> +{
> + for (int i=0; i<LOONGARCH_TLB_MAX; i++)
> + {
> + LoongArchTLB*tlb =&env->tlb[i];
> + uint8_t tlb_ps;
> + if(i >= LOONGARCH_STLB) {
> + tlb_ps = FIELD_EX64(tlb->tlb_misc,TLB_MISC,PS);
It is strange why tlb entries is check here? If I am understanding
right, TLB page size should comes from these two areas:
FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE); or
FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS,PS);
If page size of CSR_PWCL is equal to CSR_STLBPS, it is put to STLB, else
it is put to MTLB. If so, it will be ok if these CSR registers are checked.
FIELD_EX64(env->CSR_PWCL, CSR_PWCL, PTBASE)
FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS,PS)
And when system is set with Page-mode by writing CRMD register, TLB
entry should be empty in theory.
> + if (tlb_ps < 12) {
> + tlb->tlb_misc = FIELD_DP64(tlb->tlb_misc, TLB_MISC, PS, 12);
> + }
> + } else {
> + tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS,PS);
> + if (tlb_ps < 12) {
> + env->CSR_STLBPS= FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, 12);
> + }
> + }
> + }
> +}
> +
> +target_ulong helper_csrwr_crmd(CPULoongArchState *env, target_ulong val)
> +{
> + uint8_t pg;
> + int64_t old_v = env->CSR_CRMD;
> +
> + pg = FIELD_EX64(val, CSR_CRMD, PG);
Do you mean that it is the first time that Page-mode is set. If so, it
had better be:
old = FIELD_EX64(old_v, CSR_CRMD, PG);
if (pg && !old) {
Regards
Bibo Mao
> + if (pg) {
> + check_tlb_ps(env);
> + }
> + env->CSR_CRMD = val;
> + return old_v;
> +}
> +
> +target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
> +{
> + uint8_t tlb_ps;
> + int64_t old_v = env->CSR_STLBPS;
> +
> + /*
> + * The real hardware only supports the min tlb_ps is 12
> + * tlb_ps=0 may cause undefined-behavior.
> + */
> + tlb_ps = FIELD_EX64(val, CSR_STLBPS, PS);
> + if (tlb_ps < 12) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "Attempted set ps %d\n",tlb_ps);
> + val = FIELD_DP64(val, CSR_STLBPS, PS, 12);
> + }
> + env->CSR_STLBPS = val;
> + return old_v;
> +}
> +
> target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
> {
> int shift;
> diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
> index 3afa23af79..d6b1f8319f 100644
> --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
> +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
> @@ -74,6 +74,8 @@ static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn,
>
> void loongarch_csr_translate_init(void)
> {
> + SET_CSR_FUNC(CRMD, NULL,gen_helper_csrwr_crmd);
> + SET_CSR_FUNC(STLBPS, NULL,gen_helper_csrwr_stlbps);
> SET_CSR_FUNC(ESTAT, NULL, gen_helper_csrwr_estat);
> SET_CSR_FUNC(ASID, NULL, gen_helper_csrwr_asid);
> SET_CSR_FUNC(PGD, gen_helper_csrrd_pgd, NULL);
> diff --git a/target/loongarch/tcg/tlb_helper.c b/target/loongarch/tcg/tlb_helper.c
> index a323606e5a..fc9c7823e7 100644
> --- a/target/loongarch/tcg/tlb_helper.c
> +++ b/target/loongarch/tcg/tlb_helper.c
> @@ -449,7 +449,11 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
> target_ulong info, target_ulong addr)
> {
> uint16_t asid = info & 0x3ff;
> + uint8_t pg = FIELD_EX64(env->CSR_CRMD, CSR_CRMD, PG);
>
> + if (!pg) {
> + return;
> + }
> for (int i = 0; i < LOONGARCH_TLB_MAX; i++) {
> LoongArchTLB *tlb = &env->tlb[i];
> uint8_t tlb_g = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, G);
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-02-18 6:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-17 0:54 [PATCH 1/1] target/loongarch: fix 'make check-functional failed' Song Gao
2025-02-18 6:34 ` 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).