Hello Community,
I am currently learning hypervisor design using ARM's virtualization extensions (on both ARMv7 and ARMv8).
A note in the ARMv8-A reference manual (section D1.5) mentions:
"In some systems, a Guest OS is unaware that it is running on a virtual machine, and is unaware of any other Guest OS. In other systems, a hypervisor makes the Guest OS aware of these facts. The ARMv8-A architecture supports both of these models."
According to this, it should be possible to implement an entirely transparent hypervisor, e.g., one that is not detectable by software running inside a guest (maybe except from external timing). However, I do not understand how this can be true in the presence of the load/store-exclusive instructions.
As I understand, the local exclusive monitor must always be cleared on a context switch. This prevents a thread from inheriting exclusive monitor state from another thread. Consequently:
Hence, every world switch back to a guest clears the exclusive monitor on both ARMv7 and ARMv8.
But this behavior makes hypervisors relying on the ARM virtualization extensions detectable. A detector could perform the following test:
Step 2 might require privileged execution (e.g., in a kernel module). The detector might have to disable preemption or perform the test multiple times to be sure the local monitor was not cleared by another thread. However, it should be possible to detect any hypervisor that way.
There seem to be no mechanisms in ARM that would let the hypervisor circumvent this detection method (e.g., by emulation). That would mean, no hypervisor using the ARM virtualization extensions can be completely transparent (except for timing). This bugs me, because transparency is quite important for many security applications that use VMs (e.g., malware analysis). Am I missing something?
Thanks,
Jan
Technically the Local Monitor can be cleared by the PE at any time - see B2.10.5 in the ARMv8 ARM A.f:
An implementation might clear an exclusive monitor between the LoadExcl instruction and the StoreExcl, instruction without any application-related cause. For example, this might happen because of cache evictions. Software must, in any single thread of execution, avoid having any explicit memory accesses, system control register updates, or cache maintenance instructions between the LoadExcl instruction and the associated StoreExcl instruction.
Therefore while you might be able to surmise that you may have a hypervisor in place; for instance, you could make the judgement that the monitor was cleared because an exception was taken to a higher EL (such as EL2) and therefore the return to your code cleared the monitor. However, you have no way of determining exactly why the monitor was cleared, there is no way of querying the monitor state, so you're just guessing that it is one possibility out of a handful of possibilities. It is perfectly possible (in fact, highly likely) that your "hypervisor detection algorithm" would "detect" hypervisors on systems which don't even implement the Virtualization Extensions, merely because they are designed to be speculative.
Ta,
Matt
.