[PATCH v2 13/36] cpu_x86: Record relations between CPU models

Jiri Denemark posted 36 patches 1 week, 4 days ago
[PATCH v2 13/36] cpu_x86: Record relations between CPU models
Posted by Jiri Denemark 1 week, 4 days ago
Record a fact a specific CPU model was derived from another one. The
original model is also marked as an alias of the new one in case it did
not change any properties of the original CPU.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---

Notes:
    Version 2:
    - new patch

 src/cpu/cpu_x86.c | 47 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 41 insertions(+), 6 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 285b272ce8..ce3506be55 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -180,6 +180,17 @@ struct _virCPUx86Model {
      * The corresponding features are a genuine part of the new model.
      */
     GStrv addedFeatures;
+
+    /* Pinter to the model this one was derived from. */
+    virCPUx86Model *ancestor;
+
+    /* Pointer to the canonical model if this model is just an alias.
+     * Because the aliases were actually added to the CPU map before their
+     * canonical models, we store this relation in the XML reversed. That is,
+     * this model contains all the data and the canonical model is defined
+     * using this model as an ancestor without adding any additional data.
+     */
+    const virCPUx86Model *canonical;
 };
 
 typedef struct _virCPUx86Map virCPUx86Map;
@@ -1567,6 +1578,7 @@ x86ModelParseAncestor(virCPUx86Model *model,
         return -1;
     }
 
+    model->ancestor = ancestor;
     model->vendor = ancestor->vendor;
     model->signatures = virCPUx86SignaturesCopy(ancestor->signatures);
     x86DataCopy(&model->data, &ancestor->data);
@@ -1582,9 +1594,11 @@ x86ModelParseAncestor(virCPUx86Model *model,
 }
 
 
+/* Updates @changed if signatures are set. */
 static int
 x86ModelParseSignatures(virCPUx86Model *model,
-                        xmlXPathContextPtr ctxt)
+                        xmlXPathContextPtr ctxt,
+                        bool *changed)
 {
     g_autofree xmlNodePtr *nodes = NULL;
     VIR_XPATH_NODE_AUTORESTORE(ctxt)
@@ -1628,14 +1642,17 @@ x86ModelParseSignatures(virCPUx86Model *model,
             return -1;
     }
 
+    *changed = true;
     return 0;
 }
 
 
+/* Updates @changed if vendor changes. */
 static int
 x86ModelParseVendor(virCPUx86Model *model,
                     xmlXPathContextPtr ctxt,
-                    virCPUx86Map *map)
+                    virCPUx86Map *map,
+                    bool *changed)
 {
     g_autofree char *vendor = NULL;
     int rc;
@@ -1658,14 +1675,17 @@ x86ModelParseVendor(virCPUx86Model *model,
         return -1;
     }
 
+    *changed = true;
     return 0;
 }
 
 
+/* Updates @changed if features are added. */
 static int
 x86ModelParseFeatures(virCPUx86Model *model,
                       xmlXPathContextPtr ctxt,
-                      virCPUx86Map *map)
+                      virCPUx86Map *map,
+                      bool *changed)
 {
     g_autofree xmlNodePtr *nodes = NULL;
     size_t i;
@@ -1725,6 +1745,7 @@ x86ModelParseFeatures(virCPUx86Model *model,
     model->removedFeatures = g_renew(char *, model->removedFeatures, nremoved + 1);
     model->addedFeatures = g_renew(char *, model->addedFeatures, nadded + 1);
 
+    *changed = true;
     return 0;
 }
 
@@ -1736,6 +1757,7 @@ x86ModelParse(xmlXPathContextPtr ctxt,
 {
     virCPUx86Map *map = data;
     g_autoptr(virCPUx86Model) model = NULL;
+    bool changed = false;
 
     if (x86ModelFind(map, name)) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -1755,15 +1777,28 @@ x86ModelParse(xmlXPathContextPtr ctxt,
     if (x86ModelParseAncestor(model, ctxt, map) < 0)
         return -1;
 
-    if (x86ModelParseSignatures(model, ctxt) < 0)
+    if (x86ModelParseSignatures(model, ctxt, &changed) < 0)
         return -1;
 
-    if (x86ModelParseVendor(model, ctxt, map) < 0)
+    if (x86ModelParseVendor(model, ctxt, map, &changed) < 0)
         return -1;
 
-    if (x86ModelParseFeatures(model, ctxt, map) < 0)
+    if (x86ModelParseFeatures(model, ctxt, map, &changed) < 0)
         return -1;
 
+    if (model->ancestor && !changed) {
+        if (model->ancestor->canonical) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Cannot set CPU model '%1$s' as canonical name of '%2$s' which is already an alias of '%3$s'"),
+                           model->name,
+                           model->ancestor->name,
+                           model->ancestor->canonical->name);
+            return -1;
+        }
+
+        model->ancestor->canonical = model;
+    }
+
     VIR_APPEND_ELEMENT(map->models, map->nmodels, model);
 
     return 0;
-- 
2.47.0
Re: [PATCH v2 13/36] cpu_x86: Record relations between CPU models
Posted by Daniel P. Berrangé 1 week, 1 day ago
On Fri, Nov 22, 2024 at 10:32:53PM +0100, Jiri Denemark wrote:
> Record a fact a specific CPU model was derived from another one. The
> original model is also marked as an alias of the new one in case it did
> not change any properties of the original CPU.
> 
> Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
> ---

Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>


With regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|