Making sense of libvrt bit map when calling virDomainPinVcpu

On my iPad this morning, I doodled the above figure to help me better understand how I should be calling the function virDomainPinVcpu (as part of project 1 for my advanced operating systems course).  The function requires two parameters which I found a bit confusing: a pointer to the cpu map (i.e. bit map) and length of the map itself.

In order to generate the CPU map, we need a couple pieces of information: the number of physical CPUs and the number of virtual CPUs (for a guest virtual machine).  This information can be obtained by calling virNodeGetInfo and virDomainGetVcpus, respectively1.

First, you need to get the number of byes needed to represent the physical CPUs. Let’s say our hypervisor runs 8 physical CPUs. In this case, we’d need a single byte: bit 0 represents CPU#0, bit 1 represents CPU#1 … bit 7 represents CPU#7. If we had 16 physical CPUs, then we’d need 2 bytes. Let’s call this physical_cpu_ptr.

Then, each virtual CPU will contain a mapping to its own unique physical_cpu_ptr.

Example

Below is an output from within GDB. In this example, my physical hypervisor has CPUs and each virtual machine runs 2 virtual CPUs.  Based off of what I mentioned above, that means mean the virtual machine’s bitmap contains 2 bytes. First byte is for virtual CPU#1 and second byte is for virtual CPU#2 — can run on any one of the four physical CPUs. Hence why only the first four bits are set.

(gdb) x /2b cpu_maps
0x555555772710: 0x0f 0x0f

References

1 – https://stackoverflow.com/questions/46254411/what-is-the-argument-cpumaps-and-maplen-in-api-virdomaingetvcpus-of-libvirt