Skip to content

Update KVM-TDX.README.md #1

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

Closed
wants to merge 10 commits into from
Closed
172 changes: 172 additions & 0 deletions KVM-TDX.README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
repositories and branches
=========================
Linux
-----
git repository:
https://github.com/intel/tdx

branchs:
kvm-upstream-workaround branch is recommended.
- kvm-upstream: includes patches only posted to the linux and kvm community.
- kvm-upstream-workaround: includes kvm-upstream and further patches.
If you tests TDX KVM, kvm-upstream-workaround branch is recommended.

Configurations:
- CONFIG_INTEL_TDX_HOST=y: enable TDX KVM support.
- CONFIG_INTEL_TDX_HOST_DEBUG: debug support for TDX module. optional. say N.
- CONFIG_INTEL_TDX_GUEST: guest TD support. Optional. Not needed for TDX KVM.
- CONFIG_X86_TDX_KVM_EXPERIMENTAL=y: Enable experimental TDX KVM support. Optional, needed for https://github.com/intel/tdx/releases/tag/kvm-upstream-2022.03.29-v5.17-rc8-workaround. TDX KVM needs many patches and the patches will be merged step by step, not at once. Set it to y to enable TDX KVM support so that developper can exercise TDX KVM code.

kernel command line:
- tdx_host=on
Enables TDX features in host kernel. Because it's off by default, it needs to be
explicitly enabled.
- disable_mtrr_cleanup

Qemu
----
git repository:
https://github.com/intel/qemu-tdx

branches:
tdx-upstream-wip branch is recommended.
- tdx: includes full features. It's being deprecated in favor for tdx-upstream-wip.
- tdx-upstream: includes patches only posted to the qemu community
- tdx-upstream-wip: includes tdx-upstream and further patches.

build:
build x86_64-softmmu target.
./configure --target-list=x86_64-softmmu

kvm-unit-tests
--------------
git repository:
https://github.com/intel/kvm-unit-tests-tdx

branches:
- tdx: include test cases for TDX.

TDVF
----
git repository:
https://github.com/tianocore/edk2-staging/tree/TDVF

Please refer its documentation for further information.
https://github.com/tianocore/edk2-staging/blob/TDVF/README.md

Guest
-----
git repository:
https://github.com/intel/tdx

branches:
- guest-upstream: guest TD support for upstreaming
- guest: guest TD support

Configurations:
- CONFIG_INTEL_TDX_GUEST=y

Unit Testing
============
selftests and kvm-unit-tests are available for TDX KVM.

selftests
---------
linux/tools/testing/selftests/kvm/x86_64/tdx_vm_tests

kvm-unit-tests
--------------
For running unit tests with TDX enabled, refer to
https://github.com/intel/kvm-unit-tests-tdx/blob/tdx/README.md#unit-test-in-tdx-environment


Running guest TD
================
qemu tdx-upstream-wip branch
----------------------------
- create tdx-guest object.
-object tdx-guest,id=tdx0,debug=off,sept-ve-disable=on \
-machine confidential-guest-support=tdx0
- specify q35 chipset and KVM
-machine q35,accel=kvm
- specify TDVF
-bios ${OVMF}
- specify split irqchip, disable PIC and PIT
-machine kernel-irqchip=split,pic=off,pit=off

command line example:
SMP=8
MEM=512M
KERNEL=/path/to/guest-kernel
INITRD=/path/to/guest-initrd
APPEND="console=hvc0 nomce no-kvmclock no-steal-acc no_console_suspend"
DRIVE_DISC=/path/to/disk-image
OVMF=/path/to/OVMF.fd
qemu-system-x86_64 \
-s -m ${MEM} -smp ${SMP},sockets=1 \
-cpu host,host-phys-bits,pmu=off,pks=on \
-no-hpet -nographic -vga none \
-nodefaults \
-monitor stdio \
-object tdx-guest,id=tdx0,debug=off,sept-ve-disable=on \
-machine confidential-guest-support=tdx0 \
-machine q35,accel=kvm \
-machine kernel-irqchip=split,sata=off,pic=off,pit=off \
-bios ${OVMF} \
-device virtio-serial \
-chardev socket,id=tcp0,port=4445,host=0.0.0.0,server=on,wait=off \
-device virtconsole,chardev=tcp0 \
-kernel ${KERNEL} \
-initrd ${INITRD} \
-append "${APPEND}" \
-drive file=${DRIVE_DISK},if=virtio,format=qcow2,media=disk,index=0 \
-device vhost-vsock-pci,guest-cid=3


