Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Intel Trust Domain Extensions (TDX) #228

Draft
wants to merge 36 commits into
base: main
Choose a base branch
from

Conversation

jakecorrenti
Copy link
Member

@jakecorrenti jakecorrenti commented Oct 21, 2024

This PR adds support for the Intel Trust Domain Extensions (TDX) Confidential Computing architecture.

This is currently a draft as the following issues are present:

  • The guest is failing to complete the boot sequence. I suspect this is due to firmware issues, such as a lack of proper IDT setup and #VE handling
  • https://www.github.com/virtee/tdx needs to get published to crates.io before this can get merged

Before merging there are some commits that will be squashed and/or re-ordered.

There is also additional functionality that I would like to add such as:

  • Comprehensive CPUID configuration based off of the TDX capabilities reported by KVM_TDX_CAPABILITIES
  • Handle the following VMCALLs
    • TDG.VP.VMCALL<SetupEventNotifyInterrupt>
    • TDG.VP.VMCALL<GetQuote>
    • TDG.VP.VMCALL<MapGPA>
    • TDG.VP.VMCALL<REPORT_FATAL_ERROR>
  • Validate TDX Attributes when reported by KVM_TDX_CAPABILITIES
  • Update README.md and other docs
  • Make sure guests work with varying memory and vCPU configurations

Any early reviews are welcome.

Fixes some of the existing feature flags for `tee` and `amd-sev` to be
more generic.

Signed-off-by: Jake Correnti <[email protected]>
Adjust the Makefile to use a TDX environment variable.

Fix the launch-tee.c test source code so that it compiles.

Signed-off-by: Jake Correnti <[email protected]>
Add a TDX target for the Makefile.

Signed-off-by: Jake Correnti <[email protected]>
Adds the VirTEE TDX crate and also updates the versions of the
kvm-ioctls and the kvm-bindings crates since they require newer features
for the TDX crate to work.

Adds the "intel-tdx" feature flag.

Signed-off-by: Jake Correnti <[email protected]>
In `memory_init` we need to use `kvm_userspace_memory_region2`,
`kvm_create_guest_memfd`, and `kvm_memory_attributes` for the TDX
architecture, otherwise it will fail.

