cpu.c 29.5 KB
Newer Older
J
Jiri Denemark 已提交
1 2 3
/*
 * cpu.c: internal functions for CPU manipulation
 *
4
 * Copyright (C) 2009-2013 Red Hat, Inc.
J
Jiri Denemark 已提交
5 6 7 8 9 10 11 12 13 14 15 16
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library.  If not, see
O
Osier Yang 已提交
18
 * <http://www.gnu.org/licenses/>.
J
Jiri Denemark 已提交
19 20 21 22
 */

#include <config.h>

23
#include "virlog.h"
24
#include "viralloc.h"
25
#include "virxml.h"
J
Jiri Denemark 已提交
26
#include "cpu.h"
27
#include "cpu_map.h"
J
Jiri Denemark 已提交
28
#include "cpu_x86.h"
29
#include "cpu_ppc64.h"
T
Thang Pham 已提交
30
#include "cpu_s390.h"
C
Chuck Short 已提交
31
#include "cpu_arm.h"
M
Martin Kletzander 已提交
32
#include "capabilities.h"
33
#include "virstring.h"
J
Jiri Denemark 已提交
34 35 36 37


#define VIR_FROM_THIS VIR_FROM_CPU

38 39
VIR_LOG_INIT("cpu.cpu");

J
Jiri Denemark 已提交
40 41
static struct cpuArchDriver *drivers[] = {
    &cpuDriverX86,
42
    &cpuDriverPPC64,
T
Thang Pham 已提交
43
    &cpuDriverS390,
C
Chuck Short 已提交
44
    &cpuDriverArm,
J
Jiri Denemark 已提交
45 46 47 48
};


static struct cpuArchDriver *
49
cpuGetSubDriver(virArch arch)
J
Jiri Denemark 已提交
50
{
51 52
    size_t i;
    size_t j;
J
Jiri Denemark 已提交
53

54
    if (arch == VIR_ARCH_NONE) {
55 56
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("undefined hardware architecture"));
J
Jiri Denemark 已提交
57 58 59
        return NULL;
    }

60
    for (i = 0; i < G_N_ELEMENTS(drivers); i++) {
J
Jiri Denemark 已提交
61
        for (j = 0; j < drivers[i]->narch; j++) {
62
            if (arch == drivers[i]->arch[j])
J
Jiri Denemark 已提交
63 64 65 66
                return drivers[i];
        }
    }

J
Jiri Denemark 已提交
67 68 69 70
    virReportError(VIR_ERR_NO_SUPPORT,
                   _("'%s' architecture is not supported by CPU driver"),
                   virArchToString(arch));
    return NULL;
J
Jiri Denemark 已提交
71 72 73
}


74 75 76 77 78
static struct cpuArchDriver *
cpuGetSubDriverByName(const char *name)
{
    size_t i;

79
    for (i = 0; i < G_N_ELEMENTS(drivers); i++) {
80 81 82 83 84 85 86 87 88 89 90
        if (STREQ_NULLABLE(name, drivers[i]->name))
            return drivers[i];
    }

    virReportError(VIR_ERR_INTERNAL_ERROR,
                   _("CPU driver '%s' does not exist"),
                   name);
    return NULL;
}


91
/**
J
Jiri Denemark 已提交
92
 * virCPUCompareXML:
93
 *
J
Jiri Denemark 已提交
94
 * @arch: CPU architecture
95 96
 * @host: host CPU definition
 * @xml: XML description of either guest or host CPU to be compared with @host
97
 * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE
98 99 100 101 102 103
 *
 * Compares the CPU described by @xml with @host CPU.
 *
 * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
 * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs
 * are identical, VIR_CPU_COMPARE_SUPERSET when the @xml CPU is a superset of
104 105 106
 * the @host CPU. If @failIncompatible is true, the function will return
 * VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE error) when the
 * two CPUs are incompatible.
107
 */
J
Jiri Denemark 已提交
108
virCPUCompareResult
J
Jiri Denemark 已提交
109 110 111 112
virCPUCompareXML(virArch arch,
                 virCPUDefPtr host,
                 const char *xml,
                 bool failIncompatible)
J
Jiri Denemark 已提交
113 114 115 116
{
    virCPUDefPtr cpu = NULL;
    virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;

J
Jiri Denemark 已提交
117 118 119
    VIR_DEBUG("arch=%s, host=%p, xml=%s",
              virArchToString(arch), host, NULLSTR(xml));

120
    if (virCPUDefParseXMLString(xml, VIR_CPU_TYPE_AUTO, &cpu) < 0)
J
Jiri Denemark 已提交
121 122
        goto cleanup;

J
Jiri Denemark 已提交
123
    ret = virCPUCompare(arch, host, cpu, failIncompatible);
J
Jiri Denemark 已提交
124

125
 cleanup:
J
Jiri Denemark 已提交
126 127 128 129 130 131
    virCPUDefFree(cpu);

    return ret;
}


