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@xxxxxxxxxx> --- 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