Skip to content

Commit cfadd79

Browse files
committed
Merge tag 'pull-loongarch-20250307' of https://gitlab.com/gaosong/qemu into staging
pull-loongarch-tcg-20250307 # -----BEGIN PGP SIGNATURE----- # # iLMEAAEKAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZ8pZ+gAKCRBAov/yOSY+ # 3ytAA/9OHCtGa35ZAFb4BrRQirs6cfjz9mSQDmjXzmt5/2mjhlm42chnfF5h0UR4 # puP2LuhpvomYsdCJDnznK8+9y9b34O5jcT8kd4jZ3Bo/fCczGPMqXy0a5lXc5IEE # 7dHqZ+ksiCptHtBhoubfJzqiNDTMpgBUA2h855CUqIFhjkhDyA== # =rUF7 # -----END PGP SIGNATURE----- # gpg: Signature made Fri 07 Mar 2025 10:29:14 HKT # gpg: using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF # gpg: Good signature from "Song Gao <[email protected]>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: B8FF 1DA0 D2FD CB2D A09C 6C2C 40A2 FFF2 3926 3EDF * tag 'pull-loongarch-20250307' of https://gitlab.com/gaosong/qemu: target/loongarch: check tlb_ps target/loongarch: fix 'make check-functional' failed Signed-off-by: Stefan Hajnoczi <[email protected]>
2 parents 98c7362 + d882c28 commit cfadd79

File tree

6 files changed

+68
-8
lines changed

6 files changed

+68
-8
lines changed

target/loongarch/cpu.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ static void loongarch_max_initfn(Object *obj)
544544

545545
static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
546546
{
547+
uint8_t tlb_ps;
547548
CPUState *cs = CPU(obj);
548549
LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj);
549550
CPULoongArchState *env = cpu_env(cs);
@@ -592,13 +593,17 @@ static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
592593
*/
593594
env->CSR_PGDH = 0;
594595
env->CSR_PGDL = 0;
595-
env->CSR_PWCL = 0;
596596
env->CSR_PWCH = 0;
597-
env->CSR_STLBPS = 0;
598597
env->CSR_EENTRY = 0;
599598
env->CSR_TLBRENTRY = 0;
600599
env->CSR_MERRENTRY = 0;
601-
600+
/* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */
601+
if (env->CSR_PRCFG2 == 0) {
602+
env->CSR_PRCFG2 = 0x3fffff000;
603+
}
604+
tlb_ps = ctz32(env->CSR_PRCFG2);
605+
env->CSR_STLBPS = FIELD_DP64(env->CSR_STLBPS, CSR_STLBPS, PS, tlb_ps);
606+
env->CSR_PWCL = FIELD_DP64(env->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps);
602607
for (n = 0; n < 4; n++) {
603608
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV0, 0);
604609
env->CSR_DMW[n] = FIELD_DP64(env->CSR_DMW[n], CSR_DMW, PLV1, 0);

target/loongarch/helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ DEF_HELPER_1(rdtime_d, i64, env)
100100
DEF_HELPER_1(csrrd_pgd, i64, env)
101101
DEF_HELPER_1(csrrd_cpuid, i64, env)
102102
DEF_HELPER_1(csrrd_tval, i64, env)
103+
DEF_HELPER_2(csrwr_stlbps, i64, env, tl)
103104
DEF_HELPER_2(csrwr_estat, i64, env, tl)
104105
DEF_HELPER_2(csrwr_asid, i64, env, tl)
105106
DEF_HELPER_2(csrwr_tcfg, i64, env, tl)

target/loongarch/internals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ enum {
4343
TLBRET_PE = 7,
4444
};
4545

46+
bool check_ps(CPULoongArchState *ent, int ps);
47+
4648
extern const VMStateDescription vmstate_loongarch_cpu;
4749

4850
void loongarch_cpu_set_irq(void *opaque, int irq, int level);

target/loongarch/tcg/csr_helper.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,22 @@
1717
#include "hw/irq.h"
1818
#include "cpu-csr.h"
1919