132
/**
J
Jiri Denemark 已提交
133
 * virCPUCompare:
134
 *
J
Jiri Denemark 已提交
135
 * @arch: CPU architecture
136 137
 * @host: host CPU definition
 * @cpu: either guest or host CPU to be compared with @host
138
 * @failIncompatible: return an error instead of VIR_CPU_COMPARE_INCOMPATIBLE
139 140 141 142 143 144
 *
 * Compares the CPU described by @cpu with @host CPU.
 *
 * Returns VIR_CPU_COMPARE_ERROR on error, VIR_CPU_COMPARE_INCOMPATIBLE when
 * the two CPUs are incompatible, VIR_CPU_COMPARE_IDENTICAL when the two CPUs
 * are identical, VIR_CPU_COMPARE_SUPERSET when the @cpu CPU is a superset of
145 146 147
 * the @host CPU. If @failIncompatible is true, the function will return
 * VIR_CPU_COMPARE_ERROR (and set VIR_ERR_CPU_INCOMPATIBLE error) when the
 * two CPUs are incompatible.
148
 */
J
Jiri Denemark 已提交
149
virCPUCompareResult
J
Jiri Denemark 已提交
150 151 152 153
virCPUCompare(virArch arch,
              virCPUDefPtr host,
              virCPUDefPtr cpu,
              bool failIncompatible)
J
Jiri Denemark 已提交
154 155 156
{
    struct cpuArchDriver *driver;

J
Jiri Denemark 已提交
157 158
    VIR_DEBUG("arch=%s, host=%p, cpu=%p",
              virArchToString(arch), host, cpu);
159

J
Jiri Denemark 已提交
160
    if (!(driver = cpuGetSubDriver(arch)))
J
Jiri Denemark 已提交
161 162
        return VIR_CPU_COMPARE_ERROR;

J
Jiri Denemark 已提交
163
    if (!driver->compare) {
164 165
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot compare CPUs of %s architecture"),
J
Jiri Denemark 已提交
166
                       virArchToString(arch));
J
Jiri Denemark 已提交
167 168 169
        return VIR_CPU_COMPARE_ERROR;
    }

170
    return driver->compare(host, cpu, failIncompatible);
J
Jiri Denemark 已提交
171 172 173
}


174 175 176 177 178 179 180 181 182 183 184 185
/**
 * cpuDecode:
 *
 * @cpu: CPU definition stub to be filled in
 * @data: internal CPU data to be decoded into @cpu definition
 * @models: list of CPU models that can be considered when decoding @data
 *
 * Decodes internal CPU data into a CPU definition consisting of a CPU model
 * and a list of CPU features. The @cpu model stub is supposed to have arch,
 * type, match and fallback members set, this function will add the rest. If
 * @models list is NULL, all models supported by libvirt will be considered
 * when decoding the data. In general, this function will select the model
186
 * closest to the CPU specified by @data.
187 188 189 190 191 192
 *
 * For VIR_ARCH_I686 and VIR_ARCH_X86_64 architectures this means the computed
 * CPU definition will have the shortest possible list of additional features.
 *
 * Returns 0 on success, -1 on error.
 */
J
Jiri Denemark 已提交
193
int
194
cpuDecode(virCPUDefPtr cpu,
195
          const virCPUData *data,
196
          virDomainCapsCPUModelsPtr models)
J
Jiri Denemark 已提交
197 198 199
{
    struct cpuArchDriver *driver;

200
    VIR_DEBUG("cpu=%p, data=%p, models=%p", cpu, data, models);
201
    if (models) {
202
        size_t i;
203 204
        for (i = 0; i < models->nmodels; i++)
            VIR_DEBUG("models[%zu]=%s", i, models->models[i].name);
205 206
    }

207 208 209 210
    if (cpu->type > VIR_CPU_TYPE_GUEST ||
        cpu->mode != VIR_CPU_MODE_CUSTOM) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("invalid CPU definition stub"));
J
Jiri Denemark 已提交
211 212 213
        return -1;
    }

214
    if ((driver = cpuGetSubDriver(data->arch)) == NULL)
J
Jiri Denemark 已提交
215 216 217
        return -1;

    if (driver->decode == NULL) {
218 219
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot decode CPU data for %s architecture"),
220
                       virArchToString(cpu->arch));
J
Jiri Denemark 已提交
221 222 223
        return -1;
    }

224
    return driver->decode(cpu, data, models);
J
Jiri Denemark 已提交
225 226 227
}


