On 2026/9/22 上午10:44, SignKirigami wrote:
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.
In loongarch_la464_init_csr(), if there is special requirement with guest mode. There should be code like this, keep others unchanged.
    CPUSysState *guest = get_sys(env, VM_LEVEL1);
    guest->CSR_ASID = FIELD_DP64(0, CSR_ASID, ASIDBITS, 0xa);

In loongarch_cpu_reset_hold(), vCPU may run in guest mode when system is resetting, here is to reset CSR registers in host mode. The piece of code should something like this:
    CPUSysState *sys = get_sys(env, VM_LEVEL0);

And then if you want to change variable name sys --> host, please use another separate patch.

Regards
Bibo Mao

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;














Reply via email to