qemu tdx branch
---------------
- create tdx-guest object.
-object tdx-guest,id=tdx0,debug=off,sept-ve-disable=on \
-machine confidential-guest-support=tdx0
- specify q35 chipset, KVM and tdx kvm vm type.
-machine q35,accel=kvm,kvm-type=tdx
- specify TDVF
-device loader,file=${OVMF}
or
-device loader,file=${OVMF_CODE},config-firmware-volume=${OVMF_VARS},id=fd0
- specify split irqchip, disable PIC and PIT
-machine kernel-irqchip=split,pic=off,pit=off
- UPM (Unmapping Process Memory): create memfd-private backend
-object memory-backend-memfd-private,id=ram1,size=${MEM} \
-machine memory-backend=ram1

command line example:
SMP=8
MEM=512M
KERNEL=/path/to/guest-kernel
INITRD=/path/to/guest-initrd
APPEND="console=hvc0 nomce no-kvmclock no-steal-acc no_console_suspend"
DRIVE_DISC=/path/to/disk-image
OVMF_CODE=/path/to/OVMF_CODE.fd
OVMF_VARS=/path/to/OVMF_VARS.fd
qemu-system-x86_64 \
-s -m ${MEM} -smp ${SMP},sockets=1 \
-cpu host,host-phys-bits,pmu=off,pks=on \
-no-hpet -nographic -vga none \
-nodefaults \
-monitor stdio \
-object tdx-guest,id=tdx0,debug=off,sept-ve-disable=on \
-machine confidential-guest-support=tdx0 \
-machine q35,accel=kvm,kvm-type=tdx \
-machine kernel-irqchip=split,sata=off,pic=off,pit=off \
-object memory-backend-memfd-private,id=ram1,size=${MEM} \
-machine memory-backend=ram1 \
-device loader,file=${OVMF_CODE},config-firmware-volume=${OVMF_VARS},id=fd0 \
-kernel ${KERNEL} \
-initrd ${INITRD} \
-append "${APPEND}" \
-device virtio-serial \
-chardev socket,id=tcp0,port=4445,host=0.0.0.0,server=on,wait=off \
-device virtconsole,chardev=tcp0 \
-drive file=${DRIVE_DISK},if=virtio,format=qcow2,media=disk,index=0 \
-device vhost-vsock-pci,guest-cid=3
5 changes: 3 additions & 2 deletions arch/x86/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -1444,7 +1444,8 @@ struct kvm_x86_ops {
void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
void (*enable_irq_window)(struct kvm_vcpu *vcpu);
void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
bool (*check_apicv_inhibit_reasons)(enum kvm_apicv_inhibit reason);
bool (*check_apicv_inhibit_reasons)(struct kvm *kvm,
enum kvm_apicv_inhibit reason);
void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr);
Expand Down Expand Up @@ -1678,7 +1679,7 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned long kvm_nr_mmu_pages);

#ifdef CONFIG_INTEL_TDX_HOST
int kvm_mmu_is_page_private(struct kvm *kvm, struct kvm_memory_slot *memslot,
gfn_t gfn, bool *is_private);
gfn_t gfn, bool *is_private, kvm_pfn_t *pfn);
#endif

int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3);
Expand Down
4 changes: 0 additions & 4 deletions arch/x86/kvm/mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,10 +270,6 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
}

void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end);
#ifdef CONFIG_INTEL_TDX_HOST
int kvm_tdp_mmu_is_page_private(struct kvm *kvm, struct kvm_memory_slot *memslot,
gfn_t gfn, bool *is_private);
#endif

int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);

