于 2026年9月1日 GMT+08:00 15:08:59,Bibo Mao <[email protected]> 写道:
>
>
>On 2026/8/26 下午6:30, SignKirigami wrote:
>> Add LVZ host and guest CSR access metadata to the existing CSR table. Keep
>> one shared register description and calculate the host or guest bank
>> offset at translation time instead of duplicating CSRInfo entries.
>> 
>> Mark guest read-only, sensitive and unavailable CSRs for later LVZ
>> instruction translation.
>> 
>> Signed-off-by: SignKirigami <[email protected]>
>> Signed-off-by: Hengyu Yu <[email protected]>
>> ---
>>   target/loongarch/cpu.c                        |   3 +-
>>   target/loongarch/csr.c                        | 108 +++++++++---------
>>   target/loongarch/csr.h                        |   2 +
>>   .../tcg/insn_trans/trans_extra.c.inc          |   2 +-
>>   .../tcg/insn_trans/trans_privileged.c.inc     |   6 +-
>>   5 files changed, 65 insertions(+), 56 deletions(-)
>> 
>> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
>> index 2f7692dc93..0f6a211949 100644
>> --- a/target/loongarch/cpu.c
>> +++ b/target/loongarch/cpu.c
>> @@ -783,7 +783,8 @@ static void loongarch_cpu_dump_csr(CPUState *cs, FILE *f)
>>               qemu_fprintf(f, " CSR%03d:", col);
>>           }
>>   -        addr = (void *)env + get_csr_offset(csr_info, 0);
>> +        addr = (void *)env + get_csr_offset(csr_info,
>> +                                             LOONGARCH_VM_LEVEL_HOST);
>>           qemu_fprintf(f, " %s ", csr_info->name);
>>           len = strlen(csr_info->name);
>>           for (; len < 6; len++) {
>> diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c
>> index 309b826ca9..fa018a4582 100644
>> --- a/target/loongarch/csr.c
>> +++ b/target/loongarch/csr.c
>> @@ -13,15 +13,16 @@
>>           .flags = FL, .readfn = RD, .writefn = WR           \
>>       }
>>   -#define CSR_OFF_ARRAY(NAME, N)                                \
>> +#define CSR_OFF_ARRAY_FLAGS(NAME, N, FL)                      \
>>       [LOONGARCH_CSR_##NAME(N)] = {                             \
>>           .name   = (stringify(NAME##N)),                       \
>>           .offset = CSR_OFFSET(CSR_##NAME[N]),                  \
>> -        .flags = CSRFL_BASIC, .readfn = NULL, .writefn = NULL           \
>> +        .flags = FL                                           \
>>       }
>>     #define CSR_OFF_FLAGS(NAME, FL)   CSR_OFF_FUNCS(NAME, FL, NULL, NULL)
>>   #define CSR_OFF(NAME)             CSR_OFF_FLAGS(NAME, CSRFL_BASIC)
>> +#define CSR_OFF_ARRAY(NAME, N)    CSR_OFF_ARRAY_FLAGS(NAME, N, CSRFL_BASIC)
>>     static CSRInfo csr_info[] = {
>>       CSR_OFF_FLAGS(CRMD, CSRFL_EXITTB),
>> @@ -35,6 +36,7 @@ static CSRInfo csr_info[] = {
>>       CSR_OFF_FLAGS(BADI, CSRFL_READONLY),
>>       CSR_OFF(EENTRY),
>>       CSR_OFF(TLBIDX),
>> +    CSR_OFF_FLAGS(GTLBC, CSRFL_GSPR),
>>       CSR_OFF(TLBEHI),
>>       CSR_OFF(TLBELO0),
>>       CSR_OFF(TLBELO1),
>> @@ -71,9 +73,13 @@ static CSRInfo csr_info[] = {
>>       CSR_OFF_FLAGS(TVAL, CSRFL_READONLY | CSRFL_IO),
>>       CSR_OFF(CNTC),
>>       CSR_OFF_FLAGS(TICLR, CSRFL_IO),
>Should previous CSR_OFF_FLAGS(GTLBC, CSRFL_GSPR) be moved to here? since all 
>these registers relative with LVZ.
>> +    CSR_OFF_FLAGS(GSTAT, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(GCFG, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(GINTC, CSRFL_IO | CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(GCNTC, CSRFL_GSPR),
>>       CSR_OFF(LLBCTL),
>> -    CSR_OFF(IMPCTL1),
>> -    CSR_OFF(IMPCTL2),
>> +    CSR_OFF_FLAGS(IMPCTL1, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(IMPCTL2, CSRFL_GSPR),
>It change the old flags, previous its flag is CSRFL_BASIC, and not it is 
>replaced with CSRFL_GSPR. How about CSRFL_BASIC | CSRFL_GSPR and keep old flag 
>still on?
CSRFL_BASIC is for "no flag but valid", as new get_csr sees csr_info with flag 
0 as invalid,
no other code uses this flag so it is ok to delete this flag when another flag 
exists.

Regards
SignKirigami
>
>>       CSR_OFF(TLBRENTRY),
>>       CSR_OFF(TLBRBADV),
>>       CSR_OFF(TLBRERA),
>> @@ -82,57 +88,57 @@ static CSRInfo csr_info[] = {
>>       CSR_OFF(TLBRELO1),
>>       CSR_OFF(TLBREHI),
>>       CSR_OFF(TLBRPRMD),
>> -    CSR_OFF(MERRCTL),
>> -    CSR_OFF(MERRINFO1),
>> -    CSR_OFF(MERRINFO2),
>> -    CSR_OFF(MERRENTRY),
>> -    CSR_OFF(MERRERA),
>> -    CSR_OFF(MERRSAVE),
>> -    CSR_OFF(CTAG),
>> +    CSR_OFF_FLAGS(MERRCTL, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(MERRINFO1, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(MERRINFO2, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(MERRENTRY, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(MERRERA, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(MERRSAVE, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(CTAG, CSRFL_GSPR),
>>       CSR_OFF_ARRAY(DMW, 0),
>>       CSR_OFF_ARRAY(DMW, 1),
>>       CSR_OFF_ARRAY(DMW, 2),
>>       CSR_OFF_ARRAY(DMW, 3),
>> -    CSR_OFF_ARRAY(PERFCTRL, 0),
>> -    CSR_OFF_ARRAY(PERFCNTR, 0),
>> -    CSR_OFF_ARRAY(PERFCTRL, 1),
>> -    CSR_OFF_ARRAY(PERFCNTR, 1),
>> -    CSR_OFF_ARRAY(PERFCTRL, 2),
>> -    CSR_OFF_ARRAY(PERFCNTR, 2),
>> -    CSR_OFF_ARRAY(PERFCTRL, 3),
>> -    CSR_OFF_ARRAY(PERFCNTR, 3),
>> -    CSR_OFF_ARRAY(PERFCTRL, 4),
>> -    CSR_OFF_ARRAY(PERFCNTR, 4),
>> -    CSR_OFF_ARRAY(PERFCTRL, 5),
>> -    CSR_OFF_ARRAY(PERFCNTR, 5),
>> -    CSR_OFF_ARRAY(PERFCTRL, 6),
>> -    CSR_OFF_ARRAY(PERFCNTR, 6),
>> -    CSR_OFF_ARRAY(PERFCTRL, 7),
>> -    CSR_OFF_ARRAY(PERFCNTR, 7),
>> -    CSR_OFF_ARRAY(PERFCTRL, 8),
>> -    CSR_OFF_ARRAY(PERFCNTR, 8),
>> -    CSR_OFF_ARRAY(PERFCTRL, 9),
>> -    CSR_OFF_ARRAY(PERFCNTR, 9),
>> -    CSR_OFF_ARRAY(PERFCTRL, 10),
>> -    CSR_OFF_ARRAY(PERFCNTR, 10),
>> -    CSR_OFF_ARRAY(PERFCTRL, 11),
>> -    CSR_OFF_ARRAY(PERFCNTR, 11),
>> -    CSR_OFF_ARRAY(PERFCTRL, 12),
>> -    CSR_OFF_ARRAY(PERFCNTR, 12),
>> -    CSR_OFF_ARRAY(PERFCTRL, 13),
>> -    CSR_OFF_ARRAY(PERFCNTR, 13),
>> -    CSR_OFF_ARRAY(PERFCTRL, 14),
>> -    CSR_OFF_ARRAY(PERFCNTR, 14),
>> -    CSR_OFF_ARRAY(PERFCTRL, 15),
>> -    CSR_OFF_ARRAY(PERFCNTR, 15),
>> -    CSR_OFF(DBG),
>> -    CSR_OFF(DERA),
>> -    CSR_OFF(DSAVE),
>> -    CSR_OFF_ARRAY(MSGIS, 0),
>> -    CSR_OFF_ARRAY(MSGIS, 1),
>> -    CSR_OFF_ARRAY(MSGIS, 2),
>> -    CSR_OFF_ARRAY(MSGIS, 3),
>> -    CSR_OFF(MSGIR),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 0, CSRFL_GUEST_INVALID),
>what is different between flag CSRFL_GSPR and CSRFL_GUEST_INVALID?
>
>With CSR register access instruction, on host value zero is return if it is 
>not implemented. On guest mode, I think that there should be GSPR exception 
>and trap to host and let hypervisor to handle this if it is not implemented. 
>There is no much meaning to return zero and does not trap to host.
>
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 0, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 1, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 1, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 2, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 2, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 3, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 3, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 4, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 4, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 5, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 5, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 6, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 6, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 7, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 7, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 8, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 8, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 9, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 9, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 10, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 10, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 11, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 11, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 12, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 12, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 13, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 13, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 14, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 14, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCTRL, 15, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(PERFCNTR, 15, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_FLAGS(DBG, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(DERA, CSRFL_GSPR),
>> +    CSR_OFF_FLAGS(DSAVE, CSRFL_GSPR),
>> +    CSR_OFF_ARRAY_FLAGS(MSGIS, 0, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(MSGIS, 1, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(MSGIS, 2, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_ARRAY_FLAGS(MSGIS, 3, CSRFL_GUEST_INVALID),
>> +    CSR_OFF_FLAGS(MSGIR, CSRFL_GUEST_INVALID),
>>   };
>>     CSRInfo *get_csr(unsigned int csr_num)
>> diff --git a/target/loongarch/csr.h b/target/loongarch/csr.h
>> index c2b6b882bc..647695e248 100644
>> --- a/target/loongarch/csr.h
>> +++ b/target/loongarch/csr.h
>> @@ -20,6 +20,8 @@ enum {
>>       CSRFL_IO       = (1 << 2),
>>       CSRFL_UNUSED   = (1 << 3),
>>       CSRFL_BASIC    = (1 << 4),
>> +    CSRFL_GSPR     = (1 << 5),
>> +    CSRFL_GUEST_INVALID = (1 << 6),
>>   };
>>     typedef struct {
>> diff --git a/target/loongarch/tcg/insn_trans/trans_extra.c.inc 
>> b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
>> index 655dce329e..e69384497f 100644
>> --- a/target/loongarch/tcg/insn_trans/trans_extra.c.inc
>> +++ b/target/loongarch/tcg/insn_trans/trans_extra.c.inc
>> @@ -55,7 +55,7 @@ static bool gen_rdtime(DisasContext *ctx, arg_rr *a,
>>           tcg_gen_sextract_tl(dst1, dst1, high ? 32 : 0, 32);
>>       }
>>   -    offset = CPU_CSR_OFFSET(CSR_TID, 0);
>> +    offset = CPU_CSR_OFFSET(CSR_TID, LOONGARCH_VM_LEVEL_HOST);
>This should be another small patch.
>
>Regards
>Bibo Mao
>>       tcg_gen_ld_i64(dst2, tcg_env, offset);
>>         return true;
>> diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc 
>> b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
>> index 6728ce5ec9..bcfc977990 100644
>> --- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
>> +++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
>> @@ -122,7 +122,7 @@ static bool trans_csrrd(DisasContext *ctx, arg_csrrd *a)
>>           if (readfn) {
>>               readfn(dest, tcg_env);
>>           } else {
>> -            offset = get_csr_offset(csr, 0);
>> +            offset = get_csr_offset(csr, LOONGARCH_VM_LEVEL_HOST);
>>               tcg_gen_ld_tl(dest, tcg_env, offset);
>>           }
>>       }
>> @@ -157,7 +157,7 @@ static bool trans_csrwr(DisasContext *ctx, arg_csrwr *a)
>>           writefn(dest, tcg_env, src1);
>>       } else {
>>           dest = tcg_temp_new();
>> -        offset = get_csr_offset(csr, 0);
>> +        offset = get_csr_offset(csr, LOONGARCH_VM_LEVEL_HOST);
>>           tcg_gen_ld_tl(dest, tcg_env, offset);
>>           tcg_gen_st_tl(src1, tcg_env, offset);
>>       }
>> @@ -196,7 +196,7 @@ static bool trans_csrxchg(DisasContext *ctx, arg_csrxchg 
>> *a)
>>       newv = tcg_temp_new();
>>       temp = tcg_temp_new();
>>   -    offset = get_csr_offset(csr, 0);
>> +    offset = get_csr_offset(csr, LOONGARCH_VM_LEVEL_HOST);
>>       tcg_gen_ld_tl(oldv, tcg_env, offset);
>>       tcg_gen_and_tl(newv, src1, mask);
>>       tcg_gen_andc_tl(temp, oldv, mask);
>> 
>



Reply via email to