228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
/**
 * cpuEncode:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition to be encoded into internal CPU driver representation
 * @forced: where to store CPU data corresponding to forced features
 * @required: where to store CPU data corresponding to required features
 * @optional: where to store CPU data corresponding to optional features
 * @disabled: where to store CPU data corresponding to disabled features
 * @forbidden: where to store CPU data corresponding to forbidden features
 * @vendor: where to store CPU data corresponding to CPU vendor
 *
 * Encode CPU definition from @cpu into internal CPU driver representation.
 * Any of @forced, @required, @optional, @disabled, @forbidden and @vendor
 * arguments can be NULL in case the caller is not interested in the
 * corresponding data.
 *
 * Returns 0 on success, -1 on error.
 */
J
Jiri Denemark 已提交
247
int
248
cpuEncode(virArch arch,
249
          const virCPUDef *cpu,
250 251 252 253 254 255
          virCPUDataPtr *forced,
          virCPUDataPtr *required,
          virCPUDataPtr *optional,
          virCPUDataPtr *disabled,
          virCPUDataPtr *forbidden,
          virCPUDataPtr *vendor)
J
Jiri Denemark 已提交
256 257 258
{
    struct cpuArchDriver *driver;

259
    VIR_DEBUG("arch=%s, cpu=%p, forced=%p, required=%p, "
J
Jiri Denemark 已提交
260
              "optional=%p, disabled=%p, forbidden=%p, vendor=%p",
261
              virArchToString(arch), cpu, forced, required,
J
Jiri Denemark 已提交
262
              optional, disabled, forbidden, vendor);
263

264 265 266 267 268 269
    if (!cpu->model) {
        virReportError(VIR_ERR_INVALID_ARG, "%s",
                       _("no guest CPU model specified"));
        return -1;
    }

270
    if ((driver = cpuGetSubDriver(arch)) == NULL)
J
Jiri Denemark 已提交
271 272 273
        return -1;

    if (driver->encode == NULL) {
274 275
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot encode CPU data for %s architecture"),
276
                       virArchToString(arch));
J
Jiri Denemark 已提交
277 278 279
        return -1;
    }

J
Jiri Denemark 已提交
280
    return driver->encode(arch, cpu, forced, required,
J
Jiri Denemark 已提交
281
                          optional, disabled, forbidden, vendor);
J
Jiri Denemark 已提交
282 283 284
}


J
Jiri Denemark 已提交
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
/**
 * virCPUDataNew:
 *
 * Returns an allocated memory for virCPUData or NULL on error.
 */
virCPUDataPtr
virCPUDataNew(virArch arch)
{
    virCPUDataPtr data;

    if (VIR_ALLOC(data) < 0)
        return NULL;

    data->arch = arch;

    return data;
}


304
/**
J
Jiri Denemark 已提交
305
 * virCPUDataFree:
306 307 308 309 310 311 312
 *
 * @data: CPU data structure to be freed
 *
 * Free internal CPU data.
 *
 * Returns nothing.
 */
J
Jiri Denemark 已提交
313
void
J
Jiri Denemark 已提交
314
virCPUDataFree(virCPUDataPtr data)
J
Jiri Denemark 已提交
315 316 317
{
    struct cpuArchDriver *driver;

J
Jiri Denemark 已提交
318
    VIR_DEBUG("data=%p", data);
319

J
Jiri Denemark 已提交
320
    if (!data)
J
Jiri Denemark 已提交
321 322
        return;

J
Jiri Denemark 已提交
323 324 325 326
    if ((driver = cpuGetSubDriver(data->arch)) && driver->dataFree)
        driver->dataFree(data);
    else
        VIR_FREE(data);
J
Jiri Denemark 已提交
327 328 329
}


330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
/**
 * virCPUGetHostIsSupported:
 *
 * @arch: CPU architecture
 *
 * Check whether virCPUGetHost is supported for @arch.
 *
 * Returns true if virCPUGetHost is supported, false otherwise.
 */
bool
virCPUGetHostIsSupported(virArch arch)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s", virArchToString(arch));

    return (driver = cpuGetSubDriver(arch)) && driver->getHost;
}


350
/**
351
 * virCPUGetHost:
352 353
 *
 * @arch: CPU architecture
354
 * @type: requested type of the CPU
355
 * @nodeInfo: simplified CPU topology (optional)
356
 * @models: list of CPU models that can be considered for host CPU
357
 *
358 359 360 361 362 363 364 365 366
 * Create CPU definition describing the host's CPU.
 *
 * The @type (either VIR_CPU_TYPE_HOST or VIR_CPU_TYPE_GUEST) specifies what
 * type of CPU definition should be created. Specifically, VIR_CPU_TYPE_HOST
 * CPUs may contain only features without any policy attribute. Requesting
 * VIR_CPU_TYPE_GUEST provides better results because the CPU is allowed to
 * contain disabled features.
 *
 * If @nodeInfo is not NULL (which is only allowed for VIR_CPU_TYPE_HOST CPUs),
367 368 369 370 371 372
 * the CPU definition will have topology (sockets, cores, threads) filled in
 * according to the content of @nodeInfo. The function fails only if @nodeInfo
 * was not passed in and the assigned CPU driver was not able to detect the
 * host CPU model. In other words, a CPU definition containing just the
 * topology is a successful result even if detecting the host CPU model fails.
 *
373 374 375 376 377
 * It possible to limit the CPU model which may appear in the created CPU
 * definition by passing non-NULL @models list. This is useful when requesting
 * a CPU model usable on a specific hypervisor. If @models is NULL, any CPU
 * model known to libvirt may appear in the result.
 *
378
 * Returns host CPU definition or NULL on error.
379
 */
