qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] Byte ordering of VM Generation ID in Windows VMs


From: Laszlo Ersek
Subject: Re: [Qemu-devel] Byte ordering of VM Generation ID in Windows VMs
Date: Thu, 5 Jul 2018 16:20:33 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.7.0

Hi Rich,

On 07/05/18 14:52, Richard W.M. Jones wrote:
> On Thu, Jul 05, 2018 at 01:39:29PM +0100, Richard W.M. Jones wrote:
>> I was doing a bit of investigation around how different hypervisors
>> handle the VM Generation ID feature.  QEMU's behaviour seems quite
>> strange, I wonder if this is a bug or expected?
>>
>> (1) I booted a Windows 2016 VM with:
>>
>>   qemu-system-x86_64 -M pc,accel=kvm -m 2G -hda w2k16-mincore.img \
>>       -device vmgenid,guid=01020304-0506-0708-090a-0b0c0d0e0f00,id=vmgenid0
>>
>> (2) Inside the guest I used the VMGENID.EXE program from:
>>
>>   https://bugzilla.redhat.com/show_bug.cgi?id=1598350#c3
>>   
>> https://docs.microsoft.com/en-gb/windows/desktop/HyperV_v2/virtual-machine-generation-identifier
>>
>> Note this is self-compiled using mingw64-g++ (not using Visual Studio
>> which I don't have available), but I don't believe that could have
>> caused the problem.
>>
>> (3) The program prints:
>>
>>   VmCounterValue: 708050601020304:f0e0d0c0b0a09
>>
>> To make it easier to see, this is the same number but zero-extended:
>>
>>   VmCounterValue: 07 08 05 06 01 02 03 04 : 00 0f 0e 0d 0c 0b 0a 09
>>                   \________ LOW ________/   \_______ HIGH _______/
>>                             WORD                     WORD
>>
>> As you can see it looks like there is no clear relationship between
>> the order of the bytes in the guid= parameter and the order that they
>> are seen by Windows.
>
> OK after examining util/uuid.c and the qemu_uuid_bswap function,
> I sort of see what's going on here.
>
> FWIW other hypervisors seem to store these as two 64 bit integers.

This is a bit tricky. Please refer to the following:

* https://bugzilla.redhat.com/show_bug.cgi?id=1118834#c21
* http://mid.mail-archive.com/address@hidden

in particular steps (8) + (9), and (15) + (16).

The QEMU device model takes the UUID (GUID) in textual representation
and stores it in guest memory in little endian binary UUID
representation. Historically, components of the UUID used to be encoded
in big endian, when represented in binary; however, as e.g. the SMBIOS
spec states (in "7.2.1 System -- UUID"), Microsoft uses little endian
encoding, for representing those fields of the UUID, in binary, that are
not simple byte arrays. (This has BTW leaked into other domains, for
example ACPI and UEFI).

In turn, the test program that you used didn't print the binary value in
either UUID format or raw byte dump format -- instead, it interpreted
the first 8 bytes as a little-endian uint64_t, and the second 8 bytes as
another uint64_t.

Applied to your example, we have:

  01020304-0506-0708-090a-0b0c0d0e0f00

  time_low:                  0x01020304 (DWORD)
  time_mid:                  0x0506 (WORD)
  time_hi_and_version:       0x0708 (WORD)
  clock_seq_hi_and_reserved: 0x09 (BYTE)
  clock_seq_low:             0x0a (BYTE)
  Node:                      0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00 (BYTE[6])

The DWORD and WORD fields are sensitive to endianness. When using
little-endian, the full raw representation, and the uint64_t
interpretations will be:

  time_low                time_mid    time_hi_and_version  
clock_seq_hi_and_reserved  clock_seq_low         Node
  ----------------------  ----------  -------------------  
-------------------------  --------------------  
----------------------------------
  0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07,          0x09,                
      0x0a,                 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00
  -------------------------------------------------------  
-----------------------------------------------------------------------------------
  uint64_t: 0x0708050601020304                             uint64_t: 
0x000f0e0d0c0b0a09

QEMU does the right thing. If other hypervisors don't do this -- while
still taking and displaying the value in UUID / GUID textual format --,
they are wrong. The VMGENID spec from Microsoft
<http://go.microsoft.com/fwlink/?LinkId=260709> specifically mentions
"GUID".

Thanks,
Laszlo



reply via email to

[Prev in Thread] Current Thread [Next in Thread]