From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pg1-f198.google.com (mail-pg1-f198.google.com [209.85.215.198]) (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 327525237BA for ; Thu, 1 Oct 2026 19:38:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.198 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790883541; cv=none; b=Q28i9ozvF0niCAv+coKMWS2KwYlltYJakaY+UFu6Ulw1SuUhYdo0kY/gU/aAUQwpFun0huvB9zXJc/z+nBMpoy16b1k783trqKLf6fby7JDlFJScwsKTPKGoARvBcm9rzvnlEdO9Reo3+fPqWSKdEz9DmmXGMYCXmNcoFBMo024= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790883541; c=relaxed/simple; bh=SV/MXgGWckWhx+Jyo7DLJEx2fZgBooEYcqqqXWGamts=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=QOS8sE8tvJRzosrhGfEP20bbcqi6UQw1Ozn87f6MFY+JaEaKgZAdCsge68RHO9SdBw0k7ask3p/C/z2yGpiRdcO4hVmyu9U9BfWkLxjPgXlyde67USlJ5kff1GpknfgctEnep+CUP01pQ3N/cyu1EHlI+OhODxmSL1xIZ/FWt6o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--wyihan.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=cv9bTlqE; arc=none smtp.client-ip=209.85.215.198 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--wyihan.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="cv9bTlqE" Received: by mail-pg1-f198.google.com with SMTP id 41be03b00d2f7-cc4922b7c31so5004604a12.1 for ; Thu, 01 Oct 2026 12:38:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1790883538; x=1791488338; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=rRbrmyW96rrCs3DEZjhRs/AR+c7fdb5fNUuxs/BXvEg=; b=cv9bTlqEC9xgquHi5sFtTY8swUbGVTR5SEJdTjz6uBofq9WMnfKLUmObuowVfmmrbc a5HARBXq3wts/YzZRcp8ciuXP5yVkc7/nqrwu7uJenygF1C4t3duXtizNbESUKQszIIF r2nvM0XW7KuxQs4WX5FM/8Zxgjp7wgUGPcy4tIBkeaOZ005Bx7mW+8c5aWZ/a/lKMsJM KzUaUmEVNimrs7nR95aFIr4q9NJ3TRSLTSQKGYq1SxH/pgPg+krzpcIQ+l4hUOwv+qNg 7xs7Mf4FwYNIpTXkQpm8ioGWSX2WFOlXpYxx84zQoLQG5vtRRrwkSp0E+xi2y8CnzBOe GFvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790883538; x=1791488338; h=content-type: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:content-type; bh=rRbrmyW96rrCs3DEZjhRs/AR+c7fdb5fNUuxs/BXvEg=; b=dSkNMK/Vs92pOnKCs8XN3m1E+FZV+JcyxybV8v0jhEGuKDLCb7z3afBAXMqZa1M/HJ FBPIlfSRd9JH/SNOyBOCLNZUTefrp3gFFd7m14U0dwkNCpV80rGOcMmvm30GeeFZQvLy ok+BXhT8IIO0FSJqzg0ArA/uaDpR/ygHx94UlGRiVE6CgSFd7PScGo6DEX/JTtozCdiZ SNn4xyS5uHdgcHJEKJoFTh8jNt4JHajUqjy/QCHBOXcCdH06SgRJV5w6mlC6jkcSj9lb 5+lJzsJ/bLO+W9FM6Bgo3nfG/BA+Lvs53IQrXEpnvXfjzucZkfILelynJiC0afIBOFTQ Fs3g== X-Forwarded-Encrypted: i=1; AKwUvBwhJFNiSSTnFRN/9fSev7w5p0qwCkkYVA2IjJB7cdu+sBlT1NZzpXMA1kPkRaqLULxLab4amXauTbMR1iE=@vger.kernel.org X-Gm-Message-State: AFuF++k1Or91DGAAK4T19iOme041qXuFcVKb1bWDjXhaD9+KV+bTh1IS vQkCLw9tYiZhAC/vev/wQ7zx0UGtkCJGD4hVL8r2LhGyI4a5Ferzk+vRxLRVRIuYxY4d/Qq9B9w nm91oAQ== X-Received: from pgaz8.prod.google.com ([2002:a05:6a02:50e8:b0:cc7:caf5:50f3]) (user=wyihan job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a21:3987:b0:3dd:a00a:7ac9 with SMTP id adf61e73a8af0-3e0bd2ce276mr381873637.54.1790883537939; Thu, 01 Oct 2026 12:38:57 -0700 (PDT) Date: Thu, 01 Oct 2026 19:37:45 +0000 In-Reply-To: <20261001-tdx-selftests-v15-0-7c62a5d8a992@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20261001-tdx-selftests-v15-0-7c62a5d8a992@google.com> X-Developer-Key: i=wyihan@google.com; a=ed25519; pk=cRi0fKzS5BMxlHyHY2pJv3w/1zcgfYKr6EYGYppdMYc= X-Developer-Signature: v=1; a=ed25519-sha256; t=1790883521; l=4084; i=wyihan@google.com; s=20260319; h=from:subject:message-id; bh=B0/+AYwoNGMvhRTjH0hvziwoAGkXGZBATDrRe3FTczI=; b=XmUVuwsaLPQHE5JnV3C5LhZEiXXFAZAmrE8yvKo3mx/4aIirB+K9fhi9QYnUBWUyePemkGtoE jD6v7R/Wm9KACDs+wsCbUgCBidbgkppxfx37bYK7dbeJaVyokWiPfJA X-Mailer: b4 0.14.3 Message-ID: <20261001-tdx-selftests-v15-18-7c62a5d8a992@google.com> Subject: [PATCH v15 18/23] KVM: selftests: Add helpers to init TDX memory and finalize VM From: Lisa Wang To: Andrew Jones , Ackerley Tng , Binbin Wu , Chao Gao , Chenyi Qiang , Dave Hansen , Erdem Aktas , Ira Weiny , Isaku Yamahata , Kiryl Shutsemau , linux-kselftest@vger.kernel.org, Paolo Bonzini , "Pratik R. Sampat" , Reinette Chatre , Rick Edgecombe , Roger Wang , Ryan Afranji , Sagi Shahar , Sean Christopherson , Shuah Khan , Xiaoyao Li , Oliver Upton Cc: Jeremiah McReynolds , kvm@vger.kernel.org, linux-coco@lists.linux.dev, linux-kernel@vger.kernel.org, x86@kernel.org, Lisa Wang , Ira Weiny Content-Type: text/plain; charset="utf-8" From: Ackerley Tng TDX protected memory needs to be measured and encrypted before it can be used by the guest. Traverse the VM's memory regions and initialize all the protected ranges by calling KVM_TDX_INIT_MEM_REGION. Once all the memory is initialized, the VM can be finalized by calling KVM_TDX_FINALIZE_VM. Co-developed-by: Erdem Aktas Signed-off-by: Erdem Aktas Co-developed-by: Sagi Shahar Signed-off-by: Sagi Shahar Co-developed-by: Lisa Wang Signed-off-by: Lisa Wang Signed-off-by: Ackerley Tng Reviewed-by: Binbin Wu Reviewed-by: Ira Weiny --- .../selftests/kvm/include/x86/tdx/tdx_util.h | 2 + tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c | 62 ++++++++++++++++++++++ 2 files changed, 64 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 f36cddbd045c..dcfc62ffbaeb 100644 --- a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h +++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h @@ -73,4 +73,6 @@ void tdx_vm_load_common_boot_parameters(struct kvm_vm *vm); void tdx_vcpu_load_boot_parameters(struct kvm_vm *vm, struct kvm_vcpu *vcpu); void tdx_vcpu_set_entry_point(struct kvm_vcpu *vcpu, void *guest_code); +void tdx_vm_finalize(struct kvm_vm *vm); + #endif /* SELFTESTS_TDX_TDX_UTIL_H */ 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 5f10a7c1455d..b8e1f848cf54 100644 --- a/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c +++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx_util.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only +#include #include #include "processor.h" @@ -228,3 +229,64 @@ void tdx_init_vm(struct kvm_vm *vm) free(init_vm); } + +static void tdx_init_mem_region(struct kvm_vm *vm, void *source_pages, + u64 gpa, u64 size) +{ + u32 flags = KVM_TDX_MEASURE_MEMORY_REGION; + struct kvm_tdx_init_mem_region mem_region = { + .source_addr = (u64)source_pages, + .gpa = gpa, + .nr_pages = size / PAGE_SIZE, + }; + struct kvm_vcpu *vcpu; + + vcpu = list_first_entry_or_null(&vm->vcpus, struct kvm_vcpu, list); + + TEST_ASSERT(size && IS_ALIGNED(size, PAGE_SIZE), + "Cannot add partial pages to the guest memory.\n"); + TEST_ASSERT(IS_ALIGNED((u64)source_pages, PAGE_SIZE), + "Source memory buffer is not page aligned\n"); + tdx_vcpu_ioctl(vcpu, KVM_TDX_INIT_MEM_REGION, flags, &mem_region); +} + +static void tdx_load_private_memory(struct kvm_vm *vm) +{ + struct userspace_mem_region *region; + int ctr; + + hash_for_each(vm->regions.slot_hash, ctr, region, slot_node) { + const struct sparsebit *protected_pages = region->protected_phy_pages; + const gpa_t gpa_base = region->region.guest_phys_addr; + const u64 hva_base = region->region.userspace_addr; + const sparsebit_idx_t lowest_page_in_region = gpa_base >> vm->page_shift; + void *source_pages = NULL; + sparsebit_idx_t i, j; + + if (!sparsebit_any_set(protected_pages)) + continue; + + TEST_ASSERT(region->region.guest_memfd != -1, + "TD private memory must be backed by guest_memfd"); + + sparsebit_for_each_set_range(protected_pages, i, j) { + const u64 size_to_load = (j - i + 1) * vm->page_size; + const u64 offset = + (i - lowest_page_in_region) * vm->page_size; + const u64 hva = hva_base + offset; + const u64 gpa = gpa_base + offset; + + if (!kvm_has_gmem_attributes) + source_pages = (void *)hva; + + vm_mem_set_private(vm, gpa, size_to_load); + tdx_init_mem_region(vm, source_pages, gpa, size_to_load); + } + } +} + +void tdx_vm_finalize(struct kvm_vm *vm) +{ + tdx_load_private_memory(vm); + tdx_vm_ioctl(vm, KVM_TDX_FINALIZE_VM, 0, NULL); +} -- 2.56.0.rc1.315.gc6ed9934b7-goog