380 381
virCPUDefPtr
virCPUGetHost(virArch arch,
382
              virCPUType type,
383
              virNodeInfoPtr nodeInfo,
384
              virDomainCapsCPUModelsPtr models)
J
Jiri Denemark 已提交
385 386
{
    struct cpuArchDriver *driver;
387
    virCPUDefPtr cpu = NULL;
J
Jiri Denemark 已提交
388

389
    VIR_DEBUG("arch=%s, type=%s, nodeInfo=%p, models=%p",
390
              virArchToString(arch), virCPUTypeToString(type), nodeInfo,
391
              models);
392

393 394 395
    if (!(driver = cpuGetSubDriver(arch)))
        return NULL;

396
    cpu = virCPUDefNew();
J
Jiri Denemark 已提交
397

398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
    switch (type) {
    case VIR_CPU_TYPE_HOST:
        cpu->arch = arch;
        cpu->type = type;
        break;

    case VIR_CPU_TYPE_GUEST:
        if (nodeInfo) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("cannot set topology for CPU type '%s'"),
                           virCPUTypeToString(type));
            goto error;
        }
        cpu->type = type;
        break;

    case VIR_CPU_TYPE_AUTO:
    case VIR_CPU_TYPE_LAST:
        virReportError(VIR_ERR_INVALID_ARG,
                       _("unsupported CPU type: %s"),
                       virCPUTypeToString(type));
        goto error;
    }
421 422 423

    if (nodeInfo) {
        cpu->sockets = nodeInfo->sockets;
424
        cpu->dies = 1;
425 426 427 428 429 430 431 432
        cpu->cores = nodeInfo->cores;
        cpu->threads = nodeInfo->threads;
    }

    /* Try to get the host CPU model, but don't really fail if nodeInfo is
     * filled in.
     */
    if (driver->getHost) {
433
        if (driver->getHost(cpu, models) < 0 &&
434
            !nodeInfo)
435 436 437 438 439
            goto error;
    } else if (nodeInfo) {
        VIR_DEBUG("cannot detect host CPU model for %s architecture",
                  virArchToString(arch));
    } else {
440
        virReportError(VIR_ERR_NO_SUPPORT,
441
                       _("cannot detect host CPU model for %s architecture"),
442
                       virArchToString(arch));
443
        goto error;
J
Jiri Denemark 已提交
444 445
    }

446 447 448 449 450
    return cpu;

 error:
    virCPUDefFree(cpu);
    return NULL;
J
Jiri Denemark 已提交
451 452 453
}


M
Martin Kletzander 已提交
454 455 456 457 458
virCPUDefPtr
virCPUProbeHost(virArch arch)
{
    virNodeInfo nodeinfo;

459
    if (virCapabilitiesGetNodeInfo(&nodeinfo) < 0)
M
Martin Kletzander 已提交
460 461
        return NULL;

462
    return virCPUGetHost(arch, VIR_CPU_TYPE_HOST, &nodeinfo, NULL);
M
Martin Kletzander 已提交
463 464 465
}


466
/**
467
 * virCPUBaseline:
468
 *
469
 * @arch: CPU architecture, use VIR_ARCH_NONE to autodetect from @cpus
470 471 472
 * @cpus: list of host CPU definitions
 * @ncpus: number of CPUs in @cpus
 * @models: list of CPU models that can be considered for the baseline CPU
473
 * @features: optional NULL terminated list of allowed features
474
 * @migratable: requests non-migratable features to be removed from the result
475 476
 *
 * Computes the most feature-rich CPU which is compatible with all given
477
 * CPUs. If @models is NULL, all models supported by libvirt will
478 479 480 481 482
 * be considered when computing the baseline CPU model, otherwise the baseline
 * CPU model will be one of the provided CPU @models.
 *
 * Returns baseline CPU definition or NULL on error.
 */
483
virCPUDefPtr
484 485
virCPUBaseline(virArch arch,
               virCPUDefPtr *cpus,
486 487
               unsigned int ncpus,
               virDomainCapsCPUModelsPtr models,
488
               const char **features,
489
               bool migratable)
