[roll] Roll fuchsia [kernel][hypervisor][x86] Improve inline assembly of vmx instructions.
We use inline assembly to implement functions for performing VMX
operations such as vmread, vmwrite, and so on. With the current
implementation, the C++ code:
return vmread(0);
is compiled to the assembly:
movabs rax, 0xaaaaaaaaaaaaaaaa // Load uninitialised memory
// pattern into RAX.
mov qword ptr [rsp - 8], rax // Write RAX to stack
xor eax, eax // Clear RAX (by clearing EAX)
vmread qword ptr [rsp - 8], rax // Perform the `vmread`, placing
// the result on the stack.
setbe al // Set AL to 1 if C or Z
// error flags set.
test al, al // Test AL...
jne .Lerror // ...and jump to .Lerror if it
// is non-zero.
mov rax, qword ptr [rsp - 8] // Load read value from stack
ret
The destination operand to `vmread` is currently specified to the
compiler as needing to be a memory location, but can actually also be
a register. Updating this, we get substantially improved code:
xor eax, eax // Clear RAX.
vmread rax, rax // Read value into RAX.
setbe cl // Set CL to 1 if C or Z error flags set.
test cl, cl // Test CL...
jne .Lerror // ... and jump to .Lerror if it is non-zero.
ret
Additionally, GCC allows us to specify that it should use CPU flags
as an output "register". This allows us to remove the explicit "setbe"
instruction in the inline assembly, and simplifies the generated
code even further:
xor eax, eax // Clear RAX
vmread rax, rax // Read value into RAX.
jbe .Lerror // Jump to .Lerror on error.
ret
This CL updates all the VMX operations to use the flags directly.
Additionally, we update vmread to use a register as the destination
operand. No other VMX function appears affected by this latter problem.
Original-Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/552472
Original-Revision: 8d534498ca851ea237ad909d7e9d5750f30c705f
GitOrigin-RevId: 87ad924401b8fd56cda62de590d54fb0bcff5641
Change-Id: I6005202b1fd3dd3220a41518475e6c5404dd8ef7
This repository contains Fuchsia's Global Integration manifest files.
All changes should be made to the internal version of this repository. Our infrastructure automatically updates this version when the internal one changes.
Currently all changes must be made by a Google employee. Non-Google employees wishing to make a change can ask for assistance via the IRC channel #fuchsia on Freenode.
First install Jiri.
Next run:
$ jiri init $ jiri import minimal https://fuchsia.googlesource.com/integration $ jiri update
Third party projects should have their own subdirectory in ./third_party.