Expand Down
14 changes: 13 additions & 1 deletion arch/x86/kvm/mmu/mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -7251,13 +7251,25 @@ void kvm_mmu_pre_destroy_vm(struct kvm *kvm)
*/
int kvm_mmu_is_page_private(struct kvm *kvm,
struct kvm_memory_slot *memslot,
gfn_t gfn, bool *is_private)
gfn_t gfn, bool *is_private, kvm_pfn_t *pfn)
{
struct slot_rmap_walk_iterator s_iter;
struct rmap_iterator r_iter;
u64 *sptep;
int ret = -EINVAL;

if (kvm_slot_is_private(memslot)) {
int order;

/* The caller must call kvm_memfile_put_pfn(memslot, pfn); */
*pfn = kvm_memfile_get_pfn(memslot, gfn, &order);
*is_private = VALID_PAGE(*pfn);
return 0;
}

if (is_tdp_mmu_enabled(kvm))
return kvm_tdp_mmu_is_page_private(kvm, memslot, gfn, is_private);

for_each_slot_rmap_range(memslot, PG_LEVEL_4K,
KVM_MAX_HUGEPAGE_LEVEL,
gfn, gfn, &s_iter) {
Expand Down
12 changes: 12 additions & 0 deletions arch/x86/kvm/mmu/tdp_mmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,16 @@ static inline bool is_tdp_mmu_page(struct kvm_mmu_page *sp) { return false; }
static inline bool is_tdp_mmu(struct kvm_mmu *mmu) { return false; }
#endif

#ifdef CONFIG_INTEL_TDX_HOST
int kvm_tdp_mmu_is_page_private(struct kvm *kvm, struct kvm_memory_slot *memslot,
gfn_t gfn, bool *is_private);
#else
static inline int kvm_tdp_mmu_is_page_private(
struct kvm *kvm, struct kvm_memory_slot *memslot, gfn_t gfn,
bool *is_private)
{
return -EOPNOTSUPP;
}
#endif

#endif /* __KVM_X86_MMU_TDP_MMU_H */
3 changes: 2 additions & 1 deletion arch/x86/kvm/svm/avic.c
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,8 @@ int avic_pi_update_irte(struct kvm *kvm, unsigned int host_irq,
return ret;
}

bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason)
bool avic_check_apicv_inhibit_reasons(struct kvm *kvm,
enum kvm_apicv_inhibit reason)
{
ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
BIT(APICV_INHIBIT_REASON_ABSENT) |
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/kvm/svm/svm.h
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,8 @@ void __avic_vcpu_put(struct kvm_vcpu *vcpu);
void avic_apicv_post_state_restore(struct kvm_vcpu *vcpu);
void avic_set_virtual_apic_mode(struct kvm_vcpu *vcpu);
void avic_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu);
bool avic_check_apicv_inhibit_reasons(enum kvm_apicv_inhibit reason);
bool avic_check_apicv_inhibit_reasons(struct kvm *kvm,
enum kvm_apicv_inhibit reason);
void avic_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr);
void avic_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr);
bool avic_dy_apicv_has_pending_interrupt(struct kvm_vcpu *vcpu);
Expand Down
15 changes: 12 additions & 3 deletions arch/x86/kvm/vmx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ static void vt_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
static void vt_update_exception_bitmap(struct kvm_vcpu *vcpu)
{
if (is_td_vcpu(vcpu))
return;
return tdx_update_exception_bitmap(vcpu);

vmx_update_exception_bitmap(vcpu);
}
Expand Down Expand Up @@ -454,7 +454,7 @@ static void vt_set_gdt(struct kvm_vcpu *vcpu, struct desc_ptr *dt)
static void vt_set_dr7(struct kvm_vcpu *vcpu, unsigned long val)
{
if (is_td_vcpu(vcpu))
return;
return tdx_set_dr7(vcpu, val);

vmx_set_dr7(vcpu, val);
}
Expand Down Expand Up @@ -843,6 +843,15 @@ static int vt_skip_emulated_instruction(struct kvm_vcpu *vcpu)
return vmx_skip_emulated_instruction(vcpu);
}

static bool vt_check_apicv_inhibit_reasons(struct kvm *kvm,
enum kvm_apicv_inhibit reason)
{
if (is_td(kvm))
return tdx_check_apicv_inhibit_reasons(kvm, reason);

return vmx_check_apicv_inhibit_reasons(kvm, reason);
}

struct kvm_x86_ops vt_x86_ops __initdata = {
.name = "kvm_intel",

Expand Down Expand Up @@ -920,7 +929,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = {
.refresh_apicv_exec_ctrl = vt_refresh_apicv_exec_ctrl,
.load_eoi_exitmap = vt_load_eoi_exitmap,
.apicv_post_state_restore = vt_apicv_post_state_restore,
.check_apicv_inhibit_reasons = vmx_check_apicv_inhibit_reasons,
.check_apicv_inhibit_reasons = vt_check_apicv_inhibit_reasons,
.hwapic_irr_update = vt_hwapic_irr_update,
.hwapic_isr_update = vt_hwapic_isr_update,
.guest_apic_has_interrupt = vt_guest_apic_has_interrupt,
Expand Down
Loading