490 491
{
    struct cpuArchDriver *driver;
492
    size_t i;
493

494 495
    VIR_DEBUG("arch=%s, ncpus=%u, models=%p, features=%p, migratable=%d",
              virArchToString(arch), ncpus, models, features, migratable);
496 497
    if (cpus) {
        for (i = 0; i < ncpus; i++)
498
            VIR_DEBUG("cpus[%zu]=%p", i, cpus[i]);
499 500
    }
    if (models) {
501 502
        for (i = 0; i < models->nmodels; i++)
            VIR_DEBUG("models[%zu]=%s", i, models->models[i].name);
503
    }
504

505
    if (!cpus && ncpus != 0) {
506 507
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       "%s", _("nonzero ncpus doesn't match with NULL cpus"));
508 509 510 511
        return NULL;
    }

    if (ncpus < 1) {
512
        virReportError(VIR_ERR_INVALID_ARG, "%s", _("no CPUs given"));
513 514 515
        return NULL;
    }

516 517 518 519 520 521 522 523 524 525 526 527 528
    for (i = 0; i < ncpus; i++) {
        if (!cpus[i]) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("invalid CPU definition at index %zu"), i);
            return NULL;
        }
        if (!cpus[i]->model) {
            virReportError(VIR_ERR_INVALID_ARG,
                           _("no CPU model specified at index %zu"), i);
            return NULL;
        }
    }

529 530 531
    if (arch == VIR_ARCH_NONE)
        arch = cpus[0]->arch;

532
    if (!(driver = cpuGetSubDriver(arch)))
533 534
        return NULL;

535
    if (!driver->baseline) {
536 537
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot compute baseline CPU of %s architecture"),
538
                       virArchToString(arch));
539 540 541
        return NULL;
    }

542
    return driver->baseline(cpus, ncpus, models, features, migratable);
543
}
544 545


546
/**
J
Jiri Denemark 已提交
547
 * virCPUUpdate:
548
 *
J
Jiri Denemark 已提交
549 550
 * @arch: CPU architecture
 * @guest: guest CPU definition to be updated
551 552 553
 * @host: host CPU definition
 *
 * Updates @guest CPU definition according to @host CPU. This is required to
J
Jiri Denemark 已提交
554 555 556 557 558
 * support guest CPU definitions specified relatively to host CPU, such as
 * CPUs with VIR_CPU_MODE_CUSTOM and optional features or
 * VIR_CPU_MATCH_MINIMUM, or CPUs with VIR_CPU_MODE_HOST_MODEL.
 * When the guest CPU was not specified relatively, the function does nothing
 * and returns success.
559 560 561
 *
 * Returns 0 on success, -1 on error.
 */
562
int
J
Jiri Denemark 已提交
563 564 565
virCPUUpdate(virArch arch,
             virCPUDefPtr guest,
             const virCPUDef *host)
566 567 568
{
    struct cpuArchDriver *driver;

J
Jiri Denemark 已提交
569 570 571
    VIR_DEBUG("arch=%s, guest=%p mode=%s model=%s, host=%p model=%s",
              virArchToString(arch), guest, virCPUModeTypeToString(guest->mode),
              NULLSTR(guest->model), host, NULLSTR(host ? host->model : NULL));
572

J
Jiri Denemark 已提交
573
    if (!(driver = cpuGetSubDriver(arch)))
574 575
        return -1;

J
Jiri Denemark 已提交
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600
    if (guest->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
        return 0;

    if (guest->mode == VIR_CPU_MODE_CUSTOM &&
        guest->match != VIR_CPU_MATCH_MINIMUM) {
        size_t i;
        bool optional = false;

        for (i = 0; i < guest->nfeatures; i++) {
            if (guest->features[i].policy == VIR_CPU_FEATURE_OPTIONAL) {
                optional = true;
                break;
            }
        }

        if (!optional)
            return 0;
    }

    /* We get here if guest CPU is either
     *  - host-model
     *  - custom with minimum match
     *  - custom with optional features
     */
    if (!driver->update) {
601
        virReportError(VIR_ERR_NO_SUPPORT,
J
Jiri Denemark 已提交
602 603
                       _("cannot update guest CPU for %s architecture"),
                       virArchToString(arch));
604 605 606
        return -1;
    }

J
Jiri Denemark 已提交
607 608 609 610 611
    if (driver->update(guest, host) < 0)
        return -1;

    VIR_DEBUG("model=%s", NULLSTR(guest->model));
    return 0;
612
}
D
Daniel P. Berrange 已提交
613

614

615 616 617 618 619 620 621 622 623 624
/**
 * virCPUUpdateLive:
 *
 * @arch: CPU architecture
 * @cpu: guest CPU definition to be updated
 * @dataEnabled: CPU data of the virtual CPU
 * @dataDisabled: CPU data with features requested by @cpu but disabled by the
 *                hypervisor
 *
 * Update custom mode CPU according to the virtual CPU created by the
625 626
 * hypervisor. The function refuses to update the CPU in case cpu->check is set
 * to VIR_CPU_CHECK_FULL.
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
 *
 * Returns -1 on error,
 *          0 when the CPU was successfully updated,
 *          1 when the operation does not make sense on the CPU or it is not
 *            supported for the given architecture.
 */
int
virCPUUpdateLive(virArch arch,
                 virCPUDefPtr cpu,
                 virCPUDataPtr dataEnabled,
                 virCPUDataPtr dataDisabled)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpu=%p, dataEnabled=%p, dataDisabled=%p",
              virArchToString(arch), cpu, dataEnabled, dataDisabled);

    if (!(driver = cpuGetSubDriver(arch)))
        return -1;

    if (!driver->updateLive)
        return 1;

