mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-22 04:25:18 +00:00
Adds CPU selection infrastructure
Each driver supporting CPU selection must fill in host CPU capabilities. When filling them, drivers for hypervisors running on the same node as libvirtd can use cpuNodeData() to obtain raw CPU data. Other drivers, such as VMware, need to implement their own way of getting such data. Raw data can be decoded into virCPUDefPtr using cpuDecode() function. When implementing virConnectCompareCPU(), a hypervisor driver can just call cpuCompareXML() function with host CPU capabilities. For each guest for which a driver supports selecting CPU models, it must set the appropriate feature in guest's capabilities: virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0) Actions needed when a domain is being created depend on whether the hypervisor understands raw CPU data (currently CPUID for i686, x86_64 architectures) or symbolic names has to be used. Typical use by hypervisors which prefer CPUID (such as VMware and Xen): - convert guest CPU configuration from domain's XML into a set of raw data structures each representing one of the feature policies: cpuEncode(conn, architecture, guest_cpu_config, &forced_data, &required_data, &optional_data, &disabled_data, &forbidden_data) - create a mask or whatever the hypervisor expects to see and pass it to the hypervisor Typical use by hypervisors with symbolic model names (such as QEMU): - get raw CPU data for a computed guest CPU: cpuGuestData(conn, host_cpu, guest_cpu_config, &data) - decode raw data into virCPUDefPtr with a possible restriction on allowed model names: cpuDecode(conn, guest, data, n_allowed_models, allowed_models) - pass guest->model and guest->features to the hypervisor * src/cpu/cpu.c src/cpu/cpu.h src/cpu/cpu_generic.c src/cpu/cpu_generic.h src/cpu/cpu_map.c src/cpu/cpu_map.h src/cpu/cpu_x86.c src/cpu/cpu_x86.h src/cpu/cpu_x86_data.h * configure.in: check for CPUID instruction * src/Makefile.am: glue the new files in * src/libvirt_private.syms: add new private symbols * po/POTFILES.in: add new cpu files containing translatable strings
This commit is contained in:
parent
e104269398
commit
7286882c34
20
configure.in
20
configure.in
@ -78,6 +78,26 @@ AC_SUBST(VERSION_SCRIPT_FLAGS)
|
||||
|
||||
LIBVIRT_COMPILE_WARNINGS([maximum])
|
||||
|
||||
AC_MSG_CHECKING([for CPUID instruction])
|
||||
AC_COMPILE_IFELSE(AC_LANG_PROGRAM(
|
||||
[[
|
||||
#include <stdint.h>
|
||||
]],
|
||||
[[
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
asm volatile (
|
||||
"cpuid"
|
||||
: "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
|
||||
: "a" (eax));
|
||||
]]),
|
||||
[have_cpuid=yes],
|
||||
[have_cpuid=no])
|
||||
if test "x$have_cpuid" = xyes; then
|
||||
AC_DEFINE_UNQUOTED([HAVE_CPUID], 1, [whether CPUID instruction is supported])
|
||||
fi
|
||||
AC_MSG_RESULT([$have_cpuid])
|
||||
|
||||
|
||||
dnl Support large files / 64 bit seek offsets.
|
||||
dnl Use --disable-largefile if you don't want this.
|
||||
AC_SYS_LARGEFILE
|
||||
|
@ -10,6 +10,9 @@ src/conf/node_device_conf.c
|
||||
src/conf/secret_conf.c
|
||||
src/conf/storage_conf.c
|
||||
src/conf/storage_encryption_conf.c
|
||||
src/cpu/cpu.c
|
||||
src/cpu/cpu_map.c
|
||||
src/cpu/cpu_x86.c
|
||||
src/datatypes.c
|
||||
src/interface/netcf_driver.c
|
||||
src/libvirt.c
|
||||
|
@ -16,6 +16,7 @@ INCLUDES = \
|
||||
-DSBINDIR=\""$(sbindir)"\" \
|
||||
-DSYSCONF_DIR="\"$(sysconfdir)\"" \
|
||||
-DLOCALEBASEDIR=\""$(datadir)/locale"\" \
|
||||
-DDATADIR=\""$(datadir)/libvirt"\" \
|
||||
-DLOCAL_STATE_DIR=\""$(localstatedir)"\" \
|
||||
-DGETTEXT_PACKAGE=\"$(PACKAGE)\" \
|
||||
$(WARN_CFLAGS) \
|
||||
@ -280,6 +281,11 @@ NODE_DEVICE_DRIVER_UDEV_SOURCES = \
|
||||
node_device/node_device_udev.c \
|
||||
node_device/node_device_udev.h
|
||||
|
||||
CPU_SOURCES = \
|
||||
cpu/cpu.h cpu/cpu.c \
|
||||
cpu/cpu_generic.h cpu/cpu_generic.c \
|
||||
cpu/cpu_x86.h cpu/cpu_x86.c cpu/cpu_x86_data.h \
|
||||
cpu/cpu_map.h cpu/cpu_map.c
|
||||
|
||||
#########################
|
||||
#
|
||||
@ -301,6 +307,12 @@ libvirt_conf_la_SOURCES = $(CONF_SOURCES)
|
||||
libvirt_conf_la_CFLAGS =
|
||||
libvirt_conf_la_LDFLAGS =
|
||||
|
||||
noinst_LTLIBRARIES += libvirt_cpu.la
|
||||
libvirt_la_LIBADD += libvirt_cpu.la
|
||||
libvirt_cpu_la_CFLAGS = \
|
||||
-I@top_srcdir@/src/conf
|
||||
libvirt_cpu_la_SOURCES = $(CPU_SOURCES)
|
||||
|
||||
|
||||
noinst_LTLIBRARIES += libvirt_driver.la
|
||||
libvirt_la_LIBADD += libvirt_driver.la
|
||||
|
241
src/cpu/cpu.c
Normal file
241
src/cpu/cpu.c
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* cpu.c: internal functions for CPU manipulation
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "xml.h"
|
||||
#include "cpu.h"
|
||||
#include "cpu_x86.h"
|
||||
#include "cpu_generic.h"
|
||||
|
||||
|
||||
#define NR_DRIVERS ARRAY_CARDINALITY(drivers)
|
||||
#define VIR_FROM_THIS VIR_FROM_CPU
|
||||
|
||||
static struct cpuArchDriver *drivers[] = {
|
||||
&cpuDriverX86,
|
||||
/* generic driver must always be the last one */
|
||||
&cpuDriverGeneric
|
||||
};
|
||||
|
||||
|
||||
static struct cpuArchDriver *
|
||||
cpuGetSubDriver(virConnectPtr conn,
|
||||
const char *arch)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
if (arch == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("undefined hardware architecture"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < NR_DRIVERS - 1; i++) {
|
||||
for (j = 0; j < drivers[i]->narch; j++) {
|
||||
if (STREQ(arch, drivers[i]->arch[j]))
|
||||
return drivers[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* use generic driver by default */
|
||||
return drivers[NR_DRIVERS - 1];
|
||||
}
|
||||
|
||||
|
||||
virCPUCompareResult
|
||||
cpuCompareXML(virConnectPtr conn,
|
||||
virCPUDefPtr host,
|
||||
const char *xml)
|
||||
{
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
virCPUDefPtr cpu = NULL;
|
||||
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
|
||||
|
||||
doc = xmlParseMemory(xml, strlen(xml));
|
||||
|
||||
if (doc == NULL || (ctxt = xmlXPathNewContext(doc)) == NULL) {
|
||||
virReportOOMError(conn);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ctxt->node = xmlDocGetRootElement(doc);
|
||||
|
||||
cpu = virCPUDefParseXML(conn, ctxt->node, ctxt, VIR_CPU_TYPE_AUTO);
|
||||
if (cpu == NULL)
|
||||
goto cleanup;
|
||||
|
||||
ret = cpuCompare(conn, host, cpu);
|
||||
|
||||
cleanup:
|
||||
virCPUDefFree(cpu);
|
||||
xmlXPathFreeContext(ctxt);
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
virCPUCompareResult
|
||||
cpuCompare(virConnectPtr conn,
|
||||
virCPUDefPtr host,
|
||||
virCPUDefPtr cpu)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
if ((driver = cpuGetSubDriver(conn, host->arch)) == NULL)
|
||||
return VIR_CPU_COMPARE_ERROR;
|
||||
|
||||
if (driver->compare == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("cannot compare CPUs of %s architecture"),
|
||||
host->arch);
|
||||
return VIR_CPU_COMPARE_ERROR;
|
||||
}
|
||||
|
||||
return driver->compare(host, cpu);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpuDecode(virConnectPtr conn,
|
||||
virCPUDefPtr cpu,
|
||||
const union cpuData *data,
|
||||
unsigned int nmodels,
|
||||
const char **models)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
if (cpu == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_INTERNAL_ERROR,
|
||||
_("invalid CPU definition"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((driver = cpuGetSubDriver(conn, cpu->arch)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (driver->decode == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("cannot decode CPU data for %s architecture"),
|
||||
cpu->arch);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return driver->decode(cpu, data, nmodels, models);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cpuEncode(virConnectPtr conn,
|
||||
const char *arch,
|
||||
const virCPUDefPtr cpu,
|
||||
union cpuData **forced,
|
||||
union cpuData **required,
|
||||
union cpuData **optional,
|
||||
union cpuData **disabled,
|
||||
union cpuData **forbidden)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
if ((driver = cpuGetSubDriver(conn, arch)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (driver->encode == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("cannot encode CPU data for %s architecture"),
|
||||
arch);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return driver->encode(cpu, forced, required,
|
||||
optional, disabled, forbidden);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cpuDataFree(virConnectPtr conn,
|
||||
const char *arch,
|
||||
union cpuData *data)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
if ((driver = cpuGetSubDriver(conn, arch)) == NULL)
|
||||
return;
|
||||
|
||||
if (driver->free == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("cannot free CPU data for %s architecture"),
|
||||
arch);
|
||||
return;
|
||||
}
|
||||
|
||||
driver->free(data);
|
||||
}
|
||||
|
||||
|
||||
union cpuData *
|
||||
cpuNodeData(virConnectPtr conn,
|
||||
const char *arch)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
if ((driver = cpuGetSubDriver(conn, arch)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (driver->nodeData == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("cannot get node CPU data for %s architecture"),
|
||||
arch);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return driver->nodeData();
|
||||
}
|
||||
|
||||
|
||||
virCPUCompareResult
|
||||
cpuGuestData(virConnectPtr conn,
|
||||
virCPUDefPtr host,
|
||||
virCPUDefPtr guest,
|
||||
union cpuData **data)
|
||||
{
|
||||
struct cpuArchDriver *driver;
|
||||
|
||||
if ((driver = cpuGetSubDriver(conn, host->arch)) == NULL)
|
||||
return VIR_CPU_COMPARE_ERROR;
|
||||
|
||||
if (driver->guestData == NULL) {
|
||||
virCPUReportError(conn, VIR_ERR_NO_SUPPORT,
|
||||
_("cannot compute guest CPU data for %s architecture"),
|
||||
host->arch);
|
||||
return VIR_CPU_COMPARE_ERROR;
|
||||
}
|
||||
|
||||
return driver->guestData(host, guest, data);
|
||||
}
|
129
src/cpu/cpu.h
Normal file
129
src/cpu/cpu.h
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* cpu.h: internal functions for CPU manipulation
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_CPU_H__
|
||||
#define __VIR_CPU_H__
|
||||
|
||||
#include "virterror_internal.h"
|
||||
#include "datatypes.h"
|
||||
#include "conf/cpu_conf.h"
|
||||
#include "cpu_x86_data.h"
|
||||
|
||||
|
||||
#define virCPUReportError(conn, code, fmt...) \
|
||||
virReportErrorHelper(conn, VIR_FROM_CPU, code, __FILE__, \
|
||||
__FUNCTION__, __LINE__, fmt)
|
||||
|
||||
|
||||
union cpuData {
|
||||
struct cpuX86Data x86;
|
||||
/* generic driver needs no data */
|
||||
};
|
||||
|
||||
|
||||
typedef virCPUCompareResult
|
||||
(*cpuArchCompare) (virCPUDefPtr host,
|
||||
virCPUDefPtr cpu);
|
||||
|
||||
typedef int
|
||||
(*cpuArchDecode) (virCPUDefPtr cpu,
|
||||
const union cpuData *data,
|
||||
unsigned int nmodels,
|
||||
const char **models);
|
||||
|
||||
typedef int
|
||||
(*cpuArchEncode) (const virCPUDefPtr cpu,
|
||||
union cpuData **forced,
|
||||
union cpuData **required,
|
||||
union cpuData **optional,
|
||||
union cpuData **disabled,
|
||||
union cpuData **forbidden);
|
||||
|
||||
typedef void
|
||||
(*cpuArchDataFree) (union cpuData *data);
|
||||
|
||||
typedef union cpuData *
|
||||
(*cpuArchNodeData) (void);
|
||||
|
||||
typedef virCPUCompareResult
|
||||
(*cpuArchGuestData) (virCPUDefPtr host,
|
||||
virCPUDefPtr guest,
|
||||
union cpuData **data);
|
||||
|
||||
|
||||
struct cpuArchDriver {
|
||||
const char *name;
|
||||
const char **arch;
|
||||
unsigned int narch;
|
||||
cpuArchCompare compare;
|
||||
cpuArchDecode decode;
|
||||
cpuArchEncode encode;
|
||||
cpuArchDataFree free;
|
||||
cpuArchNodeData nodeData;
|
||||
cpuArchGuestData guestData;
|
||||
};
|
||||
|
||||
|
||||
extern virCPUCompareResult
|
||||
cpuCompareXML(virConnectPtr conn,
|
||||
virCPUDefPtr host,
|
||||
const char *xml);
|
||||
|
||||
extern virCPUCompareResult
|
||||
cpuCompare (virConnectPtr conn,
|
||||
virCPUDefPtr host,
|
||||
virCPUDefPtr cpu);
|
||||
|
||||
extern int
|
||||
cpuDecode (virConnectPtr conn,
|
||||
virCPUDefPtr cpu,
|
||||
const union cpuData *data,
|
||||
unsigned int nmodels,
|
||||
const char **models);
|
||||
|
||||
extern int
|
||||
cpuEncode (virConnectPtr conn,
|
||||
const char *arch,
|
||||
const virCPUDefPtr cpu,
|
||||
union cpuData **forced,
|
||||
union cpuData **required,
|
||||
union cpuData **optional,
|
||||
union cpuData **disabled,
|
||||
union cpuData **forbidden);
|
||||
|
||||
extern void
|
||||
cpuDataFree (virConnectPtr conn,
|
||||
const char *arch,
|
||||
union cpuData *data);
|
||||
|
||||
extern union cpuData *
|
||||
cpuNodeData (virConnectPtr conn,
|
||||
const char *arch);
|
||||
|
||||
extern virCPUCompareResult
|
||||
cpuGuestData(virConnectPtr conn,
|
||||
virCPUDefPtr host,
|
||||
virCPUDefPtr guest,
|
||||
union cpuData **data);
|
||||
|
||||
#endif /* __VIR_CPU_H__ */
|
122
src/cpu/cpu_generic.c
Normal file
122
src/cpu/cpu_generic.c
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* cpu_generic.c: CPU manipulation driver for architectures which are not
|
||||
* handled by their own driver
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "hash.h"
|
||||
#include "cpu.h"
|
||||
#include "cpu_generic.h"
|
||||
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_CPU
|
||||
|
||||
|
||||
static virHashTablePtr
|
||||
genericHashFeatures(virCPUDefPtr cpu)
|
||||
{
|
||||
virHashTablePtr hash;
|
||||
unsigned int i;
|
||||
|
||||
if ((hash = virHashCreate(cpu->nfeatures)) == NULL)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < cpu->nfeatures; i++) {
|
||||
if (virHashAddEntry(hash,
|
||||
cpu->features[i].name,
|
||||
cpu->features + i)) {
|
||||
virHashFree(hash, NULL);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
static virCPUCompareResult
|
||||
genericCompare(virCPUDefPtr host,
|
||||
virCPUDefPtr cpu)
|
||||
{
|
||||
virHashTablePtr hash;
|
||||
virCPUCompareResult ret = VIR_CPU_COMPARE_ERROR;
|
||||
unsigned int i;
|
||||
unsigned int reqfeatures;
|
||||
|
||||
if ((cpu->arch && STRNEQ(host->arch, cpu->arch)) ||
|
||||
STRNEQ(host->model, cpu->model))
|
||||
return VIR_CPU_COMPARE_INCOMPATIBLE;
|
||||
|
||||
if ((hash = genericHashFeatures(host)) == NULL) {
|
||||
virReportOOMError(NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
reqfeatures = 0;
|
||||
for (i = 0; i < cpu->nfeatures; i++) {
|
||||
void *hval = virHashLookup(hash, cpu->features[i].name);
|
||||
|
||||
if (hval) {
|
||||
if (cpu->type == VIR_CPU_TYPE_GUEST &&
|
||||
cpu->features[i].policy == VIR_CPU_FEATURE_FORBID) {
|
||||
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
|
||||
goto cleanup;
|
||||
}
|
||||
reqfeatures++;
|
||||
}
|
||||
else {
|
||||
if (cpu->type == VIR_CPU_TYPE_HOST ||
|
||||
cpu->features[i].policy == VIR_CPU_FEATURE_REQUIRE) {
|
||||
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (host->nfeatures > reqfeatures) {
|
||||
if (cpu->type == VIR_CPU_TYPE_GUEST &&
|
||||
cpu->match == VIR_CPU_MATCH_STRICT)
|
||||
ret = VIR_CPU_COMPARE_INCOMPATIBLE;
|
||||
else
|
||||
ret = VIR_CPU_COMPARE_SUPERSET;
|
||||
}
|
||||
else
|
||||
ret = VIR_CPU_COMPARE_IDENTICAL;
|
||||
|
||||
cleanup:
|
||||
virHashFree(hash, NULL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct cpuArchDriver cpuDriverGeneric = {
|
||||
.name = "generic",
|
||||
.arch = NULL,
|
||||
.narch = 0,
|
||||
.compare = genericCompare,
|
||||
.decode = NULL,
|
||||
.encode = NULL,
|
||||
.free = NULL,
|
||||
.nodeData = NULL,
|
||||
.guestData = NULL
|
||||
};
|
32
src/cpu/cpu_generic.h
Normal file
32
src/cpu/cpu_generic.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* cpu_generic.h: CPU manipulation driver for architectures which are not
|
||||
* handled by their own driver
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_CPU_GENERIC_H__
|
||||
#define __VIR_CPU_GENERIC_H__
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
extern struct cpuArchDriver cpuDriverGeneric;
|
||||
|
||||
#endif /* __VIR_CPU_GENERIC_H__ */
|
129
src/cpu/cpu_map.c
Normal file
129
src/cpu/cpu_map.c
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* cpu_map.c: internal functions for handling CPU mapping configuration
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "cpu.h"
|
||||
#include "cpu_map.h"
|
||||
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_CPU
|
||||
|
||||
#define CPUMAPFILE DATADIR "/cpu_map.xml"
|
||||
|
||||
|
||||
static int load(xmlXPathContextPtr ctxt,
|
||||
const char *node,
|
||||
cpuMapLoadCallback callback,
|
||||
void *data)
|
||||
{
|
||||
int ret = -1;
|
||||
xmlNodePtr ctxt_node;
|
||||
xmlNodePtr cur;
|
||||
|
||||
ctxt_node = ctxt->node;
|
||||
|
||||
cur = ctxt_node->children;
|
||||
while (cur != NULL) {
|
||||
if (cur->type == XML_ELEMENT_NODE &&
|
||||
xmlStrEqual(cur->name, BAD_CAST node)) {
|
||||
ctxt->node = cur;
|
||||
if (callback(ctxt, data) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
ctxt->node = ctxt_node;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int cpuMapLoad(const char *arch,
|
||||
cpuMapLoadCallback feature_cb,
|
||||
void *model_data,
|
||||
cpuMapLoadCallback model_cb,
|
||||
void *feature_data)
|
||||
{
|
||||
xmlDocPtr xml = NULL;
|
||||
xmlXPathContextPtr ctxt = NULL;
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
char *xpath = NULL;
|
||||
int ret = -1;
|
||||
|
||||
if (arch == NULL) {
|
||||
virCPUReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("undefined hardware architecture"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((xml = xmlParseFile(CPUMAPFILE)) == NULL) {
|
||||
virCPUReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse CPU map file: %s"),
|
||||
CPUMAPFILE);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((ctxt = xmlXPathNewContext(xml)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
virBufferVSprintf(&buf, "./arch[@name='%s']", arch);
|
||||
if (virBufferError(&buf))
|
||||
goto no_memory;
|
||||
|
||||
xpath = virBufferContentAndReset(&buf);
|
||||
|
||||
ctxt->node = xmlDocGetRootElement(xml);
|
||||
|
||||
if ((ctxt->node = virXPathNode(NULL, xpath, ctxt)) == NULL) {
|
||||
virCPUReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot find CPU map for %s architecture"), arch);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((feature_cb && load(ctxt, "feature", feature_cb, feature_data) < 0) ||
|
||||
(model_cb && load(ctxt, "model", model_cb, model_data) < 0)) {
|
||||
virCPUReportError(NULL, VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse CPU map for %s architecture"), arch);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
xmlXPathFreeContext(ctxt);
|
||||
xmlFreeDoc(xml);
|
||||
VIR_FREE(xpath);
|
||||
|
||||
return ret;
|
||||
|
||||
no_memory:
|
||||
virReportOOMError(NULL);
|
||||
goto cleanup;
|
||||
}
|
41
src/cpu/cpu_map.h
Normal file
41
src/cpu/cpu_map.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* cpu_map.h: internal functions for handling CPU mapping configuration
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_CPU_MAP_H__
|
||||
#define __VIR_CPU_MAP_H__
|
||||
|
||||
#include "xml.h"
|
||||
|
||||
|
||||
typedef int
|
||||
(*cpuMapLoadCallback) (xmlXPathContextPtr ctxt,
|
||||
void *data);
|
||||
|
||||
extern int
|
||||
cpuMapLoad(const char *arch,
|
||||
cpuMapLoadCallback feature_cb,
|
||||
void *model_data,
|
||||
cpuMapLoadCallback model_cb,
|
||||
void *feature_data);
|
||||
|
||||
#endif /* __VIR_CPU_MAP_H__ */
|
1161
src/cpu/cpu_x86.c
Normal file
1161
src/cpu/cpu_x86.c
Normal file
File diff suppressed because it is too large
Load Diff
31
src/cpu/cpu_x86.h
Normal file
31
src/cpu/cpu_x86.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* cpu_x86.h: CPU driver for CPUs with x86 compatible CPUID instruction
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_CPU_X86_H__
|
||||
#define __VIR_CPU_X86_H__
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
extern struct cpuArchDriver cpuDriverX86;
|
||||
|
||||
#endif /* __VIR_CPU_X86_H__ */
|
45
src/cpu/cpu_x86_data.h
Normal file
45
src/cpu/cpu_x86_data.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* cpu_x86_data.h: x86 specific CPU data
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
*
|
||||
* 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
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Authors:
|
||||
* Jiri Denemark <jdenemar@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __VIR_CPU_X86_DATA_H__
|
||||
#define __VIR_CPU_X86_DATA_H__
|
||||
|
||||
struct cpuX86cpuid {
|
||||
uint32_t function;
|
||||
uint32_t eax;
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
};
|
||||
|
||||
#define CPUX86_BASIC 0x0
|
||||
#define CPUX86_EXTENDED 0x80000000
|
||||
|
||||
struct cpuX86Data {
|
||||
int basic_len;
|
||||
struct cpuX86cpuid *basic;
|
||||
int extended_len;
|
||||
struct cpuX86cpuid *extended;
|
||||
};
|
||||
|
||||
#endif /* __VIR_CPU_X86_DATA_H__ */
|
@ -71,6 +71,16 @@ virCgroupGetFreezerState;
|
||||
virCgroupSetFreezerState;
|
||||
|
||||
|
||||
# cpu.h
|
||||
cpuCompare;
|
||||
cpuCompareXML;
|
||||
cpuDataFree;
|
||||
cpuDecode;
|
||||
cpuEncode;
|
||||
cpuGuestData;
|
||||
cpuNodeData;
|
||||
|
||||
|
||||
# cpu_conf.h
|
||||
virCPUDefFree;
|
||||
virCPUDefParseXML;
|
||||
|
Loading…
x
Reference in New Issue
Block a user