[libvirt PATCH v2 09/12] qemu: report max number of SEV guests

Daniel P. Berrangé berrange at redhat.com
Fri Dec 10 11:37:32 UTC 2021


Different CPU generations have different limits on the number
of SEV/SEV-ES guests that can be run. Since both limits come
from the same overall set, there is typically also BIOS config
to set the tradeoff betweeen SEV and SEV-ES guest limits.

This is important information to expose for a mgmt application
scheduling guests to hosts.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/qemu/qemu_capabilities.c                  | 38 +++++++++++++++++++
 src/qemu/qemu_driver.c                        | 10 +++++
 .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml |  2 +-
 .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml |  2 +-
 tests/domaincapsdata/qemu_2.12.0.x86_64.xml   |  2 +-
 .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml  |  2 +-
 .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml  |  2 +-
 tests/domaincapsdata/qemu_6.0.0.x86_64.xml    |  2 +-
 8 files changed, 54 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 4ffd0a98a2..456ce1b72e 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1897,6 +1897,8 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
 
     tmp->cbitpos = src->cbitpos;
     tmp->reduced_phys_bits = src->reduced_phys_bits;
+    tmp->max_guests = src->max_guests;
+    tmp->max_es_guests = src->max_es_guests;
 
     *dst = g_steal_pointer(&tmp);
     return 0;
@@ -3286,6 +3288,30 @@ virQEMUCapsProbeQMPGICCapabilities(virQEMUCaps *qemuCaps,
 }
 
 
+static void
+virQEMUCapsGetSEVMaxGuests(virSEVCapability *caps)
+{
+# if __x86_64__
+    uint32_t eax, ebx, ecx, edx;
+    asm("xor %%ebx, %%ebx;" /* clear the other registers as some cpuid */
+        "xor %%edx, %%edx;" /* functions may use them as additional arguments */
+        "cpuid;"
+        : "=a" (eax),
+          "=b" (ebx),
+          "=c" (ecx),
+          "=d" (edx)
+        : "0" (0x8000001F),
+          "c" (0)
+        : "cc");
+
+    caps->max_guests = ecx - edx + 1;
+    caps->max_es_guests = edx - 1;
+# else
+    VIR_WARN("Unexpectedly asked for SEV guest count on non-x86_64 arch");
+    caps->max_guests = caps->max_es_guests = 0;
+# endif
+}
+
 static int
 virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
                                    qemuMonitor *mon)
@@ -3305,6 +3331,8 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
         return 0;
     }
 
+    virQEMUCapsGetSEVMaxGuests(caps);
+
     virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
     qemuCaps->sevCapabilities = caps;
     return 0;
@@ -4084,6 +4112,14 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt)
         return -1;
     }
 
+
+    /* We probe this every time because the values
+     * can change on every reboot via firmware
+     * config tunables. It is cheap to query so
+     * lack of caching is a non-issue
+     */
+    virQEMUCapsGetSEVMaxGuests(sev);
+
     qemuCaps->sevCapabilities = g_steal_pointer(&sev);
     return 0;
 }
@@ -6344,6 +6380,8 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCaps *qemuCaps,
     domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
     domCaps->sev->cbitpos = cap->cbitpos;
     domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits;
+    domCaps->sev->max_guests = cap->max_guests;
+    domCaps->sev->max_es_guests = cap->max_es_guests;
 }
 
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1bf1938634..572e09be9f 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -19934,6 +19934,16 @@ qemuGetSEVInfoToParams(virQEMUCaps *qemuCaps,
                     sev->reduced_phys_bits) < 0)
         goto cleanup;
 
+    if (virTypedParamsAddUInt(&sevParams, &n, &maxpar,
+                    VIR_NODE_SEV_MAX_GUESTS,
+                    sev->max_guests) < 0)
+        goto cleanup;
+
+    if (virTypedParamsAddUInt(&sevParams, &n, &maxpar,
+                    VIR_NODE_SEV_MAX_ES_GUESTS,
+                    sev->max_es_guests) < 0)
+        goto cleanup;
+
     *params = g_steal_pointer(&sevParams);
     *nparams = n;
     return 0;
diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
index 26816ff066..6956f9af07 100644
--- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml
@@ -205,7 +205,7 @@
     <sev supported='yes'>
       <cbitpos>47</cbitpos>
       <reducedPhysBits>1</reducedPhysBits>
-      <maxGuests>0</maxGuests>
+      <maxGuests>15</maxGuests>
       <maxESGuests>0</maxESGuests>
     </sev>
   </features>
diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
index 5840a8b921..c6408d154c 100644
--- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml
@@ -215,7 +215,7 @@
     <sev supported='yes'>
       <cbitpos>47</cbitpos>
       <reducedPhysBits>1</reducedPhysBits>
-      <maxGuests>0</maxGuests>
+      <maxGuests>15</maxGuests>
       <maxESGuests>0</maxESGuests>
     </sev>
   </features>
diff --git a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
index 21d1b6946e..918439e4a0 100644
--- a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml
@@ -205,7 +205,7 @@
     <sev supported='yes'>
       <cbitpos>47</cbitpos>
       <reducedPhysBits>1</reducedPhysBits>
-      <maxGuests>0</maxGuests>
+      <maxGuests>15</maxGuests>
       <maxESGuests>0</maxESGuests>
     </sev>
   </features>
diff --git a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
index 3415d44019..8733b79a31 100644
--- a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml
@@ -227,7 +227,7 @@
     <sev supported='yes'>
       <cbitpos>47</cbitpos>
       <reducedPhysBits>1</reducedPhysBits>
-      <maxGuests>0</maxGuests>
+      <maxGuests>15</maxGuests>
       <maxESGuests>0</maxESGuests>
     </sev>
   </features>
diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
index f58be3af6c..0382bdaf5a 100644
--- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml
@@ -233,7 +233,7 @@
     <sev supported='yes'>
       <cbitpos>47</cbitpos>
       <reducedPhysBits>1</reducedPhysBits>
-      <maxGuests>0</maxGuests>
+      <maxGuests>15</maxGuests>
       <maxESGuests>0</maxESGuests>
     </sev>
   </features>
diff --git a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
index 0a2615c519..30ea787a75 100644
--- a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
+++ b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml
@@ -227,7 +227,7 @@
     <sev supported='yes'>
       <cbitpos>47</cbitpos>
       <reducedPhysBits>1</reducedPhysBits>
-      <maxGuests>0</maxGuests>
+      <maxGuests>15</maxGuests>
       <maxESGuests>0</maxESGuests>
     </sev>
   </features>
-- 
2.33.1




More information about the libvir-list mailing list