From nobody Wed Dec 17 12:17:22 2025 Received: from mail-ot1-f73.google.com (mail-ot1-f73.google.com [209.85.210.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 158AF3557FE for ; Tue, 28 Oct 2025 21:21:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761686466; cv=none; b=q6GcXZzsYcAPUvylUwNCZVL5auWGInZKomufeJ+TZhDi7aLPRyqKPoo9pNshNi3NDwf4MwVF7hf0vtFmTIOPhE9CqfSB3m184/7hG1F65O/CqhStCZw9YxALXWsZ11YddRwlPid9s1FUeb5k/dSBmq561VJmA1OlPll+NU853EE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761686466; c=relaxed/simple; bh=1pFhFcxcWb6H73VV7nWvHIQIecGrbGn1xVkopoQFDws=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=sCoMog7F6jMx1Bei3Tm6RleXCf/Ns6YuYtqEnHrhE1XHEyJp0Y+01Kl8sOrDPLRjzvfHAaKxpxybsXUIBmswAtOpKMRjOBB0f9T2FpdnrKWHtjWHuQDUyhbogNEeQnlWduGo4QMOgOmd/13Gxb9tTZ0ZpX5COs/0AYJdtc+bxJI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--sagis.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=HN76BPW4; arc=none smtp.client-ip=209.85.210.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--sagis.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="HN76BPW4" Received: by mail-ot1-f73.google.com with SMTP id 46e09a7af769-7c53030704dso7766522a34.1 for ; Tue, 28 Oct 2025 14:21:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1761686463; x=1762291263; darn=vger.kernel.org; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:from:to:cc:subject:date:message-id :reply-to; bh=9afY0QTIDk71MMQfwJiwQWcpoO0hDRu8Jah9GndkX2I=; b=HN76BPW4MsyvwV29yjqtwtsky0Ht9BERVKpoAQJ42oabUxIw0JWZS38ayl/bTHphxb NF6e3v4se1vBpPVd/+Bsnz/dYKkfUO9XnpoouvWJlYmRS0uSG5eHZSgBiIG99yi1HwdH 3bh1DZqFq5uMYmQ5ZuzLxYurxTzI5kKh1RwueOpjHvYDZkxYHJ2JIvapYYgWWcs5SRd/ WLXLbhkU7AKWee10I5lFQIzzy18HY058N8zdGagstQ7nWHaWW9MAUW0LvTv1R75+49Ue kbDBaWzuSFiupfXLTitHB0GsHueygAuOcYek9zDEwz2kZ+rGnCfruhyQ07djaTk2S10F XdLA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1761686463; x=1762291263; h=content-transfer-encoding:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:x-gm-message-state:from:to:cc:subject :date:message-id:reply-to; bh=9afY0QTIDk71MMQfwJiwQWcpoO0hDRu8Jah9GndkX2I=; b=hsAgh7lrW+sK/+viTe+U2oHuEk+0ZEmSYU5FU4dJsMmeoOejCZVmLcLMpiaMTFMpli F2ATHc7OQ8uBVvlBrBDT6BYND5Yj8YVYutHZR33myee2med6WU7TSn/o7OU9lpoOfNKC W3rKPZzPxQ1oen7AYWLZXTbKZfhl3fpwzW5pAqKQoeUVJmtrw8Z4o4Em0pDJ1ojrkrxo jOlNagXXAteBs/VGaXowGbs6mEQ8rwQYBOrSKWDUl8xjYBYbUUS1uMUNyTjYC1eoI41E 2reJVYcIXlXSHi+wZtsWn37k6/J3noebNddMKpqfMuRGyMyoAzAtie04yqtDKmuvVXFS qpuw== X-Gm-Message-State: AOJu0Yx0Z2BgV6gY1hFsKuXN7gp6pMm7JlZsxd7Ko2E9gTAtHEd3tz4n qQxZCr7jZ6Aqu5E9vqejwa2hOg6K0TKwzeQfENSlf6SSEPFPAqUPels5X2e/e+OlUfSpKHWp2Ig cPw== X-Google-Smtp-Source: AGHT+IHl/b16hj3J2TqA3wFZ2Y7a2bBoYwoEq0S++TA6ohiqPUzOF/4wHSzUC2JZ+xQVjNTQKb+DTE0UQg== X-Received: from oiky14.prod.google.com ([2002:a05:6808:c08e:b0:44d:bb41:de3f]) (user=sagis job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6808:1829:b0:44f:6d6e:14af with SMTP id 5614622812f47-44f7a420012mr525641b6e.12.1761686463193; Tue, 28 Oct 2025 14:21:03 -0700 (PDT) Date: Tue, 28 Oct 2025 21:20:34 +0000 In-Reply-To: <20251028212052.200523-1-sagis@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251028212052.200523-1-sagis@google.com> X-Mailer: git-send-email 2.51.1.851.g4ebd6896fd-goog Message-ID: <20251028212052.200523-9-sagis@google.com> Subject: [PATCH v12 08/23] KVM: selftests: Define structs to pass parameters to TDX boot code From: Sagi Shahar To: linux-kselftest@vger.kernel.org, Paolo Bonzini , Shuah Khan , Sean Christopherson , Ackerley Tng , Ryan Afranji , Andrew Jones , Isaku Yamahata , Erdem Aktas , Rick Edgecombe , Sagi Shahar , Roger Wang , Binbin Wu , Oliver Upton , "Pratik R. Sampat" , Reinette Chatre , Ira Weiny , Chao Gao , Chenyi Qiang Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" TDX registers are inaccessible to KVM. Therefore we need a different mechanism to load boot parameters for TDX code. TDX boot code will read the registers values from memory and set the registers manually. This patch defines the data structures used to communicate between c code and the TDX assembly boot code which will be added in a later patch. Use kbuild.h to expose the offsets into the structs from c code to assembly code. Reviewed-by: Binbin Wu Co-developed-by: Ackerley Tng Signed-off-by: Ackerley Tng Signed-off-by: Sagi Shahar --- tools/testing/selftests/kvm/Makefile.kvm | 18 +++++ .../selftests/kvm/include/x86/tdx/td_boot.h | 69 +++++++++++++++++++ .../kvm/lib/x86/tdx/td_boot_offsets.c | 21 ++++++ 3 files changed, 108 insertions(+) create mode 100644 tools/testing/selftests/kvm/include/x86/tdx/td_boot.h create mode 100644 tools/testing/selftests/kvm/lib/x86/tdx/td_boot_offsets= .c diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selft= ests/kvm/Makefile.kvm index 148d427ff24b..5e809064ff1c 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -19,6 +19,8 @@ LIBKVM +=3D lib/userfaultfd_util.c =20 LIBKVM_STRING +=3D lib/string_override.c =20 +LIBKVM_ASM_DEFS +=3D lib/x86/tdx/td_boot_offsets.c + LIBKVM_x86 +=3D lib/x86/apic.c LIBKVM_x86 +=3D lib/x86/handlers.S LIBKVM_x86 +=3D lib/x86/hyperv.c @@ -239,6 +241,10 @@ OVERRIDE_TARGETS =3D 1 include ../lib.mk include ../cgroup/lib/libcgroup.mk =20 +# Enable Kbuild tools. +include $(top_srcdir)/scripts/Kbuild.include +include $(top_srcdir)/scripts/Makefile.lib + INSTALL_HDR_PATH =3D $(top_srcdir)/usr LINUX_HDR_PATH =3D $(INSTALL_HDR_PATH)/include/ LINUX_TOOL_INCLUDE =3D $(top_srcdir)/tools/include @@ -291,6 +297,7 @@ LIBKVM_S :=3D $(filter %.S,$(LIBKVM)) LIBKVM_C_OBJ :=3D $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_C)) LIBKVM_S_OBJ :=3D $(patsubst %.S, $(OUTPUT)/%.o, $(LIBKVM_S)) LIBKVM_STRING_OBJ :=3D $(patsubst %.c, $(OUTPUT)/%.o, $(LIBKVM_STRING)) +LIBKVM_ASM_DEFS_OBJ +=3D $(patsubst %.c, $(OUTPUT)/%.s, $(LIBKVM_ASM_DEFS)) LIBKVM_OBJS =3D $(LIBKVM_C_OBJ) $(LIBKVM_S_OBJ) $(LIBKVM_STRING_OBJ) $(LIB= CGROUP_O) SPLIT_TEST_GEN_PROGS :=3D $(patsubst %, $(OUTPUT)/%, $(SPLIT_TESTS)) SPLIT_TEST_GEN_OBJ :=3D $(patsubst %, $(OUTPUT)/$(ARCH)/%.o, $(SPLIT_TESTS= )) @@ -317,6 +324,7 @@ $(SPLIT_TEST_GEN_OBJ): $(OUTPUT)/$(ARCH)/%.o: $(ARCH)/%= .c =20 EXTRA_CLEAN +=3D $(GEN_HDRS) \ $(LIBKVM_OBJS) \ + $(LIBKVM_ASM_DEFS_OBJ) \ $(SPLIT_TEST_GEN_OBJ) \ $(TEST_DEP_FILES) \ $(TEST_GEN_OBJ) \ @@ -328,18 +336,28 @@ $(LIBKVM_C_OBJ): $(OUTPUT)/%.o: %.c $(GEN_HDRS) $(LIBKVM_S_OBJ): $(OUTPUT)/%.o: %.S $(GEN_HDRS) $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ =20 +$(LIBKVM_ASM_DEFS_OBJ): $(OUTPUT)/%.s: %.c FORCE + $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -S $< -o $@ + # Compile the string overrides as freestanding to prevent the compiler from # generating self-referential code, e.g. without "freestanding" the compil= er may # "optimize" memcmp() by invoking memcmp(), thus causing infinite recursio= n. $(LIBKVM_STRING_OBJ): $(OUTPUT)/%.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -ffreestanding $< -o $@ =20 +$(OUTPUT)/include/x86/tdx/td_boot_offsets.h: $(OUTPUT)/lib/x86/tdx/td_boot= _offsets.s FORCE + $(call filechk,offsets,__TDX_BOOT_OFFSETS_H__) + +EXTRA_CLEAN +=3D $(OUTPUT)/include/x86/tdx/td_boot_offsets.h + $(shell mkdir -p $(sort $(dir $(TEST_GEN_PROGS)))) $(SPLIT_TEST_GEN_OBJ): $(GEN_HDRS) $(TEST_GEN_PROGS): $(LIBKVM_OBJS) $(TEST_GEN_PROGS_EXTENDED): $(LIBKVM_OBJS) $(TEST_GEN_OBJ): $(GEN_HDRS) =20 +FORCE: + cscope: include_paths =3D $(LINUX_TOOL_INCLUDE) $(LINUX_HDR_PATH) include = lib .. cscope: $(RM) cscope.* diff --git a/tools/testing/selftests/kvm/include/x86/tdx/td_boot.h b/tools/= testing/selftests/kvm/include/x86/tdx/td_boot.h new file mode 100644 index 000000000000..32631645fe13 --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/tdx/td_boot.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTEST_TDX_TD_BOOT_H +#define SELFTEST_TDX_TD_BOOT_H + +#include + +#include +#include + +/* + * Layout for boot section (not to scale) + * + * GPA + * _________________________________ 0x1_0000_0000 (4GB) + * | Boot code trampoline | + * |___________________________|____ 0x0_ffff_fff0: Reset vector (16B belo= w 4GB) + * | Boot code | + * |___________________________|____ td_boot will be copied here, so that = the + * | | jmp to td_boot is exactly at the rese= t vector + * | Empty space | + * | | + * |=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80| + * | | + * | | + * | Boot parameters | + * | | + * | | + * |___________________________|____ 0x0_ffff_0000: TD_BOOT_PARAMETERS_GPA + */ +#define FOUR_GIGABYTES_GPA (SZ_4G) + +/* + * The exact memory layout for LGDT or LIDT instructions. + */ +struct __packed td_boot_parameters_dtr { + uint16_t limit; + uint32_t base; +}; + +/* + * Allows each vCPU to be initialized with different rip and esp. + */ +struct td_per_vcpu_parameters { + uint32_t esp_gva; + uint64_t guest_code; +}; + +/* + * Boot parameters for the TD. + * + * Unlike a regular VM, KVM cannot set registers such as esp, eip, etc + * before boot, so to run selftests, these registers' values have to be + * initialized by the TD. + * + * This struct is loaded in TD private memory at TD_BOOT_PARAMETERS_GPA. + * + * The TD boot code will read off parameters from this struct and set up t= he + * vCPU for executing selftests. + */ +struct td_boot_parameters { + uint32_t cr0; + uint32_t cr3; + uint32_t cr4; + struct td_boot_parameters_dtr gdtr; + struct td_boot_parameters_dtr idtr; + struct td_per_vcpu_parameters per_vcpu[]; +}; + +#endif /* SELFTEST_TDX_TD_BOOT_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/tdx/td_boot_offsets.c b/to= ols/testing/selftests/kvm/lib/x86/tdx/td_boot_offsets.c new file mode 100644 index 000000000000..7f76a3585b99 --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86/tdx/td_boot_offsets.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 +#define COMPILE_OFFSETS + +#include + +#include "tdx/td_boot.h" + +static void __attribute__((used)) common(void) +{ + OFFSET(TD_BOOT_PARAMETERS_CR0, td_boot_parameters, cr0); + OFFSET(TD_BOOT_PARAMETERS_CR3, td_boot_parameters, cr3); + OFFSET(TD_BOOT_PARAMETERS_CR4, td_boot_parameters, cr4); + OFFSET(TD_BOOT_PARAMETERS_GDT, td_boot_parameters, gdtr); + OFFSET(TD_BOOT_PARAMETERS_IDT, td_boot_parameters, idtr); + OFFSET(TD_BOOT_PARAMETERS_PER_VCPU, td_boot_parameters, per_vcpu); + OFFSET(TD_PER_VCPU_PARAMETERS_ESP_GVA, td_per_vcpu_parameters, esp_gva); + OFFSET(TD_PER_VCPU_PARAMETERS_GUEST_CODE, td_per_vcpu_parameters, + guest_code); + DEFINE(SIZEOF_TD_PER_VCPU_PARAMETERS, + sizeof(struct td_per_vcpu_parameters)); +} --=20 2.51.1.851.g4ebd6896fd-goog