@samitouri / QOSamiQemu / commits / 45e3ef638e

target/loongarch: Add some CPUCFG bits with host CPU model

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> Reviewed-by: Song Gao <gaosong@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn>

Bibo Mao committed Feb 25, 2026 at 09:41 UTC 45e3ef638e73799815a07a31041afe162d856dc3
2 files changed +43 -1
target/loongarch/cpu.c
+35 -1
@@ -532,7 +532,7 @@ static uint32_t get_host_cpucfg(int number)
532
533 static void loongarch_host_initfn(Object *obj)
534 {
535 - uint32_t data;
535 + uint32_t data, cpucfg, field;
536 uint64_t cpuid;
537 LoongArchCPU *cpu = LOONGARCH_CPU(obj);
538
@@ -542,6 +542,40 @@ static void loongarch_host_initfn(Object *obj)
542 cpu->env.cpucfg[0] = data;
543 }
544
545 + /*
546 + * There is no exception in KVM hypervisor when these intructions are
547 + * executed if HW support, KVM hypervisor cannot control this.
548 + *
549 + * Set cpucfg bits which cannot be controlled by KVM hypervisor.
550 + */
551 + data = get_host_cpucfg(2);
552 + cpucfg = cpu->env.cpucfg[2];
553 + field = FIELD_EX32(data, CPUCFG2, FRECIPE);
554 + cpucfg = FIELD_DP32(cpucfg, CPUCFG2, FRECIPE, field);
555 + field = FIELD_EX32(data, CPUCFG2, DIV32);
556 + cpucfg = FIELD_DP32(cpucfg, CPUCFG2, DIV32, field);
557 + field = FIELD_EX32(data, CPUCFG2, LAM_BH);
558 + cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAM_BH, field);
559 + field = FIELD_EX32(data, CPUCFG2, LAMCAS);
560 + cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LAMCAS, field);
561 + field = FIELD_EX32(data, CPUCFG2, LLACQ_SCREL);
562 + cpucfg = FIELD_DP32(cpucfg, CPUCFG2, LLACQ_SCREL, field);
563 + field = FIELD_EX32(data, CPUCFG2, SCQ);
564 + cpucfg = FIELD_DP32(cpucfg, CPUCFG2, SCQ, field);
565 + cpu->env.cpucfg[2] = cpucfg;
566 +
567 + data = get_host_cpucfg(3);
568 + cpucfg = cpu->env.cpucfg[3];
569 + field = FIELD_EX32(data, CPUCFG3, DBAR_HINTS);
570 + cpucfg = FIELD_DP32(cpucfg, CPUCFG3, DBAR_HINTS, field);
571 + field = FIELD_EX32(data, CPUCFG3, ALDORDER_STA);
572 + cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ALDORDER_STA, field);
573 + field = FIELD_EX32(data, CPUCFG3, ASTORDER_STA);
574 + cpucfg = FIELD_DP32(cpucfg, CPUCFG3, ASTORDER_STA, field);
575 + field = FIELD_EX32(data, CPUCFG3, SLDORDER_STA);
576 + cpucfg = FIELD_DP32(cpucfg, CPUCFG3, SLDORDER_STA, field);
577 + cpu->env.cpucfg[3] = cpucfg;
578 +
579 cpuid = get_host_cpu_model();
580 if (cpuid) {
581 cpu->env.cpu_id = cpuid;
target/loongarch/cpu.h
+8
@@ -147,6 +147,7 @@ FIELD(CPUCFG2, LSPW, 21, 1)
147 FIELD(CPUCFG2, LAM, 22, 1)
148 FIELD(CPUCFG2, HPTW, 24, 1)
149 FIELD(CPUCFG2, FRECIPE, 25, 1)
150 +FIELD(CPUCFG2, DIV32, 26, 1)
151 FIELD(CPUCFG2, LAM_BH, 27, 1)
152 FIELD(CPUCFG2, LAMCAS, 28, 1)
153 FIELD(CPUCFG2, LLACQ_SCREL, 29, 1)
@@ -165,6 +166,13 @@ FIELD(CPUCFG3, SPW_LVL, 8, 3)
166 FIELD(CPUCFG3, SPW_HP_HF, 11, 1)
167 FIELD(CPUCFG3, RVA, 12, 1)
168 FIELD(CPUCFG3, RVAMAX, 13, 4)
169 +FIELD(CPUCFG3, DBAR_HINTS, 17, 1)
170 +FIELD(CPUCFG3, ALDORDER_CAP, 18, 1)
171 +FIELD(CPUCFG3, ASTORDER_CAP, 19, 1)
172 +FIELD(CPUCFG3, ALDORDER_STA, 20, 1)
173 +FIELD(CPUCFG3, ASTORDER_STA, 21, 1)
174 +FIELD(CPUCFG3, SLDORDER_CAP, 22, 1)
175 +FIELD(CPUCFG3, SLDORDER_STA, 23, 1)
176
177 /* cpucfg[4] bits */
178 FIELD(CPUCFG4, CC_FREQ, 0, 32)