mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
qemu: report max number of SEV guests
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. Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
parent
2150c7c9f7
commit
7826148a72
@ -1897,6 +1897,8 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
|
|||||||
|
|
||||||
tmp->cbitpos = src->cbitpos;
|
tmp->cbitpos = src->cbitpos;
|
||||||
tmp->reduced_phys_bits = src->reduced_phys_bits;
|
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);
|
*dst = g_steal_pointer(&tmp);
|
||||||
return 0;
|
return 0;
|
||||||
@ -3286,6 +3288,31 @@ virQEMUCapsProbeQMPGICCapabilities(virQEMUCaps *qemuCaps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
virQEMUCapsGetSEVMaxGuests(virSEVCapability *caps)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* From Secure Encrypted Virtualization API v0.24, section 6.19.1
|
||||||
|
*
|
||||||
|
* If the guest is SEV-ES enabled, then the ASID must be at least
|
||||||
|
* 1h and at most (MIN_SEV_ASID-1). If the guest is not SEV-ES
|
||||||
|
* enabled, then the ASID must be at least MIN_SEV_ASID and at
|
||||||
|
* most the maximum SEV ASID available. The MIN_SEV_ASID value
|
||||||
|
* is discovered by CPUID Fn8000_001F[EDX]. The maximum SEV ASID
|
||||||
|
* available is discovered by CPUID Fn8000_001F[ECX].
|
||||||
|
*/
|
||||||
|
uint32_t min_asid, max_asid;
|
||||||
|
virHostCPUX86GetCPUID(0x8000001F, 0, NULL, NULL,
|
||||||
|
&max_asid, &min_asid);
|
||||||
|
|
||||||
|
if (max_asid != 0 && min_asid != 0) {
|
||||||
|
caps->max_guests = max_asid - min_asid + 1;
|
||||||
|
caps->max_es_guests = min_asid - 1;
|
||||||
|
} else {
|
||||||
|
caps->max_guests = caps->max_es_guests = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
|
virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
|
||||||
qemuMonitor *mon)
|
qemuMonitor *mon)
|
||||||
@ -3305,6 +3332,8 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virQEMUCapsGetSEVMaxGuests(caps);
|
||||||
|
|
||||||
virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
|
virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
|
||||||
qemuCaps->sevCapabilities = caps;
|
qemuCaps->sevCapabilities = caps;
|
||||||
return 0;
|
return 0;
|
||||||
@ -4084,6 +4113,14 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt)
|
|||||||
return -1;
|
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);
|
qemuCaps->sevCapabilities = g_steal_pointer(&sev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -6344,6 +6381,8 @@ virQEMUCapsFillDomainFeatureSEVCaps(virQEMUCaps *qemuCaps,
|
|||||||
domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
|
domCaps->sev->cert_chain = g_strdup(cap->cert_chain);
|
||||||
domCaps->sev->cbitpos = cap->cbitpos;
|
domCaps->sev->cbitpos = cap->cbitpos;
|
||||||
domCaps->sev->reduced_phys_bits = cap->reduced_phys_bits;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19917,6 +19917,16 @@ qemuGetSEVInfoToParams(virQEMUCaps *qemuCaps,
|
|||||||
sev->reduced_phys_bits) < 0)
|
sev->reduced_phys_bits) < 0)
|
||||||
goto cleanup;
|
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);
|
*params = g_steal_pointer(&sevParams);
|
||||||
*nparams = n;
|
*nparams = n;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -205,8 +205,8 @@
|
|||||||
<sev supported='yes'>
|
<sev supported='yes'>
|
||||||
<cbitpos>47</cbitpos>
|
<cbitpos>47</cbitpos>
|
||||||
<reducedPhysBits>1</reducedPhysBits>
|
<reducedPhysBits>1</reducedPhysBits>
|
||||||
<maxGuests>0</maxGuests>
|
<maxGuests>59</maxGuests>
|
||||||
<maxESGuests>0</maxESGuests>
|
<maxESGuests>450</maxESGuests>
|
||||||
</sev>
|
</sev>
|
||||||
</features>
|
</features>
|
||||||
</domainCapabilities>
|
</domainCapabilities>
|
||||||
|
@ -215,8 +215,8 @@
|
|||||||
<sev supported='yes'>
|
<sev supported='yes'>
|
||||||
<cbitpos>47</cbitpos>
|
<cbitpos>47</cbitpos>
|
||||||
<reducedPhysBits>1</reducedPhysBits>
|
<reducedPhysBits>1</reducedPhysBits>
|
||||||
<maxGuests>0</maxGuests>
|
<maxGuests>59</maxGuests>
|
||||||
<maxESGuests>0</maxESGuests>
|
<maxESGuests>450</maxESGuests>
|
||||||
</sev>
|
</sev>
|
||||||
</features>
|
</features>
|
||||||
</domainCapabilities>
|
</domainCapabilities>
|
||||||
|
@ -205,8 +205,8 @@
|
|||||||
<sev supported='yes'>
|
<sev supported='yes'>
|
||||||
<cbitpos>47</cbitpos>
|
<cbitpos>47</cbitpos>
|
||||||
<reducedPhysBits>1</reducedPhysBits>
|
<reducedPhysBits>1</reducedPhysBits>
|
||||||
<maxGuests>0</maxGuests>
|
<maxGuests>59</maxGuests>
|
||||||
<maxESGuests>0</maxESGuests>
|
<maxESGuests>450</maxESGuests>
|
||||||
</sev>
|
</sev>
|
||||||
</features>
|
</features>
|
||||||
</domainCapabilities>
|
</domainCapabilities>
|
||||||
|
@ -227,8 +227,8 @@
|
|||||||
<sev supported='yes'>
|
<sev supported='yes'>
|
||||||
<cbitpos>47</cbitpos>
|
<cbitpos>47</cbitpos>
|
||||||
<reducedPhysBits>1</reducedPhysBits>
|
<reducedPhysBits>1</reducedPhysBits>
|
||||||
<maxGuests>0</maxGuests>
|
<maxGuests>59</maxGuests>
|
||||||
<maxESGuests>0</maxESGuests>
|
<maxESGuests>450</maxESGuests>
|
||||||
</sev>
|
</sev>
|
||||||
</features>
|
</features>
|
||||||
</domainCapabilities>
|
</domainCapabilities>
|
||||||
|
@ -233,8 +233,8 @@
|
|||||||
<sev supported='yes'>
|
<sev supported='yes'>
|
||||||
<cbitpos>47</cbitpos>
|
<cbitpos>47</cbitpos>
|
||||||
<reducedPhysBits>1</reducedPhysBits>
|
<reducedPhysBits>1</reducedPhysBits>
|
||||||
<maxGuests>0</maxGuests>
|
<maxGuests>59</maxGuests>
|
||||||
<maxESGuests>0</maxESGuests>
|
<maxESGuests>450</maxESGuests>
|
||||||
</sev>
|
</sev>
|
||||||
</features>
|
</features>
|
||||||
</domainCapabilities>
|
</domainCapabilities>
|
||||||
|
@ -227,8 +227,8 @@
|
|||||||
<sev supported='yes'>
|
<sev supported='yes'>
|
||||||
<cbitpos>47</cbitpos>
|
<cbitpos>47</cbitpos>
|
||||||
<reducedPhysBits>1</reducedPhysBits>
|
<reducedPhysBits>1</reducedPhysBits>
|
||||||
<maxGuests>0</maxGuests>
|
<maxGuests>59</maxGuests>
|
||||||
<maxESGuests>0</maxESGuests>
|
<maxESGuests>450</maxESGuests>
|
||||||
</sev>
|
</sev>
|
||||||
</features>
|
</features>
|
||||||
</domainCapabilities>
|
</domainCapabilities>
|
||||||
|
@ -143,6 +143,29 @@ virCapabilitiesHostNUMANewHost(void)
|
|||||||
return virTestCapsBuildNUMATopology(3);
|
return virTestCapsBuildNUMATopology(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
virHostCPUX86GetCPUID(uint32_t leaf,
|
||||||
|
uint32_t extended,
|
||||||
|
uint32_t *eax,
|
||||||
|
uint32_t *ebx,
|
||||||
|
uint32_t *ecx,
|
||||||
|
uint32_t *edx)
|
||||||
|
{
|
||||||
|
if (eax)
|
||||||
|
*eax = 0;
|
||||||
|
if (ebx)
|
||||||
|
*ebx = 0;
|
||||||
|
if (ecx)
|
||||||
|
*ecx = 0;
|
||||||
|
if (edx)
|
||||||
|
*edx = 0;
|
||||||
|
if (leaf == 0x8000001F && extended == 0) {
|
||||||
|
if (ecx)
|
||||||
|
*ecx = 509;
|
||||||
|
if (edx)
|
||||||
|
*edx = 451;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testQemuAddGuest(virCaps *caps,
|
testQemuAddGuest(virCaps *caps,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user