On 2026年9月22日星期二 中国标准时间 09:30:53,Bibo Mao wrote:
>
> On 2026/9/21 下午12:20, SignKirigami wrote:
> > On 2026年9月20日星期日 中国标准时间 11:40:37,Bibo Mao wrote:
> >>
> >> On 2026/9/20 上午10:43, SignKirigami wrote:
> >>> Add get_sys() to retrieve a CPUSysState by VM level. Use it to access
> >>> the host state in CPU initialization and reset paths, and name the
> >>> local pointer host to distinguish it from the currently selected state
> >>> returned by env_sys() or guest. There is no function change in this
> >>> patch.
> >>>
> >>> Signed-off-by: SignKirigami <[email protected]>
> >>> ---
> >>> This patch is a resend of [1], Sorry for wrongly handling Signed-off-by.
> >>>
> >>> [1]: https://lists.gnu.org/archive/html/qemu-devel/2026-09/msg05969.html
> >>>
> >>> target/loongarch/cpu.c | 45 +++++++++++++++++++++---------------------
> >>> target/loongarch/cpu.h | 5 +++++
> >>> 2 files changed, 27 insertions(+), 23 deletions(-)
> >>>
> >>> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> >>> index f22f64efb8..c71531c1cf 100644
> >>> --- a/target/loongarch/cpu.c
> >>> +++ b/target/loongarch/cpu.c
> >>> @@ -142,12 +142,12 @@ static void loongarch_la464_init_csr(DeviceState
> >>> *dev)
> >>> static bool initialized;
> >>> LoongArchCPU *cpu = LOONGARCH_CPU(dev);
> >>> CPULoongArchState *env = &cpu->env;
> >>> - CPUSysState *sys = env_sys(env);
> >>> + CPUSysState *host = get_sys(env, VM_LEVEL0);
> >> Why env_sys() need be replaced with get_sys() in CPU init stage?
> >>
> >> Regards
> >> Bibo Mao
> > It needs to be distinguished from CPUSysState* which is gotten from
> > VM_LEVEL1, and from current vm_level after LVZ is imported.
> By my understanding, with loongarch_la464_init_csr(), its default level
> is VM_LEVEL0 even if LVZ is supported. VMM hypervisor will set CSR
> registers when start VM. Is that right?
>
> With loongarch_cpu_reset_hold(), when vCPU is running in VM mode, there
> may be reset/shutdown request.
>
> Regards
> Bibo Mao
Sure, in loongarch_la464_init_csr(), the default level is VM_LEVEL0, and
env_sys()
is same as get_sys(VM_LEVEL0). Using host is to claim that host csrs are
initialized,
as there will be an initialization to guest CSR_ASID in this function. And I
think it will
make things more clear to use env_sys() for situation which vm_level may change.
Regards
SignKirigami
>
> > Regards
> > SignKirigami
> >>> int i, num;
> >>>
> >>> if (!initialized) {
> >>> initialized = true;
> >>> - num = FIELD_EX64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM);
> >>> + num = FIELD_EX64(host->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM);
> >>> for (i = num; i < 16; i++) {
> >>> set_csr_flag(LOONGARCH_CSR_SAVE(i), CSRFL_UNUSED);
> >>> }
> >>> @@ -300,7 +300,7 @@ static void loongarch_la464_initfn(Object *obj)
> >>> {
> >>> LoongArchCPU *cpu = LOONGARCH_CPU(obj);
> >>> CPULoongArchState *env = &cpu->env;
> >>> - CPUSysState *sys;
> >>> + CPUSysState *host = get_sys(env, VM_LEVEL0);
> >>> uint32_t data = 0, field;
> >>> int i;
> >>>
> >>> @@ -408,19 +408,18 @@ static void loongarch_la464_initfn(Object *obj)
> >>> data = FIELD_DP32(data, CPUCFG20, L3IU_SIZE, 6);
> >>> env->cpucfg[20] = data;
> >>>
> >>> - sys = env_sys(env);
> >>> - sys->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
> >>> + host->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);
> >>>
> >>> - sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, SAVE_NUM,
> >>> 8);
> >>> - sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1,
> >>> TIMER_BITS, 0x2f);
> >>> - sys->CSR_PRCFG1 = FIELD_DP64(sys->CSR_PRCFG1, CSR_PRCFG1, VSMAX, 7);
> >>> + host->CSR_PRCFG1 = FIELD_DP64(host->CSR_PRCFG1, CSR_PRCFG1,
> >>> SAVE_NUM, 8);
> >>> + host->CSR_PRCFG1 = FIELD_DP64(host->CSR_PRCFG1, CSR_PRCFG1,
> >>> TIMER_BITS, 0x2f);
> >>> + host->CSR_PRCFG1 = FIELD_DP64(host->CSR_PRCFG1, CSR_PRCFG1, VSMAX,
> >>> 7);
> >>>
> >>> - sys->CSR_PRCFG2 = 0x3ffff000;
> >>> + host->CSR_PRCFG2 = 0x3ffff000;
> >>>
> >>> - sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, TLB_TYPE,
> >>> 2);
> >>> - sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3,
> >>> MTLB_ENTRY, 63);
> >>> - sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS,
> >>> 7);
> >>> - sys->CSR_PRCFG3 = FIELD_DP64(sys->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS,
> >>> 8);
> >>> + host->CSR_PRCFG3 = FIELD_DP64(host->CSR_PRCFG3, CSR_PRCFG3,
> >>> TLB_TYPE, 2);
> >>> + host->CSR_PRCFG3 = FIELD_DP64(host->CSR_PRCFG3, CSR_PRCFG3,
> >>> MTLB_ENTRY, 63);
> >>> + host->CSR_PRCFG3 = FIELD_DP64(host->CSR_PRCFG3, CSR_PRCFG3,
> >>> STLB_WAYS, 7);
> >>> + host->CSR_PRCFG3 = FIELD_DP64(host->CSR_PRCFG3, CSR_PRCFG3,
> >>> STLB_SETS, 8);
> >>>
> >>> cpu->msgint = ON_OFF_AUTO_OFF;
> >>> cpu->ptw = ON_OFF_AUTO_OFF;
> >>> @@ -627,7 +626,7 @@ static void loongarch_cpu_reset_hold(Object *obj,
> >>> ResetType type)
> >>> CPUState *cs = CPU(obj);
> >>> LoongArchCPUClass *lacc = LOONGARCH_CPU_GET_CLASS(obj);
> >>> CPULoongArchState *env = cpu_env(cs);
> >>> - CPUSysState *sys = env_sys(env);
> >>> + CPUSysState *host = get_sys(env, VM_LEVEL0);
> >>>
> >>> if (lacc->parent_phases.hold) {
> >>> lacc->parent_phases.hold(obj, type);
> >>> @@ -638,7 +637,7 @@ static void loongarch_cpu_reset_hold(Object *obj,
> >>> ResetType type)
> >>> * its value is equal to zero for boot cpu, it causes reboot issue.
> >>> */
> >>> memset(env, 0, offsetof(CPULoongArchState, end_reset_fields));
> >>> - memset(sys, 0, offsetof(CPUSysState, end_reset_fields));
> >>> + memset(host, 0, offsetof(CPUSysState, end_reset_fields));
> >>>
> >>> #ifdef CONFIG_TCG
> >>> env->fcsr0_mask = FCSR0_M1 | FCSR0_M2 | FCSR0_M3;
> >>> @@ -655,17 +654,17 @@ static void loongarch_cpu_reset_hold(Object *obj,
> >>> ResetType type)
> >>> }
> >>> #endif
> >>>
> >>> - sys->CSR_CRMD = FIELD_DP64(sys->CSR_CRMD, CSR_CRMD, DA, 1);
> >>> - sys->CSR_CPUID = cs->cpu_index;
> >>> - sys->CSR_TID = cs->cpu_index;
> >>> + host->CSR_CRMD = FIELD_DP64(host->CSR_CRMD, CSR_CRMD, DA, 1);
> >>> + host->CSR_CPUID = cs->cpu_index;
> >>> + host->CSR_TID = cs->cpu_index;
> >>>
> >>> /* set CSR_PWCL.PTBASE and CSR_STLBPS.PS bits from CSR_PRCFG2 */
> >>> - if (sys->CSR_PRCFG2 == 0) {
> >>> - sys->CSR_PRCFG2 = 0x3fffff000;
> >>> + if (host->CSR_PRCFG2 == 0) {
> >>> + host->CSR_PRCFG2 = 0x3fffff000;
> >>> }
> >>> - tlb_ps = ctz32(sys->CSR_PRCFG2);
> >>> - sys->CSR_STLBPS = FIELD_DP64(sys->CSR_STLBPS, CSR_STLBPS, PS,
> >>> tlb_ps);
> >>> - sys->CSR_PWCL = FIELD_DP64(sys->CSR_PWCL, CSR_PWCL, PTBASE, tlb_ps);
> >>> + tlb_ps = ctz32(host->CSR_PRCFG2);
> >>> + host->CSR_STLBPS = FIELD_DP64(host->CSR_STLBPS, CSR_STLBPS, PS,
> >>> tlb_ps);
> >>> + host->CSR_PWCL = FIELD_DP64(host->CSR_PWCL, CSR_PWCL, PTBASE,
> >>> tlb_ps);
> >>>
> >>> #ifndef CONFIG_USER_ONLY
> >>> env->pc = 0x1c000000;
> >>> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> >>> index c592f69885..477a5dee7d 100644
> >>> --- a/target/loongarch/cpu.h
> >>> +++ b/target/loongarch/cpu.h
> >>> @@ -512,6 +512,11 @@ static inline void set_sys_state(CPULoongArchState
> >>> *env, CPUSysState *sys)
> >>> env->sys_state = sys;
> >>> }
> >>>
> >>> +static inline CPUSysState *get_sys(CPULoongArchState *env, int vm_level)
> >>> +{
> >>> + return &env->sys_states[vm_level];
> >>> +}
> >>> +
> >>> static inline CPUTimerState *env_timer(CPULoongArchState *env)
> >>> {
> >>> return &env->sys_states[0].timer_state;
> >>>
> >>
> >>
> >
> >
> >
>
>