[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
1 file changed
tree: d8d9add092ac1db127e3d2cb00757c5b71068886
  1. garnet/
  2. infra/
  3. peridot/
  4. third_party/
  5. topaz/
  6. zircon/
  7. firmware
  8. flower
  9. jiri.lock
  10. minimal
  11. prebuilts
  12. README.md
  13. stem
  14. test_durations
README.md

Integration

This repository contains Fuchsia's Global Integration manifest files.

Making changes

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.

Obtaining the source

First install Jiri.

Next run:

$ jiri init
$ jiri import minimal https://fuchsia.googlesource.com/integration
$ jiri update

Third party

Third party projects should have their own subdirectory in ./third_party.