@samitouri / QOSamiQemu / commits / e7aab4856d

target/loongarch: Add host CPU model in kvm mode

Host CPU model is basically the same with max CPU model, except Product ID and CPU model name. With host CPU model, Product ID comes from cpucfg0 and CPU model comes from /proc/cpuinfo. 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 e7aab4856dfb54e8cfc3a049e24dfd9761552282
1 file changed +94
target/loongarch/cpu.c
+94
@@ -458,6 +458,97 @@ static void loongarch_max_initfn(Object *obj)
458 }
459 }
460
461 +#if defined(CONFIG_KVM)
462 +static int read_cpuinfo(const char *field, char *value, int len)
463 +{
464 + FILE *f;
465 + int ret = -1;
466 + int field_len = strlen(field);
467 + char line[512];
468 +
469 + f = fopen("/proc/cpuinfo", "r");
470 + if (!f) {
471 + return -1;
472 + }
473 +
474 + do {
475 + if (!fgets(line, sizeof(line), f)) {
476 + break;
477 + }
478 + if (!strncmp(line, field, field_len)) {
479 + strncpy(value, line, len);
480 + ret = 0;
481 + break;
482 + }
483 + } while (*line);
484 +
485 + fclose(f);
486 +
487 + return ret;
488 +}
489 +
490 +static uint64_t get_host_cpu_model(void)
491 +{
492 + char line[512];
493 + char *ns;
494 + static uint64_t cpuid;
495 +
496 + if (cpuid) {
497 + return cpuid;
498 + }
499 +
500 + if (read_cpuinfo("Model Name", line, sizeof(line))) {
501 + return 0;
502 + }
503 +
504 + ns = strchr(line, ':');
505 + if (!ns) {
506 + return 0;
507 + }
508 +
509 + ns = strstr(ns, "Loongson-");
510 + if (!ns) {
511 + return 0;
512 + }
513 +
514 + ns += strlen("Loongson-");
515 + memccpy((void *)&cpuid, ns, 0, 8);
516 + return cpuid;
517 +}
518 +
519 +static uint32_t get_host_cpucfg(int number)
520 +{
521 + unsigned int data = 0;
522 +
523 +#ifdef __loongarch__
524 + asm volatile("cpucfg %[val], %[reg]"
525 + : [val] "=r" (data)
526 + : [reg] "r" (number)
527 + : "memory");
528 +#endif
529 +
530 + return data;
531 +}
532 +
533 +static void loongarch_host_initfn(Object *obj)
534 +{
535 + uint32_t data;
536 + uint64_t cpuid;
537 + LoongArchCPU *cpu = LOONGARCH_CPU(obj);
538 +
539 + loongarch_max_initfn(obj);
540 + data = get_host_cpucfg(0);
541 + if (data) {
542 + cpu->env.cpucfg[0] = data;
543 + }
544 +
545 + cpuid = get_host_cpu_model();
546 + if (cpuid) {
547 + cpu->env.cpu_id = cpuid;
548 + }
549 +}
550 +#endif
551 +
552 static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
553 {
554 uint8_t tlb_ps;
@@ -811,6 +902,9 @@ static const TypeInfo loongarch_cpu_type_infos[] = {
902 DEFINE_LOONGARCH_CPU_TYPE(64, "la464", loongarch_la464_initfn),
903 DEFINE_LOONGARCH_CPU_TYPE(32, "la132", loongarch_la132_initfn),
904 DEFINE_LOONGARCH_CPU_TYPE(64, "max", loongarch_max_initfn),
905 +#if defined(CONFIG_KVM)
906 + DEFINE_LOONGARCH_CPU_TYPE(64, "host", loongarch_host_initfn),
907 +#endif
908 };
909
910 DEFINE_TYPES(loongarch_cpu_type_infos)