650 651
    if (cpu->mode == VIR_CPU_MODE_CUSTOM ||
        cpu->check == VIR_CPU_CHECK_FULL) {
652 653
        if (driver->updateLive(cpu, dataEnabled, dataDisabled) < 0)
            return -1;
654

655 656
        return 0;
    }
657

658
    return 1;
659 660 661
}


662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
/**
 * virCPUCheckFeature:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition
 * @feature: feature to be checked for
 *
 * Checks whether @feature is supported by the CPU described by @cpu.
 *
 * Returns 1 if the feature is supported, 0 if it's not supported, or
 * -1 on error.
 */
int
virCPUCheckFeature(virArch arch,
                   const virCPUDef *cpu,
                   const char *feature)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpu=%p, feature=%s",
              virArchToString(arch), cpu, feature);

    if (!(driver = cpuGetSubDriver(arch)))
        return -1;

    if (!driver->checkFeature) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot check guest CPU feature for %s architecture"),
                       virArchToString(arch));
        return -1;
    }

    return driver->checkFeature(cpu, feature);
}


698
/**
699
 * virCPUDataCheckFeature:
700
 *
701
 * @data: CPU data
702 703 704 705 706 707 708
 * @feature: feature to be checked for
 *
 * Checks whether @feature is supported by the CPU described by @data.
 *
 * Returns 1 if the feature is supported, 0 if it's not supported, or
 * -1 on error.
 */
D
Daniel P. Berrange 已提交
709
int
710 711
virCPUDataCheckFeature(const virCPUData *data,
                       const char *feature)
D
Daniel P. Berrange 已提交
712 713 714
{
    struct cpuArchDriver *driver;

715 716
    VIR_DEBUG("arch=%s, data=%p, feature=%s",
              virArchToString(data->arch), data, feature);
D
Daniel P. Berrange 已提交
717

718
    if (!(driver = cpuGetSubDriver(data->arch)))
D
Daniel P. Berrange 已提交
719 720
        return -1;

721
    if (!driver->dataCheckFeature) {
722
        virReportError(VIR_ERR_NO_SUPPORT,
723
                       _("cannot check guest CPU feature for %s architecture"),
J
Jiri Denemark 已提交
724
                       virArchToString(data->arch));
D
Daniel P. Berrange 已提交
725 726 727
        return -1;
    }

728
    return driver->dataCheckFeature(data, feature);
D
Daniel P. Berrange 已提交
729
}
730

731 732

/**
J
Jiri Denemark 已提交
733
 * virCPUDataFormat:
734 735 736 737 738 739 740
 *
 * @data: internal CPU representation
 *
 * Formats @data into XML for test purposes.
 *
 * Returns string representation of the XML describing @data or NULL on error.
 */
741
char *
J
Jiri Denemark 已提交
742
virCPUDataFormat(const virCPUData *data)
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("data=%p", data);

    if (!(driver = cpuGetSubDriver(data->arch)))
        return NULL;

    if (!driver->dataFormat) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot format %s CPU data"),
                       virArchToString(data->arch));
        return NULL;
    }

    return driver->dataFormat(data);
}

761 762

/**
J
Jiri Denemark 已提交
763
 * virCPUDataParse:
764
 *
J
Jiri Denemark 已提交
765
 * @xmlStr: XML string produced by virCPUDataFormat
766 767 768 769 770
 *
 * Parses XML representation of virCPUData structure for test purposes.
 *
 * Returns internal CPU data structure parsed from the XML or NULL on error.
 */
