Re: [PATCH v14 11/22] KVM: selftests: Set up TDX boot parameters region

Binbin Wu <[email protected]>
Newsgroups org.kernel.vger.kvm,dev.linux.lists.linux-coco,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest
Message-ID <[email protected]>
On 7/23/2026 7:13 AM, Lisa Wang wrote:
> From: Sagi Shahar <[email protected]>
> 
> Allocate memory for TDX boot parameters and define the utility functions
> necessary to fill this memory with the boot parameters.

The code change looks good to me.

But I think it's better to describe how the parameters are initialized based
on the HVA when VM_MEM_SRC_SHMEM is used alongside KVM_MEM_GUEST_MEMFD.
Same for the patch 10.

> 
> Co-developed-by: Ackerley Tng <[email protected]>
> Signed-off-by: Ackerley Tng <[email protected]>
> Signed-off-by: Sagi Shahar <[email protected]>
> Signed-off-by: Lisa Wang <[email protected]>
> ---
>  .../selftests/kvm/include/x86/tdx/tdx_util.h       |  2 +
>  tools/testing/selftests/kvm/lib/x86/processor.c    |  2 +
>  tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c | 51 ++++++++++++++++++++++
>  3 files changed, 55 insertions(+)
> 
> diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
> index 642ffa010da3..f5003cbaa106 100644
> --- a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
> +++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
> @@ -46,5 +46,7 @@ static inline bool is_tdx_vm(struct kvm_vm *vm)
>  
>  void tdx_init_vm(struct kvm_vm *vm, u64 attributes);
>  void tdx_vm_setup_boot_code_region(struct kvm_vm *vm);
> +void tdx_vm_setup_boot_parameters_region(struct kvm_vm *vm, u32 nr_runnable_vcpus);
> +void tdx_vm_load_common_boot_parameters(struct kvm_vm *vm);
>  
>  #endif /* SELFTESTS_TDX_TDX_UTIL_H */
> diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c
> index f93953777ca1..748c6041f8bf 100644
> --- a/tools/testing/selftests/kvm/lib/x86/processor.c
> +++ b/tools/testing/selftests/kvm/lib/x86/processor.c
> @@ -794,6 +794,8 @@ void kvm_arch_vm_post_create(struct kvm_vm *vm, unsigned int nr_vcpus)
>  	if (is_tdx_vm(vm)) {
>  		tdx_init_vm(vm, 0);
>  		tdx_vm_setup_boot_code_region(vm);
> +		tdx_vm_setup_boot_parameters_region(vm, nr_vcpus);
> +		tdx_vm_load_common_boot_parameters(vm);
>  	}
>  
>  	r = __vm_ioctl(vm, KVM_GET_TSC_KHZ, NULL);
> diff --git a/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c b/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
> index d64d153d19e2..2ce8c297f7ed 100644
> --- a/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
> +++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c
> @@ -6,6 +6,7 @@
>  
>  /* Arbitrarily selected to avoid overlaps with anything else */
>  #define TD_BOOT_CODE_SLOT	20
> +#define TD_BOOT_PARAMETERS_SLOT	21
>  
>  #define X86_RESET_VECTOR	0xfffffff0ul
>  #define X86_RESET_VECTOR_SIZE	16
> @@ -49,6 +50,56 @@ void tdx_vm_setup_boot_code_region(struct kvm_vm *vm)
>  	hva[2] = 0xcc;
>  }
>  
> +void tdx_vm_setup_boot_parameters_region(struct kvm_vm *vm, u32 nr_runnable_vcpus)
> +{
> +	size_t boot_params_size =
> +		sizeof(struct td_boot_parameters) +
> +		nr_runnable_vcpus * sizeof(struct td_per_vcpu_parameters);
> +	int npages = DIV_ROUND_UP(boot_params_size, PAGE_SIZE);
> +	const u64 gmem_flags = 0;
> +	gpa_t gpa;
> +
> +	vm_mem_add(vm, VM_MEM_SRC_SHMEM, TD_BOOT_PARAMETERS_GPA,
> +		   TD_BOOT_PARAMETERS_SLOT, npages,
> +		   KVM_MEM_GUEST_MEMFD, -1, 0, gmem_flags);
> +	gpa = vm_phy_pages_alloc(vm, npages, TD_BOOT_PARAMETERS_GPA, TD_BOOT_PARAMETERS_SLOT);
> +	TEST_ASSERT(gpa == TD_BOOT_PARAMETERS_GPA, "Failed vm_phy_pages_alloc\n");
> +
> +	virt_map(vm, TD_BOOT_PARAMETERS_GPA, TD_BOOT_PARAMETERS_GPA, npages);
> +}
> +
> +void tdx_vm_load_common_boot_parameters(struct kvm_vm *vm)
> +{
> +	struct td_boot_parameters *params =
> +		addr_gpa2hva(vm, TD_BOOT_PARAMETERS_GPA);
> +	u32 cr4;
> +
> +	cr4 = kvm_get_default_cr4(vm->mmu.pgtable_levels);
> +
> +	/* TDX spec 11.6.2: CR4 bit MCE is fixed to 1 */
> +	cr4 |= X86_CR4_MCE;
> +
> +	/* TDX spec 11.6.2: CR4 bit VMXE and SMXE are fixed to 0 */
> +	cr4 &= ~(X86_CR4_VMXE | X86_CR4_SMXE);
> +
> +	/* Set parameters! */
> +	params->cr0 = kvm_get_default_cr0();
> +	TEST_ASSERT(vm->mmu.pgd < (1ULL << 32),
> +		    "PGD must be within 32-bit address space for 32-bit boot code");
> +	params->cr3 = vm->mmu.pgd;
> +	params->cr4 = cr4;
> +	params->idtr.base = vm->arch.idt;
> +	params->idtr.limit = kvm_get_default_idt_limit();
> +	params->gdtr.base = vm->arch.gdt;
> +	params->gdtr.limit = kvm_get_default_gdt_limit();
> +
> +	TEST_ASSERT(params->cr0 != 0, "cr0 should not be 0");
> +	TEST_ASSERT(params->cr3 != 0, "cr3 should not be 0");
> +	TEST_ASSERT(params->cr4 != 0, "cr4 should not be 0");
> +	TEST_ASSERT(params->gdtr.base != 0, "gdt base address should not be 0");
> +	TEST_ASSERT(params->idtr.base != 0, "idt base address should not be 0");
> +}
> +
>  static struct kvm_tdx_capabilities *tdx_read_capabilities(struct kvm_vm *vm)
>  {
>  	static struct kvm_tdx_capabilities *tdx_cap;
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.