[libvirt] cpu_map data access for libxl driver

Joao Martins joao.m.martins at oracle.com
Fri Jul 8 15:22:13 UTC 2016


On 07/08/2016 09:08 AM, Cedric Bosdonnat wrote:
> Hello Joao!
> 
> On Thu, 2016-07-07 at 16:20 +0100, Joao Martins wrote:
>> FYI I too am working on guest <cpu> config work and have an RFC wrt to libvirt host
>> cpu detection. Perhaps we could joint work on this?
> 
> I started looking at the host cpu detection yesterday, but it seems the libxl
> hw_map bits aren't too easy to understand. But sure, if we can join efforts
> that would be good.
> 
Indeed, libxl hw_caps changes from Xen 4.4-4.6 to Xen 4.7 - and it wasn't somewhat
stabilized until the latter, although field is provided from even earlier xen
versions. So the quirk there is to handle that, other than that is plain cpuid leaves
output.

> I also couldn't find your RFC in the mailing list archives. Do you have code available
> somewhere? Joining efforts without stepping on each other's toes isn't that easy ;)
Ah, sure! I don't have a public tree available these days - let me post that shortly
on the list for discussion and we could continue from there (will CC you on the series).

>> As you know, there are two forms to represent this info in xen libxl cpuid: 1) is the
>> xend format which provides the input leaf and output registers values raw CPUID data,
>> and 2) the libxl format. Though while man page depicts what the feature names are -
>> the correspondent input, output registers, and feature names aren't really exported
>> by libxl headers and will have to be replicated in libvirt and adjusted to API
>> changes. So probably xend format would be better suited - which can possible
>> accomodate other leafs than those described by the libxl format? There is also a
>> special case for 'vmx' where we need to set libxl-side nestedhvm attribute to true
>> (on HVM guests).
> 
> Sure the xend format would be more flexible, however it's fairly easy to map the
> libvirt names to the xen ones: those are mostly the same. This also helps checking
> for the xen unsupported flags. Doing the mapping manually helped me see that libxl
> has CPU features flags that libvirt doesn't have (maybe we'll have to add them).
> And anyway, we will have to adjust the libvirt feature set if there are more features
> supported in future libxl/xen versions as libvirt's <cpu> doesn't hold the register bits
> but strings.
Hmm, mapping would be fairly easy indeed. I was more concerned about duplication
in libxl driver - specially as these feature names in libxl are private (as seen from
a library perspective and will have to piggy back what it is on libxl_cpuid.c, even
though mnemonics are similar). While having to keep up with changes between libxl and
cpu_map.xml in between. But perhaps may be that's less of a concern as cpu_map.xml is
made thinking for that sort of adjustments?

The register bits can be fetched as far as I could see from the APIs (see below). I
was more thinking along the lines of knowing the register bits from each feature name
somehow and just construct the string accordingly (potentially leading to a smaller
amounts of code?), and then support xl format whenever everything is exported. Or you
think it's a less preferable way to how it should be handled in libvirt? On the other
hand the xend syntax might be more cumbersome when setting things that we shouldn't,
even though is up to the libxl cpuid policy to validate.

Irrespective of the format we decide to use - we need somehow to convert a guest
<cpu> definition a complete list of CPUID/featurename data or pre-store id in cpu map
definitions in libxl cfg object. We can actually get the CPUID part through
cpuGuestData() (the input/ouput registers). Say for example on running on a Broadwell
processor and we use this cpu definition (the example doesn't make a lot of sense
here, it's just for the purpose of pointing out the issue):

<cpu match='exact'>
   <model>Nehalem</model>
   <feature policy='require' name='avx'/>
</cpu>

The CPUID registers part coming from cpuGuestData returns me this:

libxlMakeCPU:318 : CPUID[0] input=(EAX=1,ECX=0) :EAX=000306d0, EBX=00000000
ECX=10982201 EDX=078bfbfd
libxlMakeCPU:318 : CPUID[1] input=(EAX=7,ECX=0) :EAX=00000000, EBX=00000000
ECX=00000000 EDX=00000000
libxlMakeCPU:318 : CPUID[2] input=(EAX=d,ECX=1) :EAX=00000000, EBX=00000000
ECX=00000000 EDX=00000000
libxlMakeCPU:318 : CPUID[3] input=(EAX=80000001,ECX=0) :EAX=00000000, EBX=00000000
ECX=00000001 EDX=20100800
libxlMakeCPU:318 : CPUID[4] input=(EAX=80000007,ECX=0) :EAX=00000000, EBX=00000000
ECX=00000000 EDX=00000000

So we would need to set too all features corresponding to Nehalem model as described
by cpu_map.xml, plus setting up AVX (in the context of this example). libxl keeps no
info of features associated with each model/family so there wouldn't be a shortcut
akin to QEMU where IIUC libvirt feeds qemu with the expected models and features that
it will use. Thoughts?

Joao




More information about the libvir-list mailing list