[PATCH v5 5/5] target/loongarch: Add some CPUCFG bits with host CPU model

Bibo Mao posted 5 patches 1 month, 2 weeks ago
Maintainers: Song Gao <gaosong@loongson.cn>, Bibo Mao <maobibo@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>
[PATCH v5 5/5] target/loongarch: Add some CPUCFG bits with host CPU model
Posted by Bibo Mao 1 month, 2 weeks ago
Some CPUCFG capability bits depend on KVM host hypervsior and they
are detected on QEMU. However some CPUCFG bits are irrelative with
hypervsior, here these bits are checked from host machine and set
for VM with host CPU model.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 target/loongarch/cpu.c | 36 +++++++++++++++++++++++++++++++++++-
 target/loongarch/cpu.h |  8 ++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 37950456b4..8e8b10505d 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -532,7 +532,7 @@ static uint32_t get_host_cpucfg(int number)
 
 static void loongarch_host_initfn(Object *obj)
 {
-    uint32_t data;
+    uint32_t data, cpucfg, field;
     uint64_t cpuid;
     LoongArchCPU *cpu = LOONGARCH_CPU(obj);
 
@@ -542,6 +542,40 @@ static void loongarch_host_initfn(Object *obj)
         cpu->env.cpucfg[0] = data;
     }
 
