From nobody Sat Oct 24 20:22:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1791602168668627.9293282380644; Fri, 9 Oct 2026 20:16:08 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 074F941BE3; Fri, 9 Oct 2026 23:16:06 -0400 (EDT) Received: from [172.19.199.16] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 92C0A41B3D; Fri, 9 Oct 2026 23:14:51 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id BBE99418F1; Fri, 9 Oct 2026 23:14:35 -0400 (EDT) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lists.libvirt.org (Postfix) with ESMTP id 42AD0418A6 for ; Fri, 9 Oct 2026 23:14:32 -0400 (EDT) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxPtMZrclqCl8UAA--.59326S3; Sat, 10 Oct 2026 11:12:25 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by front1 (Coremail) with SMTP id qMiowJBxrM4XrclqzLYqAA--.61946S3; Sat, 10 Oct 2026 11:12:25 +0800 (CST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 From: Xianglai Li To: devel@lists.libvirt.org, lixianglai@loongson.cn Subject: [PATCH 1/6] cpu_map: add LoongArch CPU map XML files Date: Sat, 10 Oct 2026 10:52:13 +0800 Message-Id: <20261010025218.2102264-2-lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20261010025218.2102264-1-lixianglai@loongson.cn> References: <20261010025218.2102264-1-lixianglai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxrM4XrclqzLYqAA--.61946S3 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Message-ID-Hash: OOEUA23HDIRPWE6ITZK6K7ZIZQRBXYKS X-Message-ID-Hash: OOEUA23HDIRPWE6ITZK6K7ZIZQRBXYKS X-MailFrom: lixianglai@loongson.cn X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Bibo Mao X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZM-MESSAGEID: 1791602171329158500 Content-Type: text/plain; charset="utf-8" Add CPU map XML files for the LoongArch architecture, describing the Loongson vendor, supported features, and the la464/la664 CPU models. The following files are added: - loongarch_vendors.xml: Loongson vendor (0x14) - loongarch_features.xml: lbt, lasx, lsx, ptw, pmu, msgint, kvm-pv-ipi, kvm-steal-time - loongarch_la464.xml: Loongson 3A5000 (la464) model - loongarch_la664.xml: Loongson 3A6000 (la664) model index.xml and meson.build are updated to include the new files. Signed-off-by: Xianglai Li --- Cc: Bibo Mao src/cpu_map/index.xml | 13 +++++++++++++ src/cpu_map/loongarch_features.xml | 26 ++++++++++++++++++++++++++ src/cpu_map/loongarch_la464.xml | 10 ++++++++++ src/cpu_map/loongarch_la664.xml | 11 +++++++++++ src/cpu_map/loongarch_vendors.xml | 3 +++ src/cpu_map/meson.build | 4 ++++ 6 files changed, 67 insertions(+) create mode 100644 src/cpu_map/loongarch_features.xml create mode 100644 src/cpu_map/loongarch_la464.xml create mode 100644 src/cpu_map/loongarch_la664.xml create mode 100644 src/cpu_map/loongarch_vendors.xml diff --git a/src/cpu_map/index.xml b/src/cpu_map/index.xml index 50b5cc7ed9..e4de295203 100644 --- a/src/cpu_map/index.xml +++ b/src/cpu_map/index.xml @@ -259,4 +259,17 @@ + + + + + + + + + + + + + diff --git a/src/cpu_map/loongarch_features.xml b/src/cpu_map/loongarch_fea= tures.xml new file mode 100644 index 0000000000..b86721d27d --- /dev/null +++ b/src/cpu_map/loongarch_features.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/cpu_map/loongarch_la464.xml b/src/cpu_map/loongarch_la464.= xml new file mode 100644 index 0000000000..df75222d78 --- /dev/null +++ b/src/cpu_map/loongarch_la464.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/cpu_map/loongarch_la664.xml b/src/cpu_map/loongarch_la664.= xml new file mode 100644 index 0000000000..7cf8c8fb06 --- /dev/null +++ b/src/cpu_map/loongarch_la664.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/cpu_map/loongarch_vendors.xml b/src/cpu_map/loongarch_vend= ors.xml new file mode 100644 index 0000000000..d40d2d7e51 --- /dev/null +++ b/src/cpu_map/loongarch_vendors.xml @@ -0,0 +1,3 @@ + + + diff --git a/src/cpu_map/meson.build b/src/cpu_map/meson.build index fd5d2596ec..3a707c1ff1 100644 --- a/src/cpu_map/meson.build +++ b/src/cpu_map/meson.build @@ -17,6 +17,10 @@ cpumap_data =3D [ 'arm_ThunderX299xx.xml', 'arm_vendors.xml', 'index.xml', + 'loongarch_features.xml', + 'loongarch_la464.xml', + 'loongarch_la664.xml', + 'loongarch_vendors.xml', 'ppc64_POWER10.xml', 'ppc64_POWER11.xml', 'ppc64_POWER6.xml', --=20 2.39.1 From nobody Sat Oct 24 20:22:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 17916022708600.21684716076674704; Fri, 9 Oct 2026 20:17:50 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id AA2E94191B; Fri, 9 Oct 2026 23:17:49 -0400 (EDT) Received: from [172.19.199.16] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 98AA141999; Fri, 9 Oct 2026 23:14:57 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 257F7418A9; Fri, 9 Oct 2026 23:14:36 -0400 (EDT) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by lists.libvirt.org (Postfix) with ESMTP id 4103E4189B for ; Fri, 9 Oct 2026 23:14:32 -0400 (EDT) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8DxUNEdrclqC18UAA--.59294S3; Sat, 10 Oct 2026 11:12:29 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by front1 (Coremail) with SMTP id qMiowJBxrM4XrclqzLYqAA--.61946S4; Sat, 10 Oct 2026 11:12:25 +0800 (CST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 117 seconds by postgrey-1.37 at lists.libvirt.org; Fri, 09 Oct 2026 23:14:33 EDT From: Xianglai Li To: devel@lists.libvirt.org, lixianglai@loongson.cn Subject: [PATCH 2/6] cpu: add LoongArch CPU vendor parsing Date: Sat, 10 Oct 2026 10:52:14 +0800 Message-Id: <20261010025218.2102264-3-lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20261010025218.2102264-1-lixianglai@loongson.cn> References: <20261010025218.2102264-1-lixianglai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxrM4XrclqzLYqAA--.61946S4 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Message-ID-Hash: V53XNJDID3B6LDIYSATGZMCMSWEY3PH3 X-Message-ID-Hash: V53XNJDID3B6LDIYSATGZMCMSWEY3PH3 X-MailFrom: lixianglai@loongson.cn X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Bibo Mao X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZM-MESSAGEID: 1791602275943158500 Content-Type: text/plain; charset="utf-8" Add parsing of LoongArch CPU vendors from the CPU map XML files. This introduces the virCPULoongArchData structure, the CPU map container, vendor lookup helpers. Add memory management for the CPU map and vendor objects, register src/cpu/cpu_loongarch.c in po/POTFILES for translation, and provide a stub decode callback so the driver can be registered. Signed-off-by: Xianglai Li --- Cc: Bibo Mao po/POTFILES | 1 + src/cpu/cpu.h | 2 + src/cpu/cpu_loongarch.c | 163 ++++++++++++++++++++++++++++++++++- src/cpu/cpu_loongarch_data.h | 34 ++++++++ 4 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/cpu/cpu_loongarch_data.h diff --git a/po/POTFILES b/po/POTFILES index 3812d6af88..504d5c28bd 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -74,6 +74,7 @@ src/conf/virsecretobj.c src/conf/virstorageobj.c src/cpu/cpu.c src/cpu/cpu_arm.c +src/cpu/cpu_loongarch.c src/cpu/cpu_map.c src/cpu/cpu_ppc64.c src/cpu/cpu_riscv64.c diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 65711ac085..08b49ccefa 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -27,6 +27,7 @@ #include "cpu_x86_data.h" #include "cpu_ppc64_data.h" #include "cpu_arm_data.h" +#include "cpu_loongarch_data.h" =20 =20 typedef struct _virCPUData virCPUData; @@ -36,6 +37,7 @@ struct _virCPUData { virCPUx86Data x86; virCPUppc64Data ppc64; virCPUarmData arm; + virCPULoongArchData loongarch; /* generic driver needs no data */ } data; }; diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c index 0e2b0b5848..d1ed447881 100644 --- a/src/cpu/cpu_loongarch.c +++ b/src/cpu/cpu_loongarch.c @@ -21,12 +21,30 @@ #include #include "virlog.h" #include "cpu.h" +#include "viralloc.h" +#include "cpu_map.h" =20 #define VIR_FROM_THIS VIR_FROM_CPU =20 VIR_LOG_INIT("cpu.cpu_loongarch"); =20 +typedef struct _virCPULoongArchVendor virCPULoongArchVendor; +struct _virCPULoongArchVendor { + char *name; + uint32_t value; +}; + +typedef struct _virCPULoongArchMap virCPULoongArchMap; +struct _virCPULoongArchMap { + size_t nvendors; + virCPULoongArchVendor **vendors; +}; + static const virArch archs[] =3D { VIR_ARCH_LOONGARCH64 }; +static virCPULoongArchMap *cpuMap; + +int virCPULoongArchDriverOnceInit(void); +VIR_ONCE_GLOBAL_INIT(virCPULoongArchDriver); =20 static virCPUCompareResult virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED, @@ -36,6 +54,149 @@ virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED, return VIR_CPU_COMPARE_IDENTICAL; } =20 +static void +virCPULoongArchVendorFree(virCPULoongArchVendor *vendor) +{ + if (!vendor) + return; + + g_free(vendor->name); + g_free(vendor); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchVendor, virCPULoongArchVendor= Free); + +static virCPULoongArchMap * +virCPULoongArchMapNew(void) +{ + virCPULoongArchMap *map; + + map =3D g_new0(virCPULoongArchMap, 1); + + return map; +} + +static void +virCPULoongArchMapFree(virCPULoongArchMap *map) +{ + size_t i; + + if (!map) + return; + + for (i =3D 0; i < map->nvendors; i++) + virCPULoongArchVendorFree(map->vendors[i]); + g_free(map->vendors); + g_free(map); +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchMap, virCPULoongArchMapFree); + +static virCPULoongArchVendor * +virCPULoongArchVendorFindByName(virCPULoongArchMap *map, + const char *name) +{ + size_t i; + + for (i =3D 0; i < map->nvendors; i++) { + if (STREQ(map->vendors[i]->name, name)) + return map->vendors[i]; + } + + return NULL; +} + +static virCPULoongArchVendor * +virCPULoongArchVendorFindByID(virCPULoongArchMap *map, + uint32_t vendor_id) +{ + size_t i; + + for (i =3D 0; i < map->nvendors; i++) { + if (map->vendors[i]->value =3D=3D vendor_id) + return map->vendors[i]; + } + + return NULL; +} + +static int +virCPULoongArchMapVendorParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPULoongArchMap *map =3D data; + g_autoptr(virCPULoongArchVendor) vendor =3D NULL; + + vendor =3D g_new0(virCPULoongArchVendor, 1); + vendor->name =3D g_strdup(name); + + if (virCPULoongArchVendorFindByName(map, vendor->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor %1$s already defined"), + vendor->name); + return -1; + } + + if (virXMLPropUInt(ctxt->node, "value", 16, VIR_XML_PROP_REQUIRED, + &vendor->value) < 0) + return -1; + + if (virCPULoongArchVendorFindByID(map, vendor->value)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU vendor value 0x%1$2x already defined"), + vendor->value); + return -1; + } + + VIR_APPEND_ELEMENT(map->vendors, map->nvendors, vendor); + return 0; +} + +static virCPULoongArchMap * +virCPULoongArchLoadMap(void) +{ + g_autoptr(virCPULoongArchMap) map =3D NULL; + + map =3D virCPULoongArchMapNew(); + + if (cpuMapLoad("loongarch", virCPULoongArchMapVendorParse, + NULL, NULL, map) < 0) + return NULL; + + return g_steal_pointer(&map); +} + +static virCPULoongArchMap * +virCPULoongArchGetMap(void) +{ + if (virCPULoongArchDriverInitialize() < 0) + return NULL; + + return cpuMap; +} + +int +virCPULoongArchDriverOnceInit(void) +{ + if (!(cpuMap =3D virCPULoongArchLoadMap())) + return -1; + + return 0; +} + +static int +virCPULoongArchDriverDecode(virCPUDef *cpu G_GNUC_UNUSED, + const virCPUData *cpuData, + virDomainCapsCPUModels *models G_GNUC_UNUSED) +{ + virCPULoongArchMap *map =3D NULL; + + if (!cpuData || !(map =3D virCPULoongArchGetMap())) + return -1; + + return 0; +} + static int virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED, const virCPUDef *host G_GNUC_UNUSED, @@ -50,7 +211,7 @@ struct cpuArchDriver cpuDriverLoongArch =3D { .arch =3D archs, .narch =3D G_N_ELEMENTS(archs), .compare =3D virCPULoongArchCompare, - .decode =3D NULL, + .decode =3D virCPULoongArchDriverDecode, .encode =3D NULL, .dataFree =3D NULL, .baseline =3D NULL, diff --git a/src/cpu/cpu_loongarch_data.h b/src/cpu/cpu_loongarch_data.h new file mode 100644 index 0000000000..673a4b37e6 --- /dev/null +++ b/src/cpu/cpu_loongarch_data.h @@ -0,0 +1,34 @@ +/* + * cpu_loongarch_data.h: 64-bit LoongArch CPU specific data + * + * Copyright (C) 2026 LOONGSON Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; If not, see + * . + */ + +#pragma once + +typedef struct _virCPULoongArchFeature virCPULoongArchFeature; +struct _virCPULoongArchFeature { + char *name; + uint32_t index; + uint32_t value; + int policy; /* enum virCPUFeaturePolicy */ +}; + +typedef struct _virCPULoongArchData virCPULoongArchData; +struct _virCPULoongArchData { + GPtrArray *features; +}; --=20 2.39.1 From nobody Sat Oct 24 20:22:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1791602693770398.8627537151673; Fri, 9 Oct 2026 20:24:53 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 41D0C41A03; Fri, 9 Oct 2026 23:24:52 -0400 (EDT) Received: from [172.19.199.16] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 998DD41B35; Fri, 9 Oct 2026 23:23:25 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 080884189B; Fri, 9 Oct 2026 23:23:13 -0400 (EDT) Received: from mx22.osci.io (francine.osci.io [IPv6:2620:52:6:3141:1::4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id DA562419C0 for ; Fri, 9 Oct 2026 23:20:14 -0400 (EDT) Received: by mx22.osci.io (Postfix, from userid 993) id 0AD006460E; Fri, 9 Oct 2026 23:14:35 -0400 (EDT) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx22.osci.io (Postfix) with ESMTP id F079C64660 for ; Fri, 9 Oct 2026 23:14:32 -0400 (EDT) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8DxTtMdrclqDF8UAA--.58964S3; Sat, 10 Oct 2026 11:12:29 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by front1 (Coremail) with SMTP id qMiowJBxrM4XrclqzLYqAA--.61946S5; Sat, 10 Oct 2026 11:12:29 +0800 (CST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 339 seconds by postgrey-1.37 at lists.libvirt.org; Fri, 09 Oct 2026 23:20:14 EDT X-Greylist: delayed 116 seconds by postgrey-1.37 at francine.osci.io; Fri, 09 Oct 2026 23:14:32 EDT From: Xianglai Li To: devel@lists.libvirt.org, lixianglai@loongson.cn Subject: [PATCH 3/6] cpu: add LoongArch CPU feature parsing Date: Sat, 10 Oct 2026 10:52:15 +0800 Message-Id: <20261010025218.2102264-4-lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20261010025218.2102264-1-lixianglai@loongson.cn> References: <20261010025218.2102264-1-lixianglai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxrM4XrclqzLYqAA--.61946S5 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Message-ID-Hash: XJ7XXLA72KI6U77CVK542JVRYL53LP4A X-Message-ID-Hash: XJ7XXLA72KI6U77CVK542JVRYL53LP4A X-MailFrom: lixianglai@loongson.cn X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Bibo Mao X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZM-MESSAGEID: 1791602694423158500 Content-Type: text/plain; charset="utf-8" Add parsing of LoongArch CPU features from the CPU map XML files. Each feature is described by a CPUCFG register index and a value. Feature lookup by name is also added. The feature parsing callback is now passed to cpuMapLoad(). Signed-off-by: Xianglai Li --- Cc: Bibo Mao src/cpu/cpu_loongarch.c | 92 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c index d1ed447881..7d63630615 100644 --- a/src/cpu/cpu_loongarch.c +++ b/src/cpu/cpu_loongarch.c @@ -38,6 +38,7 @@ typedef struct _virCPULoongArchMap virCPULoongArchMap; struct _virCPULoongArchMap { size_t nvendors; virCPULoongArchVendor **vendors; + virCPULoongArchData data; }; =20 static const virArch archs[] =3D { VIR_ARCH_LOONGARCH64 }; @@ -54,6 +55,25 @@ virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED, return VIR_CPU_COMPARE_IDENTICAL; } =20 +static virCPULoongArchFeature * +virCPULoongArchFeatureNew(void) +{ + return g_new0(virCPULoongArchFeature, 1); +} + +static void +virCPULoongArchFeatureFree(virCPULoongArchFeature *feature) +{ + if (!feature) + return; + + g_free(feature->name); + g_free(feature); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchFeature, + virCPULoongArchFeatureFree); + static void virCPULoongArchVendorFree(virCPULoongArchVendor *vendor) { @@ -72,7 +92,9 @@ virCPULoongArchMapNew(void) virCPULoongArchMap *map; =20 map =3D g_new0(virCPULoongArchMap, 1); - + map->data.features =3D g_ptr_array_new(); + g_ptr_array_set_free_func(map->data.features, + (GDestroyNotify) virCPULoongArchFeatureFree); return map; } =20 @@ -87,10 +109,28 @@ virCPULoongArchMapFree(virCPULoongArchMap *map) for (i =3D 0; i < map->nvendors; i++) virCPULoongArchVendorFree(map->vendors[i]); g_free(map->vendors); + g_ptr_array_free(map->data.features, TRUE); g_free(map); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchMap, virCPULoongArchMapFree); =20 +static virCPULoongArchFeature * +virCPULoongArchMapFeatureFindByName(virCPULoongArchMap *map, + const char *name) +{ + size_t i; + virCPULoongArchFeature *feature; + + for (i =3D 0; i < map->data.features->len; i++) { + feature =3D g_ptr_array_index(map->data.features, i); + if (STREQ(feature->name, name)) + return feature; + } + + return NULL; +} + + static virCPULoongArchVendor * virCPULoongArchVendorFindByName(virCPULoongArchMap *map, const char *name) @@ -119,6 +159,53 @@ virCPULoongArchVendorFindByID(virCPULoongArchMap *map, return NULL; } =20 +static int +virCPULoongArchMapCpucfgParse(xmlNodePtr node, + virCPULoongArchFeature *feature) +{ + if (virXMLPropUInt(node, "index", 16, VIR_XML_PROP_REQUIRED, + &feature->index) < 0) + return -1; + if (virXMLPropUInt(node, "value", 16, VIR_XML_PROP_REQUIRED, + &feature->value) < 0) + return -1; + + return 0; +} + +static int +virCPULoongArchMapFeatureParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + g_autoptr(virCPULoongArchFeature) feature =3D NULL; + virCPULoongArchMap *map =3D data; + xmlNodePtr node; + + if (virCPULoongArchMapFeatureFindByName(map, name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU feature %1$s already defined"), name); + return -1; + } + + feature =3D virCPULoongArchFeatureNew(); + feature->name =3D g_strdup(name); + + node =3D xmlFirstElementChild(ctxt->node); + if (node) { + if (virXMLNodeNameEqual(node, "cpucfg")) { + if (virCPULoongArchMapCpucfgParse(node, feature) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Invalid cpucfg")); + return -1; + } + } + } + + g_ptr_array_add(map->data.features, g_steal_pointer(&feature)); + return 0; +} + static int virCPULoongArchMapVendorParse(xmlXPathContextPtr ctxt, const char *name, @@ -160,7 +247,8 @@ virCPULoongArchLoadMap(void) map =3D virCPULoongArchMapNew(); =20 if (cpuMapLoad("loongarch", virCPULoongArchMapVendorParse, - NULL, NULL, map) < 0) + virCPULoongArchMapFeatureParse, + NULL, map) < 0) return NULL; =20 return g_steal_pointer(&map); --=20 2.39.1 From nobody Sat Oct 24 20:22:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1791602863477289.46046905260846; Fri, 9 Oct 2026 20:27:43 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 2AA123F942; Fri, 9 Oct 2026 23:27:42 -0400 (EDT) Received: from [172.19.199.16] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 70CC341B49; Fri, 9 Oct 2026 23:26:10 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id E2228418F1; Fri, 9 Oct 2026 23:26:01 -0400 (EDT) Received: from mx3.osci.io (carla.osci.io [IPv6:2600:1f14:21ef:6900::4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 17094419ED for ; Fri, 9 Oct 2026 23:24:20 -0400 (EDT) Received: by mx3.osci.io (Postfix, from userid 991) id 02CDA8D665F; Sat, 10 Oct 2026 03:14:34 +0000 (UTC) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx3.osci.io (Postfix) with ESMTP id 566D18D666D for ; Sat, 10 Oct 2026 03:14:32 +0000 (UTC) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxutEerclqDV8UAA--.59528S3; Sat, 10 Oct 2026 11:12:30 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by front1 (Coremail) with SMTP id qMiowJBxrM4XrclqzLYqAA--.61946S6; Sat, 10 Oct 2026 11:12:29 +0800 (CST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 585 seconds by postgrey-1.37 at lists.libvirt.org; Fri, 09 Oct 2026 23:24:20 EDT X-Greylist: delayed 115 seconds by postgrey-1.37 at carla.osci.io; Sat, 10 Oct 2026 03:14:32 UTC From: Xianglai Li To: devel@lists.libvirt.org, lixianglai@loongson.cn Subject: [PATCH 4/6] cpu: add LoongArch CPU model parsing Date: Sat, 10 Oct 2026 10:52:16 +0800 Message-Id: <20261010025218.2102264-5-lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20261010025218.2102264-1-lixianglai@loongson.cn> References: <20261010025218.2102264-1-lixianglai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxrM4XrclqzLYqAA--.61946S6 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Message-ID-Hash: LG74AFOPLQNF56A4DN3PD65U4JGXIZOD X-Message-ID-Hash: LG74AFOPLQNF56A4DN3PD65U4JGXIZOD X-MailFrom: lixianglai@loongson.cn X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Bibo Mao X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZM-MESSAGEID: 1791602863900158500 Content-Type: text/plain; charset="utf-8" Add parsing of LoongArch CPU models from the CPU map XML files. A model references a vendor and a list of features. Each feature may either reference a predefined feature or specify its own CPUCFG index and value. Model lookup by name and the model free function are also added. The model parsing callback is now passed to cpuMapLoad(). Signed-off-by: Xianglai Li --- Cc: Bibo Mao src/cpu/cpu_loongarch.c | 147 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c index 7d63630615..3cce682349 100644 --- a/src/cpu/cpu_loongarch.c +++ b/src/cpu/cpu_loongarch.c @@ -34,10 +34,19 @@ struct _virCPULoongArchVendor { uint32_t value; }; =20 +typedef struct _virCPULoongArchModel virCPULoongArchModel; +struct _virCPULoongArchModel { + char *name; + virCPULoongArchVendor *vendor; + virCPULoongArchData data; +}; + typedef struct _virCPULoongArchMap virCPULoongArchMap; struct _virCPULoongArchMap { size_t nvendors; virCPULoongArchVendor **vendors; + size_t nmodels; + virCPULoongArchModel **models; virCPULoongArchData data; }; =20 @@ -55,6 +64,25 @@ virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED, return VIR_CPU_COMPARE_IDENTICAL; } =20 +static void +virCPULoongArchDataClear(virCPULoongArchData *data) +{ + if (!data) + return; + + g_clear_pointer(&data->features, g_ptr_array_unref); +} + +static void +virCPULoongArchDataFree(virCPUData *data) +{ + if (!data) + return; + + virCPULoongArchDataClear(&data->data.loongarch); + g_free(data); +} + static virCPULoongArchFeature * virCPULoongArchFeatureNew(void) { @@ -86,6 +114,18 @@ virCPULoongArchVendorFree(virCPULoongArchVendor *vendor) =20 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchVendor, virCPULoongArchVendor= Free); =20 +static void +virCPULoongArchModelFree(virCPULoongArchModel *model) +{ + if (!model) + return; + + virCPULoongArchDataClear(&model->data); + g_free(model->name); + g_free(model); +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchModel, virCPULoongArchModelFr= ee); + static virCPULoongArchMap * virCPULoongArchMapNew(void) { @@ -106,6 +146,10 @@ virCPULoongArchMapFree(virCPULoongArchMap *map) if (!map) return; =20 + for (i =3D 0; i < map->nmodels; i++) + virCPULoongArchModelFree(map->models[i]); + g_free(map->models); + for (i =3D 0; i < map->nvendors; i++) virCPULoongArchVendorFree(map->vendors[i]); g_free(map->vendors); @@ -130,6 +174,19 @@ virCPULoongArchMapFeatureFindByName(virCPULoongArchMap= *map, return NULL; } =20 +static virCPULoongArchModel * +virCPULoongArchModelFindByName(virCPULoongArchMap *map, + const char *name) +{ + size_t i; + + for (i =3D 0; i < map->nmodels; i++) { + if (STREQ(map->models[i]->name, name)) + return map->models[i]; + } + + return NULL; +} =20 static virCPULoongArchVendor * virCPULoongArchVendorFindByName(virCPULoongArchMap *map, @@ -206,6 +263,92 @@ virCPULoongArchMapFeatureParse(xmlXPathContextPtr ctxt, return 0; } =20 +static int +virCPULoongArchMapModelParse(xmlXPathContextPtr ctxt, + const char *name, + void *data) +{ + virCPULoongArchMap *map =3D data; + g_autoptr(virCPULoongArchModel) model =3D NULL; + xmlNodePtr vendorNode =3D NULL; + g_autofree xmlNodePtr *nodes =3D NULL; + size_t i; + int n; + + model =3D g_new0(virCPULoongArchModel, 1); + model->name =3D g_strdup(name); + + if (virCPULoongArchModelFindByName(map, model->name)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("CPU model %1$s already defined"), + model->name); + return -1; + } + + if ((vendorNode =3D virXPathNode("./vendor", ctxt))) { + g_autofree char *vendor =3D NULL; + + if (!(vendor =3D virXMLPropStringRequired(vendorNode, "name"))) + return -1; + + if (!(model->vendor =3D virCPULoongArchVendorFindByName(map, vendo= r))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unknown vendor %1$s referenced by CPU model %2$= s"), + vendor, model->name); + return -1; + } + } + + if ((n =3D virXPathNodeSet("./feature", ctxt, &nodes)) < 0) + return -1; + + if (n =3D=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing feature information for CPU model %1$s"), + model->name); + return -1; + } + + model->data.features =3D g_ptr_array_new(); + g_ptr_array_set_free_func(model->data.features, + (GDestroyNotify) virCPULoongArchFeatureFree); + + for (i =3D 0; i < n; i++) { + g_autoptr(virCPULoongArchFeature) feature =3D NULL; + virCPULoongArchFeature *found; + g_autofree char *ftname =3D NULL; + xmlNodePtr node =3D nodes[i]; + xmlNodePtr child; + + if (!(ftname =3D virXMLPropString(node, "name"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Missing feature name for CPU model %1$s"), + model->name); + return -1; + } + + feature =3D virCPULoongArchFeatureNew(); + feature->name =3D g_strdup(ftname); + + if ((found =3D virCPULoongArchMapFeatureFindByName(map, ftname))) { + feature->index =3D found->index; + feature->value =3D found->value; + } else if ((child =3D xmlFirstElementChild(node))) { + virCPULoongArchFeature cpucfg; + if (virXMLNodeNameEqual(child, "cpucfg")) { + if (virCPULoongArchMapCpucfgParse(child, &cpucfg) >=3D 0) { + feature->index =3D cpucfg.index; + feature->value =3D cpucfg.value; + } + } + } + g_ptr_array_add(model->data.features, g_steal_pointer(&feature)); + } + + VIR_APPEND_ELEMENT(map->models, map->nmodels, model); + return 0; +} + static int virCPULoongArchMapVendorParse(xmlXPathContextPtr ctxt, const char *name, @@ -248,7 +391,7 @@ virCPULoongArchLoadMap(void) =20 if (cpuMapLoad("loongarch", virCPULoongArchMapVendorParse, virCPULoongArchMapFeatureParse, - NULL, map) < 0) + virCPULoongArchMapModelParse, map) < 0) return NULL; =20 return g_steal_pointer(&map); @@ -301,7 +444,7 @@ struct cpuArchDriver cpuDriverLoongArch =3D { .compare =3D virCPULoongArchCompare, .decode =3D virCPULoongArchDriverDecode, .encode =3D NULL, - .dataFree =3D NULL, + .dataFree =3D virCPULoongArchDataFree, .baseline =3D NULL, .update =3D virCPULoongArchUpdate, .getModels =3D NULL, --=20 2.39.1 From nobody Sat Oct 24 20:22:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1791602400357950.134192151626; Fri, 9 Oct 2026 20:20:00 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 4DC0A419C3; Fri, 9 Oct 2026 23:19:59 -0400 (EDT) Received: from [172.19.199.16] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id 6AACF41C05; Fri, 9 Oct 2026 23:15:10 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id DE4244189E; Fri, 9 Oct 2026 23:14:36 -0400 (EDT) Received: from mx11.osci.io (polly.osci.io [38.145.34.174]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id AB172418E9 for ; Fri, 9 Oct 2026 23:14:35 -0400 (EDT) Received: by mx11.osci.io (Postfix, from userid 993) id 48CE9404D5; Fri, 9 Oct 2026 23:14:35 -0400 (EDT) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx11.osci.io (Postfix) with ESMTP id E6CF5404BD for ; Fri, 9 Oct 2026 23:14:32 -0400 (EDT) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8AxdvAerclqDl8UAA--.59155S3; Sat, 10 Oct 2026 11:12:30 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by front1 (Coremail) with SMTP id qMiowJBxrM4XrclqzLYqAA--.61946S7; Sat, 10 Oct 2026 11:12:30 +0800 (CST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 116 seconds by postgrey-1.37 at polly.osci.io; Fri, 09 Oct 2026 23:14:32 EDT From: Xianglai Li To: devel@lists.libvirt.org, lixianglai@loongson.cn Subject: [PATCH 5/6] cpu: add LoongArch CPU decode support Date: Sat, 10 Oct 2026 10:52:17 +0800 Message-Id: <20261010025218.2102264-6-lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20261010025218.2102264-1-lixianglai@loongson.cn> References: <20261010025218.2102264-1-lixianglai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxrM4XrclqzLYqAA--.61946S7 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Message-ID-Hash: 7C6HVLQRFCO642357OFXD7GTAVJBVFKM X-Message-ID-Hash: 7C6HVLQRFCO642357OFXD7GTAVJBVFKM X-MailFrom: SRS0=PumN=IA=loongson.cn=lixianglai@osci.io X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Bibo Mao X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZM-MESSAGEID: 1791602400619158500 Content-Type: text/plain; charset="utf-8" Implement CPU decoding for LoongArch. The CPUCFG registers are read from the host and matched against the known CPU models to produce a virCPUDef. The decoding logic filters the host features based on the selected CPU model: features supported by both are enabled, while features required by the model but missing on the host are explicitly disabled. Signed-off-by: Xianglai Li --- Cc: Bibo Mao src/cpu/cpu_loongarch.c | 189 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 187 insertions(+), 2 deletions(-) diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c index 3cce682349..89ba1a0512 100644 --- a/src/cpu/cpu_loongarch.c +++ b/src/cpu/cpu_loongarch.c @@ -28,6 +28,12 @@ =20 VIR_LOG_INIT("cpu.cpu_loongarch"); =20 +#define MAX_CPU_FLAGS 32 +#define BIT(nr) ((uint32_t)(1U) << (nr)) + +#define PRID_SERIES_MASK 0xf000 +#define LOONGARCH_CPUCFG0 0x0 + typedef struct _virCPULoongArchVendor virCPULoongArchVendor; struct _virCPULoongArchVendor { char *name; @@ -158,6 +164,22 @@ virCPULoongArchMapFree(virCPULoongArchMap *map) } G_DEFINE_AUTOPTR_CLEANUP_FUNC(virCPULoongArchMap, virCPULoongArchMapFree); =20 +static virCPULoongArchFeature * +virCPULoongArchFeatureFindByIndex(virCPULoongArchData *data, + virCPULoongArchFeature *find) +{ + size_t i; + virCPULoongArchFeature *feature; + + for (i =3D 0; i < data->features->len; i++) { + feature =3D g_ptr_array_index(data->features, i); + if ((feature->index =3D=3D find->index) && (feature->value =3D=3D = find->value)) + return feature; + } + + return NULL; +} + static virCPULoongArchFeature * virCPULoongArchMapFeatureFindByName(virCPULoongArchMap *map, const char *name) @@ -188,6 +210,26 @@ virCPULoongArchModelFindByName(virCPULoongArchMap *map, return NULL; } =20 +static virCPULoongArchModel* +virCPULoongArchModelFindBySeries(const virCPULoongArchMap *map, + uint32_t series) +{ + size_t i, j; + + for (i =3D 0; i < map->nmodels; i++) { + virCPULoongArchModel *model =3D map->models[i]; + for (j =3D 0; j < model->data.features->len; j++) { + virCPULoongArchFeature *feature =3D + g_ptr_array_index(model->data.features, j); + if ((feature->index =3D=3D LOONGARCH_CPUCFG0) && + (series =3D=3D (feature->value & PRID_SERIES_MASK))) + return model; + } + } + + return NULL; +} + static virCPULoongArchVendor * virCPULoongArchVendorFindByName(virCPULoongArchMap *map, const char *name) @@ -415,16 +457,159 @@ virCPULoongArchDriverOnceInit(void) return 0; } =20 +static void +virCPULoongArchCpuDataFromCpuCfg(virCPULoongArchModel *cpumodel, + virCPULoongArchData *data) +{ + virCPULoongArchFeature *feature =3D NULL; + g_autoptr(virCPULoongArchFeature) newfeature =3D NULL; + virCPULoongArchFeature *cpucfg; + virCPULoongArchFeature find; + virCPULoongArchMap *map =3D NULL; + ssize_t i, j; + + if (!data->features || !(map =3D virCPULoongArchGetMap())) + return; + + /* + * Only features supported by both cpumodel and data are enabled; + * all other features are not processed. + */ + for (i =3D (data->features->len -1); i >=3D 0; i--) { + cpucfg =3D g_ptr_array_index(data->features, i); + if (cpucfg->index =3D=3D LOONGARCH_CPUCFG0) + continue; + for (j =3D 0; j < MAX_CPU_FLAGS; j++) { + find.index =3D cpucfg->index; + find.value =3D BIT(j); + feature =3D virCPULoongArchFeatureFindByIndex( + &cpumodel->data, + &find); + if (feature) { + newfeature =3D virCPULoongArchFeatureNew(); + newfeature->name =3D g_strdup(feature->name); + newfeature->index =3D feature->index; + newfeature->value =3D feature->value; + newfeature->policy =3D VIR_CPU_FEATURE_DISABLE; + if (cpucfg->value & BIT(j)) { + newfeature->policy =3D VIR_CPU_FEATURE_REQUIRE; + } + g_ptr_array_add(data->features, + g_steal_pointer(&newfeature)); + } else { + feature =3D virCPULoongArchFeatureFindByIndex( + &map->data, + &find); + if (feature) { + newfeature =3D virCPULoongArchFeatureNew(); + newfeature->name =3D g_strdup(feature->name); + newfeature->index =3D feature->index; + newfeature->value =3D feature->value; + newfeature->policy =3D VIR_CPU_FEATURE_DISABLE; + g_ptr_array_add(data->features, + g_steal_pointer(&newfeature)); + } + } + } + } + + for (i =3D (data->features->len -1); i >=3D 0; i--) { + cpucfg =3D g_ptr_array_index(data->features, i); + if ((cpucfg->name =3D=3D NULL) || (cpucfg->index =3D=3D LOONGARCH_= CPUCFG0)) + g_ptr_array_remove(data->features, cpucfg); + } + + /* + * In the cpu data and CPU model XML, features that are not required a= re set + * to disabled by default. + */ + for (i =3D (map->data.features->len -1); i >=3D 0; i--) { + cpucfg =3D g_ptr_array_index(map->data.features, i); + if (cpucfg->index =3D=3D LOONGARCH_CPUCFG0) + continue; + + find.index =3D cpucfg->index; + find.value =3D cpucfg->value; + feature =3D virCPULoongArchFeatureFindByIndex(data, &find); + if (!feature) { + newfeature =3D virCPULoongArchFeatureNew(); + newfeature->name =3D g_strdup(cpucfg->name); + newfeature->index =3D cpucfg->index; + newfeature->value =3D cpucfg->value; + newfeature->policy =3D VIR_CPU_FEATURE_DISABLE; + g_ptr_array_add(data->features, + g_steal_pointer(&newfeature)); + } + } + + return; +} + +static uint32_t +virCPULoongArchCpuDataGetSeries(const virCPULoongArchData *data) +{ + virCPULoongArchFeature *feature =3D NULL; + size_t i; + + for (i =3D 0; i < data->features->len; i++) { + feature =3D g_ptr_array_index(data->features, i); + if (feature->index =3D=3D LOONGARCH_CPUCFG0) + return feature->value & PRID_SERIES_MASK; + } + + return 0; +} + static int -virCPULoongArchDriverDecode(virCPUDef *cpu G_GNUC_UNUSED, +virCPULoongArchDriverDecode(virCPUDef *cpu, const virCPUData *cpuData, - virDomainCapsCPUModels *models G_GNUC_UNUSED) + virDomainCapsCPUModels *models) { virCPULoongArchMap *map =3D NULL; + virCPULoongArchModel *model; + virCPULoongArchData *data; + uint32_t series; + size_t i; =20 if (!cpuData || !(map =3D virCPULoongArchGetMap())) return -1; =20 + data =3D (virCPULoongArchData *)&cpuData->data.loongarch; + series =3D virCPULoongArchCpuDataGetSeries(data); + if (!series) + return -1; + + if (!(model =3D virCPULoongArchModelFindBySeries(map, series))) { + virReportError(VIR_ERR_OPERATION_FAILED, + _("Cannot find CPU model with cpucfg series 0x%1$08= x"), + series); + return -1; + } + + if (!virCPUModelIsAllowed(model->name, models)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU model %1$s is not supported by hypervisor"), + model->name); + return -1; + } + + virCPULoongArchCpuDataFromCpuCfg(model, data); + cpu->model =3D g_strdup(model->name); + if (model->vendor) + cpu->vendor =3D g_strdup(model->vendor->name); + + if (data->features) { + cpu->nfeatures =3D data->features->len; + cpu->features =3D g_new0(virCPUFeatureDef, cpu->nfeatures); + + for (i =3D 0; i < cpu->nfeatures; i++) { + virCPULoongArchFeature *feature =3D + g_ptr_array_index(data->features, i); + cpu->features[i].policy =3D feature->policy; + cpu->features[i].name =3D g_strdup(feature->name); + } + } + return 0; } =20 --=20 2.39.1 From nobody Sat Oct 24 20:22:40 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) client-ip=38.145.34.151; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of lists.libvirt.org designates 38.145.34.151 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [38.145.34.151]) by mx.zohomail.com with SMTPS id 1791602758458771.4949233238913; Fri, 9 Oct 2026 20:25:58 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 5357E4191B; Fri, 9 Oct 2026 23:25:57 -0400 (EDT) Received: from [172.19.199.16] (unknown [10.16.107.18]) by lists.libvirt.org (Postfix) with ESMTP id A8E5C41B92; Fri, 9 Oct 2026 23:23:40 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id E7A903F340; Fri, 9 Oct 2026 23:23:14 -0400 (EDT) Received: from mx22.osci.io (francine.osci.io [38.145.34.137]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id DA5144199E for ; Fri, 9 Oct 2026 23:20:14 -0400 (EDT) Received: by mx22.osci.io (Postfix, from userid 993) id 185C764661; Fri, 9 Oct 2026 23:14:34 -0400 (EDT) Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by mx22.osci.io (Postfix) with ESMTP id 0DFCB64661 for ; Fri, 9 Oct 2026 23:14:32 -0400 (EDT) Received: from loongson.cn (unknown [10.2.5.185]) by gateway (Coremail) with SMTP id _____8CxPNIerclqD18UAA--.59503S3; Sat, 10 Oct 2026 11:12:30 +0800 (CST) Received: from localhost.localdomain (unknown [10.2.5.185]) by front1 (Coremail) with SMTP id qMiowJBxrM4XrclqzLYqAA--.61946S8; Sat, 10 Oct 2026 11:12:30 +0800 (CST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=4.0.1 X-Greylist: delayed 339 seconds by postgrey-1.37 at lists.libvirt.org; Fri, 09 Oct 2026 23:20:14 EDT From: Xianglai Li To: devel@lists.libvirt.org, lixianglai@loongson.cn Subject: [PATCH 6/6] cpu: add LoongArch host model support Date: Sat, 10 Oct 2026 10:52:18 +0800 Message-Id: <20261010025218.2102264-7-lixianglai@loongson.cn> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20261010025218.2102264-1-lixianglai@loongson.cn> References: <20261010025218.2102264-1-lixianglai@loongson.cn> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-CM-TRANSID: qMiowJBxrM4XrclqzLYqAA--.61946S8 X-CM-SenderInfo: 5ol0xt5qjotxo6or00hjvr0hdfq/ X-Coremail-Antispam: 1Uk129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7KY7 ZEXasCq-sGcSsGvfJ3UbIjqfuFe4nvWSU5nxnvy29KBjDU0xBIdaVrnUUvcSsGvfC2Kfnx nUUI43ZEXa7xR_UUUUUUUUU== Message-ID-Hash: 635EIU7HTJNYZIYCN4C5QWUMIC4NQTMW X-Message-ID-Hash: 635EIU7HTJNYZIYCN4C5QWUMIC4NQTMW X-MailFrom: lixianglai@loongson.cn X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Bibo Mao X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-ZM-MESSAGEID: 1791602759852158500 Content-Type: text/plain; charset="utf-8" Add host model support for LoongArch, allowing libvirt to detect the host CPU and expand a host-model CPU definition into a custom model. The following driver callbacks are implemented: - getHost: read CPUCFG registers from the host - update: expand host-model to a custom model - compare: compare guest and host CPU features The QEMU capabilities code is adjusted so that LoongArch no longer falls back to the generic ARM/unknown path. Signed-off-by: Xianglai Li --- Cc: Bibo Mao src/cpu/cpu_loongarch.c | 64 ++++++++++++++++++++++++++++++++++-- src/qemu/qemu_capabilities.c | 2 +- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/cpu/cpu_loongarch.c b/src/cpu/cpu_loongarch.c index 89ba1a0512..8ce9d53cb0 100644 --- a/src/cpu/cpu_loongarch.c +++ b/src/cpu/cpu_loongarch.c @@ -33,6 +33,7 @@ VIR_LOG_INIT("cpu.cpu_loongarch"); =20 #define PRID_SERIES_MASK 0xf000 #define LOONGARCH_CPUCFG0 0x0 +#define LOONGARCH_CPUCFGMAX 0x14 =20 typedef struct _virCPULoongArchVendor virCPULoongArchVendor; struct _virCPULoongArchVendor { @@ -614,11 +615,67 @@ virCPULoongArchDriverDecode(virCPUDef *cpu, } =20 static int -virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED, - const virCPUDef *host G_GNUC_UNUSED, - bool relative G_GNUC_UNUSED, +virCPULoongArchGetHost(virCPUDef *cpu, + virDomainCapsCPUModels *models) +{ + g_autoptr(virCPUData) cpuData =3D NULL; + virCPULoongArchData *data; + uint32_t i, val; + + if (!(cpuData =3D virCPUDataNew(archs[0]))) + return -1; + + data =3D &cpuData->data.loongarch; + data->features =3D g_ptr_array_new(); + g_ptr_array_set_free_func(data->features, + (GDestroyNotify) virCPULoongArchFeatureFree); + + for (i =3D 0; i < (LOONGARCH_CPUCFGMAX +1); i++) { + g_autoptr(virCPULoongArchFeature) feature =3D NULL; + val =3D 0; + +#if defined(__loongarch64) + asm("cpucfg %0, %1" + : "=3Dr" (val) + : "r" (i) + : + ); +#endif + + if (!val) + continue; + + feature =3D virCPULoongArchFeatureNew(); + feature->index =3D i; + feature->value =3D val; + g_ptr_array_add(data->features, g_steal_pointer(&feature)); + } + + return virCPULoongArchDriverDecode(cpu, cpuData, models); +} + +static int +virCPULoongArchUpdate(virCPUDef *guest, + const virCPUDef *host, + bool relative, virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED) { + g_autoptr(virCPUDef) updated =3D virCPUDefCopyWithoutModel(guest); + + if (!relative || guest->mode !=3D VIR_CPU_MODE_HOST_MODEL) + return 0; + + if (!host) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("unknown host CPU model")); + return -1; + } + + updated->mode =3D VIR_CPU_MODE_CUSTOM; + virCPUDefCopyModel(updated, host, true); + virCPUDefStealModel(guest, updated, false); + guest->mode =3D VIR_CPU_MODE_CUSTOM; + guest->match =3D VIR_CPU_MATCH_EXACT; return 0; } =20 @@ -630,6 +687,7 @@ struct cpuArchDriver cpuDriverLoongArch =3D { .decode =3D virCPULoongArchDriverDecode, .encode =3D NULL, .dataFree =3D virCPULoongArchDataFree, + .getHost =3D virCPULoongArchGetHost, .baseline =3D NULL, .update =3D virCPULoongArchUpdate, .getModels =3D NULL, diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index bc2b0412dc..43abb00826 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -4104,7 +4104,7 @@ virQEMUCapsInitCPUModel(virQEMUCaps *qemuCaps, } else if (ARCH_IS_X86(qemuCaps->arch)) { ret =3D virQEMUCapsInitCPUModelX86(qemuCaps, type, modelInfo, cpu, migratable); - } else if (ARCH_IS_ARM(qemuCaps->arch) || ARCH_IS_LOONGARCH(qemuCaps->= arch)) { + } else if (ARCH_IS_ARM(qemuCaps->arch)) { ret =3D 2; } =20 --=20 2.39.1