771
virCPUDataPtr
J
Jiri Denemark 已提交
772
virCPUDataParse(const char *xmlStr)
773 774
{
    struct cpuArchDriver *driver;
775 776 777 778
    xmlDocPtr xml = NULL;
    xmlXPathContextPtr ctxt = NULL;
    virCPUDataPtr data = NULL;
    char *arch = NULL;
779

780
    VIR_DEBUG("xmlStr=%s", xmlStr);
781

782 783 784 785 786 787 788 789 790 791 792 793 794 795
    if (!(xml = virXMLParseStringCtxt(xmlStr, _("CPU data"), &ctxt))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("cannot parse CPU data"));
        goto cleanup;
    }

    if (!(arch = virXPathString("string(/cpudata/@arch)", ctxt))) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("missing CPU data architecture"));
        goto cleanup;
    }

    if (!(driver = cpuGetSubDriverByName(arch)))
        goto cleanup;
796 797 798

    if (!driver->dataParse) {
        virReportError(VIR_ERR_NO_SUPPORT,
799 800
                       _("cannot parse %s CPU data"), arch);
        goto cleanup;
801 802
    }

803 804 805 806 807 808 809
    data = driver->dataParse(ctxt);

 cleanup:
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(xml);
    VIR_FREE(arch);
    return data;
810 811
}

812 813 814 815 816 817 818

/** virCPUModelIsAllowed:
 *
 * @model: CPU model to be checked
 * @models: list of supported CPU models
 *
 * Checks whether @model can be found in the list of supported @models.
819
 * If @models is NULL, all models are supported.
820 821 822
 *
 * Returns true if @model is supported, false otherwise.
 */
823
bool
824
virCPUModelIsAllowed(const char *model,
825
                     virDomainCapsCPUModelsPtr models)
826
{
827
    if (!models)
828 829
        return true;

830
    return !!virDomainCapsCPUModelsGet(models, model);
831
}
832

833

834
/**
J
Jiri Denemark 已提交
835
 * virCPUGetModels:
836
 *
J
Jiri Denemark 已提交
837
 * @arch: CPU architecture
838
 * @models: where to store the NULL-terminated list of supported models
839
 *
840 841 842 843
 * Fetches all CPU models supported by libvirt on @archName. If there are
 * no restrictions on CPU models on @archName (i.e., the CPU model is just
 * passed directly to a hypervisor), this function returns 0 and sets
 * @models to NULL.
844
 *
845 846
 * Returns number of supported CPU models, 0 if any CPU model is supported,
 * or -1 on error.
847
 */
848
int
J
Jiri Denemark 已提交
849
virCPUGetModels(virArch arch, char ***models)
850 851 852
{
    struct cpuArchDriver *driver;

J
Jiri Denemark 已提交
853
    VIR_DEBUG("arch=%s", virArchToString(arch));
854

855
    if (!(driver = cpuGetSubDriver(arch)))
856
        return -1;
857

858
    if (!driver->getModels) {
859 860 861
        if (models)
            *models = NULL;
        return 0;
862
    }
863

864
    return driver->getModels(models);
865
}
J
Jiri Denemark 已提交
866 867 868 869 870 871 872


/**
 * virCPUTranslate:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition to be translated
873
 * @models: list of allowed CPU models (NULL if all are allowed)
J
Jiri Denemark 已提交
874 875 876 877 878 879 880 881 882 883 884 885
 *
 * Translates @cpu model (if allowed by @cpu->fallback) to a closest CPU model
 * from @models list.
 *
 * The function does nothing (and returns 0) if @cpu does not have to be
 * translated.
 *
 * Returns -1 on error, 0 on success.
 */
int
virCPUTranslate(virArch arch,
                virCPUDefPtr cpu,
886
                virDomainCapsCPUModelsPtr models)
J
Jiri Denemark 已提交
887 888 889
{
    struct cpuArchDriver *driver;

890 891
    VIR_DEBUG("arch=%s, cpu=%p, model=%s, models=%p",
              virArchToString(arch), cpu, NULLSTR(cpu->model), models);
J
Jiri Denemark 已提交
892 893 894 895 896 897 898 899

    if (!(driver = cpuGetSubDriver(arch)))
        return -1;

    if (cpu->mode == VIR_CPU_MODE_HOST_MODEL ||
        cpu->mode == VIR_CPU_MODE_HOST_PASSTHROUGH)
        return 0;

900
    if (virCPUModelIsAllowed(cpu->model, models))
J
Jiri Denemark 已提交
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916
        return 0;

    if (cpu->fallback != VIR_CPU_FALLBACK_ALLOW) {
        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                       _("CPU model %s is not supported by hypervisor"),
                       cpu->model);
        return -1;
    }

    if (!driver->translate) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot translate CPU model %s to a supported model"),
                       cpu->model);
        return -1;
    }

917
    if (driver->translate(cpu, models) < 0)
J
Jiri Denemark 已提交
918 919 920 921 922
        return -1;

    VIR_DEBUG("model=%s", NULLSTR(cpu->model));
    return 0;
}
923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957