+   /*
+    * There is no exception in KVM hypervisor when these intructions are
+    * executed if HW support, KVM hypervisor cannot control this.
+    *
+    * Set cpucfg bits which cannot be controlled by KVM hypervisor.
+    */
+    data = get_host_cpucfg(2);
+    cpucfg = cpu->env.cpucfg[2];
+    field = FIELD_EX32(data, CPUCFG2, FRECIPE);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, FRECIPE, field);
+    field = FIELD_EX32(data, CPUCFG2, DIV32);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, DIV32, field);
+    field = FIELD_EX32(data, CPUCFG2, LAM_BH);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAM_BH, field);
+    field = FIELD_EX32(data, CPUCFG2, LAMCAS);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAMCAS, field);
+    field = FIELD_EX32(data, CPUCFG2, LLACQ_SCREL);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LLACQ_SCREL, field);
+    field = FIELD_EX32(data, CPUCFG2, SCQ);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, SCQ, field);
+    cpu->env.cpucfg[2] = cpucfg;
+
+    data = get_host_cpucfg(3);
+    cpucfg = cpu->env.cpucfg[3];
+    field = FIELD_EX32(data, CPUCFG3, DBAR_HINTS);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, DBAR_HINTS, field);
+    field = FIELD_EX32(data, CPUCFG3, ALDORDER_STA);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ALDORDER_STA, field);
+    field = FIELD_EX32(data, CPUCFG3, ASTORDER_STA);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ASTORDER_STA, field);
+    field = FIELD_EX32(data, CPUCFG3, SLDORDER_STA);
+    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, SLDORDER_STA, field);
+    cpu->env.cpucfg[3] = cpucfg;
+
     cpuid = get_host_cpu_model();
     if (cpuid) {
         cpu->env.cpu_id = cpuid;
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index fda8577a24..d2dfdc8520 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -147,6 +147,7 @@ FIELD(CPUCFG2, LSPW, 21, 1)
 FIELD(CPUCFG2, LAM, 22, 1)
 FIELD(CPUCFG2, HPTW, 24, 1)
 FIELD(CPUCFG2, FRECIPE, 25, 1)
+FIELD(CPUCFG2, DIV32, 26, 1)
 FIELD(CPUCFG2, LAM_BH, 27, 1)
 FIELD(CPUCFG2, LAMCAS, 28, 1)
 FIELD(CPUCFG2, LLACQ_SCREL, 29, 1)
@@ -165,6 +166,13 @@ FIELD(CPUCFG3, SPW_LVL, 8, 3)
 FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
 FIELD(CPUCFG3, RVA, 12, 1)
 FIELD(CPUCFG3, RVAMAX, 13, 4)
+FIELD(CPUCFG3, DBAR_HINTS, 17, 1)
+FIELD(CPUCFG3, ALDORDER_CAP, 18, 1)
+FIELD(CPUCFG3, ASTORDER_CAP, 19, 1)
+FIELD(CPUCFG3, ALDORDER_STA, 20, 1)
+FIELD(CPUCFG3, ASTORDER_STA, 21, 1)
+FIELD(CPUCFG3, SLDORDER_CAP, 22, 1)
+FIELD(CPUCFG3, SLDORDER_STA, 23, 1)
 
 /* cpucfg[4] bits */
 FIELD(CPUCFG4, CC_FREQ, 0, 32)
-- 
2.39.3
Re: [PATCH v5 5/5] target/loongarch: Add some CPUCFG bits with host CPU model
Posted by gaosong 1 month, 1 week ago
在 2026/2/25 上午9:41, Bibo Mao 写道:
> Some CPUCFG capability bits depend on KVM host hypervsior and they
> are detected on QEMU. However some CPUCFG bits are irrelative with
> hypervsior, here these bits are checked from host machine and set
> for VM with host CPU model.
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
>   target/loongarch/cpu.c | 36 +++++++++++++++++++++++++++++++++++-
>   target/loongarch/cpu.h |  8 ++++++++
>   2 files changed, 43 insertions(+), 1 deletion(-)
Reviewed-by: Song Gao <gaosong@loongson.cn>

Thanks.
Song  Gao
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index 37950456b4..8e8b10505d 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -532,7 +532,7 @@ static uint32_t get_host_cpucfg(int number)
>   
>   static void loongarch_host_initfn(Object *obj)
>   {
> -    uint32_t data;
> +    uint32_t data, cpucfg, field;
>       uint64_t cpuid;
>       LoongArchCPU *cpu = LOONGARCH_CPU(obj);
>   
> @@ -542,6 +542,40 @@ static void loongarch_host_initfn(Object *obj)
>           cpu->env.cpucfg[0] = data;
>       }
>   
> +   /*
> +    * There is no exception in KVM hypervisor when these intructions are
> +    * executed if HW support, KVM hypervisor cannot control this.
> +    *
> +    * Set cpucfg bits which cannot be controlled by KVM hypervisor.
> +    */
> +    data = get_host_cpucfg(2);
> +    cpucfg = cpu->env.cpucfg[2];
> +    field = FIELD_EX32(data, CPUCFG2, FRECIPE);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, FRECIPE, field);
> +    field = FIELD_EX32(data, CPUCFG2, DIV32);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, DIV32, field);
> +    field = FIELD_EX32(data, CPUCFG2, LAM_BH);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAM_BH, field);
> +    field = FIELD_EX32(data, CPUCFG2, LAMCAS);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAMCAS, field);
> +    field = FIELD_EX32(data, CPUCFG2, LLACQ_SCREL);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LLACQ_SCREL, field);
> +    field = FIELD_EX32(data, CPUCFG2, SCQ);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG2, SCQ, field);
> +    cpu->env.cpucfg[2] = cpucfg;
> +
> +    data = get_host_cpucfg(3);
> +    cpucfg = cpu->env.cpucfg[3];
> +    field = FIELD_EX32(data, CPUCFG3, DBAR_HINTS);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, DBAR_HINTS, field);
> +    field = FIELD_EX32(data, CPUCFG3, ALDORDER_STA);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ALDORDER_STA, field);
> +    field = FIELD_EX32(data, CPUCFG3, ASTORDER_STA);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ASTORDER_STA, field);
> +    field = FIELD_EX32(data, CPUCFG3, SLDORDER_STA);
> +    cpucfg = FIELD_DP32(cpucfg, CPUCFG3, SLDORDER_STA, field);
> +    cpu->env.cpucfg[3] = cpucfg;
> +
>       cpuid = get_host_cpu_model();
>       if (cpuid) {
>           cpu->env.cpu_id = cpuid;
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index fda8577a24..d2dfdc8520 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -147,6 +147,7 @@ FIELD(CPUCFG2, LSPW, 21, 1)
>   FIELD(CPUCFG2, LAM, 22, 1)
>   FIELD(CPUCFG2, HPTW, 24, 1)
>   FIELD(CPUCFG2, FRECIPE, 25, 1)
> +FIELD(CPUCFG2, DIV32, 26, 1)
>   FIELD(CPUCFG2, LAM_BH, 27, 1)
>   FIELD(CPUCFG2, LAMCAS, 28, 1)
>   FIELD(CPUCFG2, LLACQ_SCREL, 29, 1)
> @@ -165,6 +166,13 @@ FIELD(CPUCFG3, SPW_LVL, 8, 3)
>   FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
>   FIELD(CPUCFG3, RVA, 12, 1)
>   FIELD(CPUCFG3, RVAMAX, 13, 4)
> +FIELD(CPUCFG3, DBAR_HINTS, 17, 1)
> +FIELD(CPUCFG3, ALDORDER_CAP, 18, 1)
> +FIELD(CPUCFG3, ASTORDER_CAP, 19, 1)
> +FIELD(CPUCFG3, ALDORDER_STA, 20, 1)
> +FIELD(CPUCFG3, ASTORDER_STA, 21, 1)
> +FIELD(CPUCFG3, SLDORDER_CAP, 22, 1)
> +FIELD(CPUCFG3, SLDORDER_STA, 23, 1)
>   
>   /* cpucfg[4] bits */
>   FIELD(CPUCFG4, CC_FREQ, 0, 32)