20+
target_ulong helper_csrwr_stlbps(CPULoongArchState *env, target_ulong val)
21+
{
22+
int64_t old_v = env->CSR_STLBPS;
23+
24+
/*
25+
* The real hardware only supports the min tlb_ps is 12
26+
* tlb_ps=0 may cause undefined-behavior.
27+
*/
28+
uint8_t tlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
29+
if (!check_ps(env, tlb_ps)) {
30+
qemu_log_mask(LOG_GUEST_ERROR,
31+
"Attempted set ps %d\n", tlb_ps);
32+
}
33+
return old_v;
34+
}
35+
2036
target_ulong helper_csrrd_pgd(CPULoongArchState *env)
2137
{
2238
int64_t v;
@@ -99,20 +115,24 @@ target_ulong helper_csrwr_ticlr(CPULoongArchState *env, target_ulong val)
99115

100116
target_ulong helper_csrwr_pwcl(CPULoongArchState *env, target_ulong val)
101117
{
102-
int shift;
118+
int shift, ptbase;
103119
int64_t old_v = env->CSR_PWCL;
104120

105121
/*
106122
* The real hardware only supports 64bit PTE width now, 128bit or others
107123
* treated as illegal.
108124
*/
109125
shift = FIELD_EX64(val, CSR_PWCL, PTEWIDTH);
126+
ptbase = FIELD_EX64(val, CSR_PWCL, PTBASE);
110127
if (shift) {
111128
qemu_log_mask(LOG_GUEST_ERROR,
112129
"Attempted set pte width with %d bit\n", 64 << shift);
113130
val = FIELD_DP64(val, CSR_PWCL, PTEWIDTH, 0);
114131
}
115-
116-
env->CSR_PWCL = val;
132+
if (!check_ps(env, ptbase)) {
133+
qemu_log_mask(LOG_GUEST_ERROR,
134+
"Attrmpted set ptbase 2^%d\n", ptbase);
135+
}
136+
env->CSR_PWCL =val;
117137
return old_v;
118138
}

target/loongarch/tcg/insn_trans/trans_privileged.c.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ static bool set_csr_trans_func(unsigned int csr_num, GenCSRRead readfn,
7474

7575
void loongarch_csr_translate_init(void)
7676
{
77+
SET_CSR_FUNC(STLBPS, NULL, gen_helper_csrwr_stlbps);
7778
SET_CSR_FUNC(ESTAT, NULL, gen_helper_csrwr_estat);
7879
SET_CSR_FUNC(ASID, NULL, gen_helper_csrwr_asid);
7980
SET_CSR_FUNC(PGD, gen_helper_csrrd_pgd, NULL);

target/loongarch/tcg/tlb_helper.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@
1818
#include "exec/log.h"
1919
#include "cpu-csr.h"
2020

21+
bool check_ps(CPULoongArchState *env, int tlb_ps)
22+
{
23+
if (tlb_ps > 64) {
24+
return false;
25+
}
26+
return BIT_ULL(tlb_ps) & (env->CSR_PRCFG2);
27+
}
28+
2129
void get_dir_base_width(CPULoongArchState *env, uint64_t *dir_base,
2230
uint64_t *dir_width, target_ulong level)
2331
{
@@ -123,7 +131,11 @@ static void invalidate_tlb_entry(CPULoongArchState *env, int index)
123131
uint8_t tlb_v0 = FIELD_EX64(tlb->tlb_entry0, TLBENTRY, V);
124132
uint8_t tlb_v1 = FIELD_EX64(tlb->tlb_entry1, TLBENTRY, V);
125133
uint64_t tlb_vppn = FIELD_EX64(tlb->tlb_misc, TLB_MISC, VPPN);
134+
uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
126135

136+
if (!tlb_e) {
137+
return;
138+
}
127139
if (index >= LOONGARCH_STLB) {
128140
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
129141
} else {
@@ -187,8 +199,10 @@ static void fill_tlb_entry(CPULoongArchState *env, int index)
187199
lo1 = env->CSR_TLBELO1;
188200
}
189201

190-
if (csr_ps == 0) {
191-
qemu_log_mask(CPU_LOG_MMU, "page size is 0\n");
202+
/*check csr_ps */
203+
if (!check_ps(env, csr_ps)) {
204+
qemu_log_mask(LOG_GUEST_ERROR, "csr_ps %d is illegal\n", csr_ps);
205+
return;
192206
}
193207

194208
/* Only MTLB has the ps fields */
@@ -298,7 +312,16 @@ void helper_tlbfill(CPULoongArchState *env)
298312
pagesize = FIELD_EX64(env->CSR_TLBIDX, CSR_TLBIDX, PS);
299313
}
300314

315+
if (!check_ps(env, pagesize)) {
316+
qemu_log_mask(LOG_GUEST_ERROR, "pagesize %d is illegal\n", pagesize);
317+
return;
318+
}
319+
301320
stlb_ps = FIELD_EX64(env->CSR_STLBPS, CSR_STLBPS, PS);
321+
if (!check_ps(env, stlb_ps)) {
322+
qemu_log_mask(LOG_GUEST_ERROR, "stlb_ps %d is illegal\n", stlb_ps);
323+
return;
324+
}
302325

303326
if (pagesize == stlb_ps) {
304327
/* Only write into STLB bits [47:13] */
@@ -427,7 +450,11 @@ void helper_invtlb_page_asid(CPULoongArchState *env, target_ulong info,
427450
uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
428451
uint64_t vpn, tlb_vppn;
429452
uint8_t tlb_ps, compare_shift;
453+
uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
430454

455+
if (!tlb_e) {
456+
continue;
457+
}
431458
if (i >= LOONGARCH_STLB) {
432459
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
433460
} else {
@@ -456,7 +483,11 @@ void helper_invtlb_page_asid_or_g(CPULoongArchState *env,
456483
uint16_t tlb_asid = FIELD_EX64(tlb->tlb_misc, TLB_MISC, ASID);
457484
uint64_t vpn, tlb_vppn;
458485
uint8_t tlb_ps, compare_shift;
486+
uint8_t tlb_e = FIELD_EX64(tlb->tlb_misc, TLB_MISC, E);
459487

488+
if (!tlb_e) {
489+
continue;
490+
}
460491
if (i >= LOONGARCH_STLB) {
461492
tlb_ps = FIELD_EX64(tlb->tlb_misc, TLB_MISC, PS);
462493
} else {

0 commit comments

Comments
 (0)