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

Yasumasa Suenaga suenaga at oss.nttdata.com
Mon Jul 27 08:33:58 UTC 2020


On 2020/07/27 17:15, David Holmes wrote:
> On 27/07/2020 6:05 pm, Yasumasa Suenaga wrote:
>> 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
> 
> Okay so I'm going to assume that a system might fill out the CPUID leaf values unconditionally and expect the programmers to check bit 31 and only if it is enabled use the information from the leaf. Hence the current code reports Hyper-V when it isn't enabled. But the new code can just skip all the leaf reading when it isn't enabled - right? (so startup should be marginally faster)

The current code reports Hyper-V even if it is running on native OS (root partition - not a guest OS).
In root partition, bit 31 is always 1 and Hyper-V is always reported (CPUID always returns "Microsoft Hv")

To avoid this problem, the new code would check with WMI whether it is running on Virtual Machine or not.


> Thanks,
> David
> -----
> 
>>    - 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