Signed-off-by: Jake Correnti <[email protected]>
Adds a new `inteltdx` module and implements a feature-flagged `new`
method for `VM to create a VM with the TDX architecure.

Signed-off-by: Jake Correnti <[email protected]>
Implements the `tdx_secure_virt_prepare` method which
in turn calls the `KVM_TDX_INIT_VM` TDX ioctl which does VM specific
initialization.

Signed-off-by: Jake Correnti <[email protected]>
After creating each x86_64 vCPU, call `KVM_TDX_INIT_VCPU` which does
TDX-specific vCPU initialization.

Signed-off-by: Jake Correnti <[email protected]>
Adds definitions from UEFI spec for volumes, resources, etc. and adds
related types.

Signed-off-by: Jake Correnti <[email protected]>
Adds the `TdxRamType` and `TdxRamEntry` structs.

Signed-off-by: Jake Correnti <[email protected]>
Adds the `TdxFirmwareEntry` struct.

Adds the`TdxHob` struct and `TdxHob::new(&TdxFirmwareEntry)` associative
function.

Signed-off-by: Jake Correnti <[email protected]>
Adds the `IntelTdx` method `init_ram_entries` which converts a list of
e820 ram entries into TDX ram entries.

Signed-off-by: Jake Correnti <[email protected]>
Adds API to the `inteltdx` module to create a TD Hand-off-block which
will be used by libkrun to communicate with the TD Virtual Firmware.

Signed-off-by: Jake Correnti <[email protected]>
Adds the `configure_td_memory` method to `IntelTdx` which does the
following:
- Initialize the TDX Ram entries
- Copies the Bfv and Cfv TDVF sections into guest memory
- Calls `tdx_accept_ram_range` on the TdHob and TempMem TDVF sections
- Creates the TD Hob
- Calls `KVM_TDX_INIT_MEM_REGION` for each TDVF section

Signed-off-by: Jake Correnti <[email protected]>
Wires together the code to configure the TD memory regions.

Signed-off-by: Jake Correnti <[email protected]>
Call `KVM_TDX_FINALIZE_VM` which finalizes the initial measurements for
the TD.

Signed-off-by: Jake Correnti <[email protected]>
For TDX we don't want to use the `KVM_CREATE_IRQCHIP` but rather enable
the `KVM_SPLIT_IRQCHIP` capability (which the TDX library does).

Signed-off-by: Jake Correnti <[email protected]>
TDX doesn't allow the VMM to configure the registers since they're
confidential.

Signed-off-by: Jake Correnti <[email protected]>
TDX doesn't use a "standard" BIOS layout when compared to a typical
x86_64 system because it uses TDVF as its BIOS. Makes sure we have the
right regions mapped to the guest so we can copy the firmware into those
addresses later on.

Signed-off-by: Jake Correnti <[email protected]>
Ensures that rustc links with the libkrunfw-tdx flavor when the
intel-tdx feature flag is enabled.

Signed-off-by: Jake Correnti <[email protected]>
Signed-off-by: Jake Correnti <[email protected]>
…r seems to work as expected...

Signed-off-by: Jake Correnti <[email protected]>
…written section at the reset vector

Signed-off-by: Jake Correnti <[email protected]>
…eed to try and re-write it closer to QEMU implementation

Signed-off-by: Jake Correnti <[email protected]>
This should determine the size of the TDVF image, determine where in the
guest offset from the top of the memory region it should land, and then
in `load_payload` it should read the contents of the firmware file into
guest memory at the right location.

This *should* line up with the commit from v5 of the QEMU patches called
"load TDVF for TD guest"

Signed-off-by: Jake Correnti <[email protected]>
We need to keep track of the e820 ram regions for TDX for future
configuration of the TD HOB.

Signed-off-by: Jake Correnti <[email protected]>
This will be where all of the TDVF configuration is done.

Signed-off-by: Jake Correnti <[email protected]>
Keep track of the host address for all the TDVF sections

Signed-off-by: Jake Correnti <[email protected]>
A TDX VM's RAM can be classified into two types:

- TDX_RAM_UNACCEPTED: default type of TDX memory, which needs to be
  accepted by the TDX guest before it can be used and will be all-zeroes
  after being accepted.
- TDX_RAM_ADDED: the RAM that is ADD'ed to TD guest before running, and
  can be used directly e.g., TD HOB and TEMP MEM that are needed by
  TDVF.

Maintain a collection of TdxRamEntries which uses the intial ram entries
from the e820 table and mark each RAM range as the default
TDX_RAM_UNACCEPTED type.

Turn the range of TD HOB and TEMP MEM to TDX_RAM_ADDED since those
ranges will be ADD'ed before the TD runs and no need to be accepted at
runtime.

The collection of TdxRamEntries are later used to setup the memory TD
resource HOB that passes memory info from libkrun to the TDVF.

Signed-off-by: Jake Correnti <[email protected]>
Signed-off-by: Jake Correnti <[email protected]>
Have debug output from edk2 redirected to stdout.

In edk2, TDX assumes that PCI is present. Libkrun doesn't use PCI or
ACPI. We either need to add it or change edk2 accordingly.

Signed-off-by: Jake Correnti <[email protected]>
Feeding libkrun TDVF as the firmware results in a failed assertion in
edk2 because libkrun doesnt' support PCI or ACPI, which are both
required for edk2 to work properly. Therefore, we should try to use
qboot instead.

Currently, qboot is starting the VM boot process, but it will triple
fault once control gets given to the vCPU. I theorize this is because
there isn't anything in the hypervisor or the firmware that knows how to
deal with a #VE (Virtualization Exception). Therefore, the exception
can't get handled and causes a double, then triple, fault.

Signed-off-by: Jake Correnti <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant