Set CPU features in appropriate libxl structure.
Use old "xend" syntax, because it allow control over any bit and libvirt
already have API for translating features to appropriate cpuid bits. And
also features naming in libxl do not match the one of libvirt in
multiple cases.
Side effect is that all the bits derived from CPU <model> (which is
required anyway) are also set as "required".
Libxl do not have distinction between "force" and "required" policy
(there is only "force") and also between "forbid" and "disable" (there
is only "disable"). So, merge them appropriately. If anything, "require"
and "forbid" should be enforced outside of specific driver.
---
src/libxl/libxl_conf.c | 139 ++++++++++++++++++++++++++++++++++--------
src/libxl/libxl_conf.h | 1 +-
2 files changed, 116 insertions(+), 24 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 938e09d..4c400f4 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -291,6 +291,93 @@ libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
return 0;
}
+static int libxlMakeCPUID(virArch arch,
+ const virCPUDef *cpu,
+ libxl_cpuid_policy_list *cpuid)
+{
+ virCPUDataPtr cpu_policy[4];
+ /* forced, required, disabled, forbidden */
+ char libxl_policy_char[4] = { '1', '1', '0', '0' };
+ int leaf, subleaf, reg;
+ size_t i, j;
+ char leaf_text[48];
+ char *reg_text;
+ int policy_index = 0;
+ uint32_t reg_value;
+ int ret = -1;
+ int cpuid_bit;
+ /* supported values, based on libxl_cpuid.c */
+ int leafs[] = { 1, 6, 7, 0x80000001 };
+ int subleafs[] = { -1, -1, 0, -1 };
+
+ if (cpuEncode(arch,
+ cpu,
+ &cpu_policy[0],
+ &cpu_policy[1],
+ NULL,
+ &cpu_policy[2],
+ &cpu_policy[3],
+ NULL))
+ return -1;
+
+ for (i = 0; i < sizeof(leafs)/sizeof(*leafs); i++) {
+ leaf = leafs[i];
+ subleaf = subleafs[i];
+
+ for (reg = 0; reg < 4; reg++) {
+ if (subleaf != -1)
+ snprintf(leaf_text, sizeof(leaf_text),
+ "%#x,%d:e%cx=" LIBXL_DEFAULT_CPUID_REG_CONFIG,
+ leaf, subleaf, 'a'+reg);
+ else
+ snprintf(leaf_text, sizeof(leaf_text),
+ "%#x:e%cx=" LIBXL_DEFAULT_CPUID_REG_CONFIG,
+ leaf, 'a'+reg);
+
+ reg_text = strstr(leaf_text, "=") + 1;
+
+ for (policy_index = 0; policy_index < 4; policy_index++) {
+ /* search for this leaf in CPUData structure */
+ for (j = 0; j < cpu_policy[policy_index]->data.x86.len; j++) {
+ virCPUx86CPUID *cpuid_policy =
+ &cpu_policy[policy_index]->data.x86.data[j];
+
+ if (cpuid_policy->eax_in == leaf &&
+ (subleaf == -1 || cpuid_policy->ecx_in == subleaf)) {
+
+ switch (reg) {
+ case 0: reg_value = cpuid_policy->eax; break;
+ case 1: reg_value = cpuid_policy->ebx; break;
+ case 2: reg_value = cpuid_policy->ecx; break;
+ case 3: reg_value = cpuid_policy->edx; break;
+ }
+
+ for (cpuid_bit = 0; cpuid_bit < 32; cpuid_bit++) {
+ if (reg_value & (1<<cpuid_bit))
+ reg_text[31-cpuid_bit] = libxl_policy_char[policy_index];
+ }
+ }
+ }
+ }
+
+ /* set it in domain config only if any bit was modified */
+ if (STRNEQ(reg_text, LIBXL_DEFAULT_CPUID_REG_CONFIG)) {
+ if (libxl_cpuid_parse_config_xend(cpuid, leaf_text))
+ goto cleanup;
+ }
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ virCPUDataFree(cpu_policy[0]);
+ virCPUDataFree(cpu_policy[1]);
+ virCPUDataFree(cpu_policy[2]);
+ virCPUDataFree(cpu_policy[3]);
+ return ret;
+}
+
static int
libxlMakeDomBuildInfo(virDomainDefPtr def,
libxl_ctx *ctx,
@@ -376,38 +463,42 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
def->features[VIR_DOMAIN_FEATURE_ACPI] ==
VIR_TRISTATE_SWITCH_ON);
- if (caps &&
- def->cpu && def->cpu->mode == (VIR_CPU_MODE_HOST_PASSTHROUGH)) {
- bool hasHwVirt = false;
- bool svm = false, vmx = false;
+ if (caps && def->cpu) {
+ if (def->cpu->mode == (VIR_CPU_MODE_HOST_PASSTHROUGH)) {
+ bool hasHwVirt = false;
+ bool svm = false, vmx = false;
- if (ARCH_IS_X86(def->os.arch)) {
- vmx = virCPUCheckFeature(caps->host.arch, caps->host.cpu, "vmx");
- svm = virCPUCheckFeature(caps->host.arch, caps->host.cpu, "svm");
- hasHwVirt = vmx | svm;
- }
+ if (ARCH_IS_X86(def->os.arch)) {
+ vmx = virCPUCheckFeature(caps->host.arch, caps->host.cpu, "vmx");
+ svm = virCPUCheckFeature(caps->host.arch, caps->host.cpu, "svm");
+ hasHwVirt = vmx | svm;
+ }
- if (def->cpu->nfeatures) {
- for (i = 0; i < def->cpu->nfeatures; i++) {
+ if (def->cpu->nfeatures) {
+ for (i = 0; i < def->cpu->nfeatures; i++) {
- switch (def->cpu->features[i].policy) {
+ switch (def->cpu->features[i].policy) {
- case VIR_CPU_FEATURE_DISABLE:
- case VIR_CPU_FEATURE_FORBID:
- if ((vmx && STREQ(def->cpu->features[i].name, "vmx")) ||
- (svm && STREQ(def->cpu->features[i].name, "svm")))
- hasHwVirt = false;
- break;
+ case VIR_CPU_FEATURE_DISABLE:
+ case VIR_CPU_FEATURE_FORBID:
+ if ((vmx && STREQ(def->cpu->features[i].name, "vmx")) ||
+ (svm && STREQ(def->cpu->features[i].name, "svm")))
+ hasHwVirt = false;
+ break;
- case VIR_CPU_FEATURE_FORCE:
- case VIR_CPU_FEATURE_REQUIRE:
- case VIR_CPU_FEATURE_OPTIONAL:
- case VIR_CPU_FEATURE_LAST:
- break;
+ case VIR_CPU_FEATURE_FORCE:
+ case VIR_CPU_FEATURE_REQUIRE:
+ case VIR_CPU_FEATURE_OPTIONAL:
+ case VIR_CPU_FEATURE_LAST:
+ break;
+ }
}
}
+ libxl_defbool_set(&b_info->u.hvm.nested_hvm, hasHwVirt);
}
- libxl_defbool_set(&b_info->u.hvm.nested_hvm, hasHwVirt);
+
+ if (libxlMakeCPUID(def->os.arch, def->cpu, &b_info->cpuid))
+ return -1;
}
if (def->nsounds > 0) {
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 264df11..8d89ccd 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -60,6 +60,7 @@
# define LIBXL_DUMP_DIR LIBXL_LIB_DIR "/dump"
# define LIBXL_CHANNEL_DIR LIBXL_LIB_DIR "/channel/target"
# define LIBXL_BOOTLOADER_PATH "pygrub"
+# define LIBXL_DEFAULT_CPUID_REG_CONFIG "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
typedef struct _libxlDriverPrivate libxlDriverPrivate;
--
git-series 0.9.1
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: > Set CPU features in appropriate libxl structure. > Use old "xend" syntax, because it allow control over any bit and libvirt > already have API for translating features to appropriate cpuid bits. And > also features naming in libxl do not match the one of libvirt in > multiple cases. How does the new syntax look like? And would it be actually better? The problem with setting individual CPUID bits is very fragile. That's mostly what we naively started to do in qemu driver and we're fighting with it since then. It's way too easy to create a virtual CPU which a guest OS will crash on. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 29, 2017 at 10:04:42AM +0200, Jiri Denemark wrote: > On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: > > Set CPU features in appropriate libxl structure. > > Use old "xend" syntax, because it allow control over any bit and libvirt > > already have API for translating features to appropriate cpuid bits. And > > also features naming in libxl do not match the one of libvirt in > > multiple cases. > > How does the new syntax look like? "host,tm=0,sse3=0" > And would it be actually better? Maybe? But the new syntax use different names for many features (like pni vs sse3, or sep vs sysenter), so it would require some ugly translation table... What I would really like here, is to get list of bits specified with <feature ...>, _without_ those defined by <model>. And maybe even without requiring <model> to be set at all. Another misleading thing about interpreting <model> here is, it doesn't mask out features not really present in that CPU. So, you get a CPU based on <model> but with many additional features. > The > problem with setting individual CPUID bits is very fragile. That's > mostly what we naively started to do in qemu driver and we're fighting > with it since then. It's way too easy to create a virtual CPU which a > guest OS will crash on. Well, IMHO if you modify things like CPUID you should really know what you are doing... -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 29, 2017 at 10:39:26 +0200, Marek Marczykowski-Górecki wrote: > On Thu, Jun 29, 2017 at 10:04:42AM +0200, Jiri Denemark wrote: > > On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: > > > Set CPU features in appropriate libxl structure. > > > Use old "xend" syntax, because it allow control over any bit and libvirt > > > already have API for translating features to appropriate cpuid bits. And > > > also features naming in libxl do not match the one of libvirt in > > > multiple cases. > > > > How does the new syntax look like? > > "host,tm=0,sse3=0" Is "host" fixed there or are other CPU models supported too? If only "host" is allowed, libxl driver should support host-passthrough mode only and it would be pretty easy to map it to the libxl's syntax. The following CPU XML <cpu mode='host-passthrough'> <feature name='avx' policy='disable'/> <feature name='aes' policy='require'/> </cpu> could be directly translated into "host,avx=0,aes=1". > > And would it be actually better? > > Maybe? But the new syntax use different names for many features (like > pni vs sse3, or sep vs sysenter), so it would require some ugly > translation table... I don't a translation table would be ugly. > What I would really like here, is to get list of bits specified with > <feature ...>, _without_ those defined by <model>. And maybe even > without requiring <model> to be set at all. That's what host-passthrough mode is for. Jirka -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 29, 2017 at 11:00:35AM +0200, Jiri Denemark wrote: > On Thu, Jun 29, 2017 at 10:39:26 +0200, Marek Marczykowski-Górecki wrote: > > On Thu, Jun 29, 2017 at 10:04:42AM +0200, Jiri Denemark wrote: > > > On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: > > > > Set CPU features in appropriate libxl structure. > > > > Use old "xend" syntax, because it allow control over any bit and libvirt > > > > already have API for translating features to appropriate cpuid bits. And > > > > also features naming in libxl do not match the one of libvirt in > > > > multiple cases. > > > > > > How does the new syntax look like? > > > > "host,tm=0,sse3=0" > > Is "host" fixed there or are other CPU models supported too? Only "host". > If only > "host" is allowed, libxl driver should support host-passthrough mode > only and it would be pretty easy to map it to the libxl's syntax. The > following CPU XML > > <cpu mode='host-passthrough'> > <feature name='avx' policy='disable'/> > <feature name='aes' policy='require'/> > </cpu> > > could be directly translated into "host,avx=0,aes=1". That would make sense, indeed. One practical issue is that I'm doing the whole thing to disable "smap" bit. And this bit isn't supported in the new libxl syntax. At least not yet - I've already submitted a patch to add it :) > > > And would it be actually better? > > > > Maybe? But the new syntax use different names for many features (like > > pni vs sse3, or sep vs sysenter), so it would require some ugly > > translation table... > > I don't a translation table would be ugly. Ok. > > What I would really like here, is to get list of bits specified with > > <feature ...>, _without_ those defined by <model>. And maybe even > > without requiring <model> to be set at all. > > That's what host-passthrough mode is for. Ok. -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 29, 2017 at 10:39:26AM +0200, Marek Marczykowski-Górecki wrote: > On Thu, Jun 29, 2017 at 10:04:42AM +0200, Jiri Denemark wrote: > > On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: > > > Set CPU features in appropriate libxl structure. > > > Use old "xend" syntax, because it allow control over any bit and libvirt > > > already have API for translating features to appropriate cpuid bits. And > > > also features naming in libxl do not match the one of libvirt in > > > multiple cases. > > > > How does the new syntax look like? > > "host,tm=0,sse3=0" > > > And would it be actually better? > > Maybe? But the new syntax use different names for many features (like > pni vs sse3, or sep vs sysenter), so it would require some ugly > translation table... That's not particularly difficult or ugly. Currently virCPUFeatureDEf stores the feature as a string, but we could easily define an enum for the feature names, and then store them as an int. We already have support for doing trivial enum -> string conversions. > What I would really like here, is to get list of bits specified with > <feature ...>, _without_ those defined by <model>. And maybe even > without requiring <model> to be set at all. That would take operation of the Xen driver in a very different direction to the QEMU driver, which I feels is not desirable for applications using libvirt. > Another misleading thing about interpreting <model> here is, it doesn't > mask out features not really present in that CPU. So, you get a CPU > based on <model> but with many additional features. > > > The > > problem with setting individual CPUID bits is very fragile. That's > > mostly what we naively started to do in qemu driver and we're fighting > > with it since then. It's way too easy to create a virtual CPU which a > > guest OS will crash on. > > Well, IMHO if you modify things like CPUID you should really know what > you are doing... The problem is that we've seen real world evidence that apps & users don't know what they're doing here. Sooo many bug reports where guests have been given arbitrary features, causing the guest OS and/or apps to randomly crash due to wierdly unexpected combinations of features. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On 06/29/2017 09:39 AM, Marek Marczykowski-Górecki wrote: > On Thu, Jun 29, 2017 at 10:04:42AM +0200, Jiri Denemark wrote: >> On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: >>> Set CPU features in appropriate libxl structure. >>> Use old "xend" syntax, because it allow control over any bit and libvirt >>> already have API for translating features to appropriate cpuid bits. And >>> also features naming in libxl do not match the one of libvirt in >>> multiple cases. >> >> How does the new syntax look like? > > "host,tm=0,sse3=0" > >> And would it be actually better? > > Maybe? But the new syntax use different names for many features (like > pni vs sse3, or sep vs sysenter), so it would require some ugly > translation table... > What I would really like here, is to get list of bits specified with > <feature ...>, _without_ those defined by <model>. And maybe even > without requiring <model> to be set at all. > Another misleading thing about interpreting <model> here is, it doesn't > mask out features not really present in that CPU. So, you get a CPU > based on <model> but with many additional features. > Two suggestions (the first one to hopefully complement current discussion): 1) Maybe there could be a driver config item to allow the Xend syntax (since it's a rather fragile facility that allows all bits controlled)? Or else prefer first libxl format through the translation table of features and use xend format for this driver config such that non-supported features in libxl format fallback to xend format instead? Probably this allows for best of both worlds (better safety with libxl-format) yet higher flexibility/controllability with xend format. Also I am not sure we should support models either - since our CPUID view is restricted to host-{passthrough,model} only. 2) perhaps part of the code in this patch could be better placed at xenconfig/xen_{xl,xm}.c since it's really two different formats of config? This would also allow supporting Xen <-> Xml config file conversions. Joao -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
On Thu, Jun 29, 2017 at 10:21:11AM +0100, Joao Martins wrote: > On 06/29/2017 09:39 AM, Marek Marczykowski-Górecki wrote: > > On Thu, Jun 29, 2017 at 10:04:42AM +0200, Jiri Denemark wrote: > >> On Thu, Jun 29, 2017 at 03:11:42 +0200, Marek Marczykowski-Górecki wrote: > >>> Set CPU features in appropriate libxl structure. > >>> Use old "xend" syntax, because it allow control over any bit and libvirt > >>> already have API for translating features to appropriate cpuid bits. And > >>> also features naming in libxl do not match the one of libvirt in > >>> multiple cases. > >> > >> How does the new syntax look like? > > > > "host,tm=0,sse3=0" > > > >> And would it be actually better? > > > > Maybe? But the new syntax use different names for many features (like > > pni vs sse3, or sep vs sysenter), so it would require some ugly > > translation table... > > What I would really like here, is to get list of bits specified with > > <feature ...>, _without_ those defined by <model>. And maybe even > > without requiring <model> to be set at all. > > Another misleading thing about interpreting <model> here is, it doesn't > > mask out features not really present in that CPU. So, you get a CPU > > based on <model> but with many additional features. > > > Two suggestions (the first one to hopefully complement current discussion): > > 1) Maybe there could be a driver config item to allow the Xend syntax (since > it's a rather fragile facility that allows all bits controlled)? Or else prefer > first libxl format through the translation table of features and use xend format > for this driver config such that non-supported features in libxl format fallback > to xend format instead? Probably this allows for best of both worlds (better > safety with libxl-format) yet higher flexibility/controllability with xend > format. Also I am not sure we should support models either - since our CPUID > view is restricted to host-{passthrough,model} only. IIUC setting CPU model is required to get CPUID bits from libvirt cpu API (cpuEncode function). If there is some other way, that would be great. But if that would require changing cpu libvirt internal API, I think just a fallback doesn't worth it. > 2) perhaps part of the code in this patch could be better placed at > xenconfig/xen_{xl,xm}.c since it's really two different formats of config? This > would also allow supporting Xen <-> Xml config file conversions. Ok, I'll look into it. -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab A: Because it messes up the order in which people normally read text. Q: Why is top-posting such a bad thing? -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
© 2016 - 2025 Red Hat, Inc.