[libvirt] [PATCH 2/4] cpu: Better support for ppc64 compatibility modes
Jiri Denemark
jdenemar at redhat.com
Fri Aug 21 21:27:14 UTC 2015
On Tue, Aug 18, 2015 at 16:45:05 -0700, Andrea Bolognani wrote:
> Not all combinations of host CPU models and compatibility modes
> are valid, so we need to make sure we don't try to do something
> that QEMU will reject.
>
> Moreover, we need to apply a different logic to guests using
> host-model and host-passthrough modes when testing them for host
> compatibility.
>
> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1251927
> ---
> src/cpu/cpu_ppc64.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++--
> 1 file changed, 90 insertions(+), 3 deletions(-)
>
> diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c
> index 72b8fa0..1a1b15b 100644
> --- a/src/cpu/cpu_ppc64.c
> +++ b/src/cpu/cpu_ppc64.c
> @@ -84,6 +84,57 @@ ppc64ConvertLegacyCPUDef(const virCPUDef *legacy)
> return cpu;
> }
>
> +/* Some hosts can run guests in compatibility mode, but not all
> + * host CPUs support this and not all combinations are valid.
> + * This function performs the necessary checks */
> +static virCPUCompareResult
> +ppc64CheckCompatibilityMode(const char *host_model,
> + const char *compat_mode)
> +{
> + int host;
> + int compat;
> + char *tmp;
> + virCPUCompareResult ret = VIR_CPU_COMPARE_IDENTICAL;
Shouldn't ret be initialized to VIR_CPU_COMPARE_ERROR so that we don't
report everything is OK on errors?
> +
> + if (!compat_mode)
> + goto out;
> +
> + ret = VIR_CPU_COMPARE_ERROR;
> +
> + /* Valid host CPUs: POWER6, POWER7, POWER8 */
> + if (!STRPREFIX(host_model, "POWER") ||
> + !(tmp = (char *) host_model + strlen("POWER")) ||
> + virStrToLong_i(tmp, NULL, 10, &host) < 0 ||
> + host < 6 || host > 8) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s",
> + _("Host CPU does not support compatibility modes"));
> + goto out;
> + }
> +
> + /* Valid compatibility modes: power6, power7, power8 */
> + if (!STRPREFIX(compat_mode, "power") ||
> + !(tmp = (char *) compat_mode + strlen("power")) ||
> + virStrToLong_i(tmp, NULL, 10, &compat) < 0 ||
> + compat < 6 || compat > 8) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Unknown compatibility mode %s"),
> + compat_mode);
> + goto out;
> + }
> +
> + ret = VIR_CPU_COMPARE_INCOMPATIBLE;
> +
> + /* Version check */
> + if (compat > host)
> + goto out;
> +
> + ret = VIR_CPU_COMPARE_IDENTICAL;
if (compat > host)
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
else
ret = VIR_CPU_COMPARE_IDENTICAL;
would be a bit more obvious I think.
> +
> + out:
> + return ret;
> +}
> +
> static void
> ppc64DataFree(virCPUppc64Data *data)
> {
> @@ -509,11 +560,47 @@ ppc64Compute(virCPUDefPtr host,
> goto cleanup;
> }
>
> - if (!(map = ppc64LoadMap()) ||
> - !(host_model = ppc64ModelFromCPU(host, map)) ||
> - !(guest_model = ppc64ModelFromCPU(cpu, map)))
> + if (!(map = ppc64LoadMap()))
> goto cleanup;
>
> + /* Host CPU information */
> + if (!(host_model = ppc64ModelFromCPU(host, map)))
> + goto cleanup;
> +
> + if (cpu->type == VIR_CPU_TYPE_GUEST) {
> + /* Guest CPU information */
> + virCPUCompareResult tmp;
> + switch (cpu->mode) {
> + case VIR_CPU_MODE_HOST_MODEL:
> + /* host-model only:
> + * we need to take compatibility modes into account */
> + tmp = ppc64CheckCompatibilityMode(host->model, cpu->model);
> + if (tmp != VIR_CPU_COMPARE_IDENTICAL) {
> + ret = tmp;
> + goto cleanup;
> + }
> + /* fallthrough */
> +
> + case VIR_CPU_MODE_HOST_PASSTHROUGH:
> + /* host-model and host-passthrough:
> + * the guest CPU is the same as the host */
> + if (!(guest_model = ppc64ModelCopy(host_model)))
> + goto cleanup;
> + break;
> +
> + case VIR_CPU_MODE_CUSTOM:
> + /* custom:
> + * look up guest CPU information */
> + if (!(guest_model = ppc64ModelFromCPU(cpu, map)))
> + goto cleanup;
> + break;
> + }
> + } else {
> + /* Other host CPU information */
> + if (!(guest_model = ppc64ModelFromCPU(cpu, map)))
> + goto cleanup;
> + }
> +
> if (STRNEQ(guest_model->name, host_model->name)) {
> VIR_DEBUG("host CPU model does not match required CPU model %s",
> guest_model->name);
In the long term, I think we should store compatibility modes within
cpu_map.xml, but ACK to this with the small issues addressed.
Jirka
More information about the libvir-list
mailing list