/**
 * virCPUConvertLegacy:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition to be converted
 *
 * Convert legacy CPU definition into one that the corresponding cpu driver
 * will be able to work with. Currently this is only implemented by the PPC
 * driver, which needs to convert legacy POWERx_v* names into POWERx.
 *
 * Returns -1 on error, 0 on success.
 */
int
virCPUConvertLegacy(virArch arch,
                    virCPUDefPtr cpu)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpu=%p, model=%s",
              virArchToString(arch), cpu, NULLSTR(cpu->model));

    if (!(driver = cpuGetSubDriver(arch)))
        return -1;

    if (!driver->convertLegacy)
        return 0;

    if (driver->convertLegacy(cpu) < 0)
        return -1;

    VIR_DEBUG("model=%s", NULLSTR(cpu->model));
    return 0;
}
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007


static int
virCPUFeatureCompare(const void *p1,
                     const void *p2)
{
    const virCPUFeatureDef *f1 = p1;
    const virCPUFeatureDef *f2 = p2;

    return strcmp(f1->name, f2->name);
}


/**
 * virCPUExpandFeatures:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition to be expanded
 *
 * Add all features implicitly enabled by the CPU model to the list of
 * features. The @cpu is expected to be either a host or a guest representation
 * of a host CPU, i.e., only VIR_CPU_FEATURE_REQUIRE and
 * VIR_CPU_FEATURE_DISABLE policies are supported.
 *
 * The updated list of features in the CPU definition is sorted.
 *
 * Return -1 on error, 0 on success.
 */
int
virCPUExpandFeatures(virArch arch,
                     virCPUDefPtr cpu)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpu=%p, model=%s, nfeatures=%zu",
              virArchToString(arch), cpu, NULLSTR(cpu->model), cpu->nfeatures);

    if (!(driver = cpuGetSubDriver(arch)))
        return -1;

    if (driver->expandFeatures &&
        driver->expandFeatures(cpu) < 0)
        return -1;

    qsort(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
          virCPUFeatureCompare);

    VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
    return 0;
}
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038


/**
 * virCPUCopyMigratable:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition to be copied
 *
 * Makes a copy of @cpu with all features which would block migration removed.
 * If this doesn't make sense for a given architecture, the function returns a
 * plain copy of @cpu (i.e., a copy with no features removed).
 *
 * Returns the copy of the CPU or NULL on error.
 */
virCPUDefPtr
virCPUCopyMigratable(virArch arch,
                     virCPUDefPtr cpu)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpu=%p, model=%s",
              virArchToString(arch), cpu, NULLSTR(cpu->model));

    if (!(driver = cpuGetSubDriver(arch)))
        return NULL;

    if (driver->copyMigratable)
        return driver->copyMigratable(cpu);
    else
        return virCPUDefCopy(cpu);
}
1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067


/**
 * virCPUValidateFeatures:
 *
 * @arch: CPU architecture
 * @cpu: CPU definition to be checked
 *
 * Checks whether all CPU features specified in @cpu are valid.
 *
 * Returns 0 on success (all features are valid), -1 on error.
 */
int
virCPUValidateFeatures(virArch arch,
                       virCPUDefPtr cpu)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpu=%p, nfeatures=%zu",
              virArchToString(arch), cpu, cpu->nfeatures);

    if (!(driver = cpuGetSubDriver(arch)))
        return -1;

    if (driver->validateFeatures)
        return driver->validateFeatures(cpu);
    else
        return 0;
}
1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100


/**
 * virCPUDataAddFeature:
 *
 * @cpuData: CPU data
 * @name: feature to be added to @cpuData
 *
 * Adds a feature called @name to @cpuData.
 *
 * Returns 0 on success, -1 on error.
 */
int
virCPUDataAddFeature(virCPUDataPtr cpuData,
                     const char *name)
{
    struct cpuArchDriver *driver;

    VIR_DEBUG("arch=%s, cpuData=%p, name=%s",
              virArchToString(cpuData->arch), cpuData, name);

    if (!(driver = cpuGetSubDriver(cpuData->arch)))
        return -1;

    if (!driver->dataAddFeature) {
        virReportError(VIR_ERR_NO_SUPPORT,
                       _("cannot add guest CPU feature for %s architecture"),
                       virArchToString(cpuData->arch));
        return -1;
    }

    return driver->dataAddFeature(cpuData, name);
}
1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124


/**
 * virCPUArchIsSupported:
 *
 * @arch: CPU architecture
 *
 * Returns true if the architecture is supported by any CPU driver.
 */
bool
virCPUArchIsSupported(virArch arch)
{
    size_t i;
    size_t j;

    for (i = 0; i < G_N_ELEMENTS(drivers); i++) {
        for (j = 0; j < drivers[i]->narch; j++) {
            if (arch == drivers[i]->arch[j])
                return true;
        }
    }

    return false;
}