RFR: 8250598: Hyper-V is detected in spite of running on host OS

Yasumasa Suenaga suenaga at oss.nttdata.com
Mon Jul 27 08:05:53 UTC 2020


On 2020/07/27 16:48, David Holmes wrote:
> On 27/07/2020 5:20 pm, Yasumasa Suenaga wrote:
>> On 2020/07/27 16:09, David Holmes wrote:
>>> On 27/07/2020 3:23 pm, Yasumasa Suenaga wrote:
>>>> On 2020/07/27 14:21, Yasumasa Suenaga wrote:
>>>>> Hi David,
>>>>>
>>>>> On 2020/07/27 14:02, David Holmes wrote:
>>>>>>
>>>>>>
>>>>>> On 27/07/2020 2:24 pm, Yasumasa Suenaga wrote:
>>>>>>> Hi all,
>>>>>>>
>>>>>>> Please review this change:
>>>>>>>
>>>>>>>    JBS: https://bugs.openjdk.java.net/browse/JDK-8250598
>>>>>>>    webrev: http://cr.openjdk.java.net/~ysuenaga/JDK-8250598/webrev.00/
>>>>>>>
>>>>>>> When I got hs_err log on Windows, I saw "HyperV virtualization detected" in it in spite of running on host OS.
>>>>>>>
>>>>>>> Hypervisor detector has been introduced in JDK-8219241, but it has some problems as below:
>>>>>>>
>>>>>>>    - Hyper-V is detected on Windows in spite of running on host OS
>>>>>>>    - Call CPUID with other than EAX = 40000000h (it is not described in the spec [1])
>>>>>>
>>>>>> That VMWare document is not a "spec" for anything other than VMware. So this may work for VMWare:
>>>>>>
>>>>>>    a->movl(rax, 0x40000000);
>>>>>>
>>>>>> but may not work for all other HV environments - which is why the original code checks a range of addresses within the reserved area. See this related code for example:
>>>>>>
>>>>>> http://git.annexia.org/?p=virt-what.git;a=blob;f=virt-what-cpuid-helper.c;h=9c6cdb290105ca86868e2c7935ed42a55598b0f7;hb=HEAD
>>>>>>
>>>>>>    71   /* Most hypervisors only have information in leaf 0x40000000.
>>>>>>    72    *
>>>>>>    73    * Some hypervisors have "Viridian [HyperV] extensions", and those
>>>>>>    74    * must appear in slot 0x40000000, but they will also have the true
>>>>>>    75    * hypervisor in a higher slot.
>>>>>>
>>>>>> You have to be able to check this on a range of HV's to ensure you have not broken anything.
>>>>>
>>>>> Currently this feature supports VMware, Hyper-V, KVM, Xen.
>>>>> We can distinguish them from CPUID with 40000000h. So we should not check other than 40000000h.
>>>>>
>>>>>     VMware: https://kb.vmware.com/s/article/1009458
>>>>>    Hyper-V: https://docs.microsoft.com/virtualization/hyper-v-on-windows/reference/hyper-v-architecture
>>>>
>>>> Sorry, Hyper-V spec is here:
>>>>
>>>> https://docs.microsoft.com/virtualization/hyper-v-on-windows/reference/tlfs
>>>>
>>>> In Windows Server 2019, you can see CPUID in 2.4.1 .
>>>>
>>>>
>>>>>        KVM: https://www.kernel.org/doc/html/latest/virt/kvm/cpuid.html
>>>>>        Xen: https://xenbits.xen.org/docs/unstable/hypercall/x86_32/include,public,arch-x86,cpuid.h.html
>>>>>
>>>>>
>>>>>> Did you actually diagnose why the existing code mis-detects Hyper-V under Windows?
>>>>>
>>>>> CPUID with EAX = 40000000h returns "Microsoft Hv" if Hyper-V is installed. I guess it is caused by Hyper-V architecture.
>>>
>>> But do we actually check the enabled bit:
>>>
>>> "Bit 31 returned in ECX is defined as Not Used, and will always return 0 from the physical CPU. A hypervisor conformant with the Microsoft hypervisor interface will set CPUID.1:ECX [bit 31] = 1 to indicate its presence to software."
>>>
>>> ?
>>
>> CPUID with EAX = 40000000h would be handled in vCPU, so it is worth to check bit 31.
>> KVM document implies it.
>>
>>    https://www.kernel.org/doc/html/latest/virt/kvm/cpuid.html
> 
> Let me try this again. This bug report was created because the hpervisor detection code is falsely reporting we are executing in hyper-v under Windows even when we are actually running a non-virtualized native OS. My question about the original is code is what part of it, exactly, is responsible for that false report?

VM_Version::check_virtualizations() would check whether the process is running on virtual machine with CPUID (EAX = 40000000h to 4000ff00h, however it would detect Hyper-V (CPUID returns "Microsoft Hv") even if the process is running on host OS. It should be check in other solution (e.g. WMI)

This is a problem in Hyper-V, but I found out some related issues in hypervisor detection code, so I want to fix them together:

   - Lack of x86 (32 bit) support
   - Lack of hypervisor present bit (bit 31) check
   - Calling CPUID with other than EAX = 40000000h

If they are the cause of confusing, I can separate them in other issues.
(They are not Hyper-V specific issues)


Thanks,

Yasumasa


> Thanks,
> David
> 
>>
>> Thanks,
>>
>> Yasumasa
>>
>>
>>> Thanks,
>>> David
>>> -----
>>>
>>>>> According to [1], root partition is as a host OS, so I guess JVM would detect which is running on Hyper-V even if it is running on host OS.
>>>>>
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Yasumasa
>>>>>
>>>>>
>>>>> [1] https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/reference/hyper-v-architecture
>>>>>
>>>>>
>>>>>> David
>>>>>> -----
>>>>>>
>>>>>>>    - Does not check CPUID hypervisor present bit [1]
>>>>>>>    - Does not support x86 (32bit) platform
>>>>>>>
>>>>>>> I've tested this change on submit repo, and have checked output from VM.info jcmd on following environment:
>>>>>>>
>>>>>>>    - Windows x64 (host)
>>>>>>>    - Windows x64 (Hyper-V guest)
>>>>>>>    - Fedora32 x64 (Hyper-V guest)
>>>>>>>    - 32 bit JDK on Fedora32 x64 (Hyper-V guest)
>>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> Yasumasa
>>>>>>>
>>>>>>>
>>>>>>> [1] https://kb.vmware.com/s/article/1009458


More information about the hotspot-runtime-dev mailing list