From nobody Tue Feb 10 10:55:06 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1659428895; cv=none; d=zohomail.com; s=zohoarc; b=LHpcrYcyJSZO4Xyc+dB+mhkm4SJmM8mJ+4XjVq39E/c6j+05XwbZXddTSKLkwCVsvMVkJSi2ir9GayYglSGNMR7UzRmtsRC9ZhxfypOC+063z6l2idPQpCvwlaQsuIdyof+E31jzUXHZNTvBu8eVB7qnQ5jv/1MCTd/Nd6NbSFg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1659428895; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=eRJgI2X2IMgdhxmKaUKYVxlb7j8Ip6z9GjZ2XeQnKVI=; b=Z16O0+dn+0nK6KPv+4ZGSmafw4qq4yBVGUxTiF9LH3+GP2MtXLaUkOhA/WaNtrwysOlkB4FCwL3B3Rg4EdGXPSKBdflp2Q+W5PzfSsNL9LAozxXx48yxhpFzDTqJk1V6YeVqWqQe/nYCcAOO0vDAT3TQC9V8wlnhhDTMs8SyQZA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1659428895364871.1377264161249; Tue, 2 Aug 2022 01:28:15 -0700 (PDT) Received: from localhost ([::1]:55852 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1oInGA-0004z1-A7 for importer@patchew.org; Tue, 02 Aug 2022 04:28:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58256) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oImf6-0005Ip-5n for qemu-devel@nongnu.org; Tue, 02 Aug 2022 03:49:56 -0400 Received: from mga04.intel.com ([192.55.52.120]:60003) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1oImf3-0006ST-9t for qemu-devel@nongnu.org; Tue, 02 Aug 2022 03:49:55 -0400 Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2022 00:49:52 -0700 Received: from lxy-dell.sh.intel.com ([10.239.48.38]) by orsmga008.jf.intel.com with ESMTP; 02 Aug 2022 00:49:48 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1659426593; x=1690962593; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NTrc2v5Eqp8DfcJfnKWddbAQ27gBG9RwLVFSBkFSZAQ=; b=IpBXQ4aawqbyqA/HfTf8uptaMtob6dlCuty8KGX93YdIJ+xprtbPSTAC 56db9g3/VhC7FFvwbRKf8s0jVTpg9aiETDLkXW0d5SmwzMfEyYsTbeifH kSZOLUdb10p7P+1KyoFiZW3Ci2jWTWGsrQXUnJoSsXW+UoocWHKhbBHQv 8h5K/HFJYKhgTjSLewD+5NIEV3F6ZXfxMhPry5bcsHq7mowcFLVhb4Ik5 4qV4i4LhTTuMWmNl70K4m0Et2EjVAZINgj0FEv6EJMb+8S+lGiigZHUwx +EqtVJspH80bwjplu7teYKLbato4w3LUNYUWOwuPlO5CrncTOx8yE2uT4 A==; X-IronPort-AV: E=McAfee;i="6400,9594,10426"; a="288105717" X-IronPort-AV: E=Sophos;i="5.93,210,1654585200"; d="scan'208";a="288105717" X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.93,210,1654585200"; d="scan'208";a="630604258" From: Xiaoyao Li To: Paolo Bonzini , Isaku Yamahata , Gerd Hoffmann , =?UTF-8?q?Daniel=20P=20=2E=20Berrang=C3=A9?= , =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Richard Henderson , "Michael S . Tsirkin" , Marcel Apfelbaum , Cornelia Huck , Marcelo Tosatti , Laszlo Ersek , Eric Blake Cc: Connor Kuehl , erdemaktas@google.com, kvm@vger.kernel.org, qemu-devel@nongnu.org, seanjc@google.com, xiaoyao.li@intel.com Subject: [PATCH v1 27/40] i386/tdx: Setup the TD HOB list Date: Tue, 2 Aug 2022 15:47:37 +0800 Message-Id: <20220802074750.2581308-28-xiaoyao.li@intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220802074750.2581308-1-xiaoyao.li@intel.com> References: <20220802074750.2581308-1-xiaoyao.li@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.55.52.120; envelope-from=xiaoyao.li@intel.com; helo=mga04.intel.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, HK_RANDOM_ENVFROM=0.998, HK_RANDOM_FROM=0.998, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1659428896380100001 Content-Type: text/plain; charset="utf-8" The TD HOB list is used to pass the information from VMM to TDVF. The TD HOB must include PHIT HOB and Resource Descriptor HOB. More details can be found in TDVF specification and PI specification. Build the TD HOB in TDX's machine_init_done callback. Co-developed-by: Isaku Yamahata Signed-off-by: Isaku Yamahata Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson Signed-off-by: Xiaoyao Li Acked-by: Gerd Hoffmann --- Changes from RFC v4: - drop the code of adding mmio resources since OVMF prepares all the MMIO hob itself. --- hw/i386/meson.build | 2 +- hw/i386/tdvf-hob.c | 146 ++++++++++++++++++++++++++++++++++++++++++ hw/i386/tdvf-hob.h | 24 +++++++ target/i386/kvm/tdx.c | 16 +++++ 4 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 hw/i386/tdvf-hob.c create mode 100644 hw/i386/tdvf-hob.h diff --git a/hw/i386/meson.build b/hw/i386/meson.build index 97f3b50503b0..b59e0d35bba3 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -28,7 +28,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files( 'port92.c')) i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'), if_false: files('pc_sysfw_ovmf-stu= bs.c')) -i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c')) +i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c', 'tdvf-hob.c')) =20 subdir('kvm') subdir('xen') diff --git a/hw/i386/tdvf-hob.c b/hw/i386/tdvf-hob.c new file mode 100644 index 000000000000..bdf3b4823340 --- /dev/null +++ b/hw/i386/tdvf-hob.c @@ -0,0 +1,146 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + + * Copyright (c) 2020 Intel Corporation + * Author: Isaku Yamahata + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "e820_memory_layout.h" +#include "hw/i386/pc.h" +#include "hw/i386/x86.h" +#include "hw/pci/pcie_host.h" +#include "sysemu/kvm.h" +#include "standard-headers/uefi/uefi.h" +#include "tdvf-hob.h" + +typedef struct TdvfHob { + hwaddr hob_addr; + void *ptr; + int size; + + /* working area */ + void *current; + void *end; +} TdvfHob; + +static uint64_t tdvf_current_guest_addr(const TdvfHob *hob) +{ + return hob->hob_addr + (hob->current - hob->ptr); +} + +static void tdvf_align(TdvfHob *hob, size_t align) +{ + hob->current =3D QEMU_ALIGN_PTR_UP(hob->current, align); +} + +static void *tdvf_get_area(TdvfHob *hob, uint64_t size) +{ + void *ret; + + if (hob->current + size > hob->end) { + error_report("TD_HOB overrun, size =3D 0x%" PRIx64, size); + exit(1); + } + + ret =3D hob->current; + hob->current +=3D size; + tdvf_align(hob, 8); + return ret; +} + +static void tdvf_hob_add_memory_resources(TdxGuest *tdx, TdvfHob *hob) +{ + EFI_HOB_RESOURCE_DESCRIPTOR *region; + EFI_RESOURCE_ATTRIBUTE_TYPE attr; + EFI_RESOURCE_TYPE resource_type; + + TdxRamEntry *e; + int i; + + for (i =3D 0; i < tdx->nr_ram_entries; i++) { + e =3D &tdx->ram_entries[i]; + + if (e->type =3D=3D TDX_RAM_UNACCEPTED) { + resource_type =3D EFI_RESOURCE_MEMORY_UNACCEPTED; + attr =3D EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED; + } else if (e->type =3D=3D TDX_RAM_ADDED){ + resource_type =3D EFI_RESOURCE_SYSTEM_MEMORY; + attr =3D EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE; + } else { + error_report("unknown TDX_RAM_ENTRY type %d", e->type); + exit(1); + } + + region =3D tdvf_get_area(hob, sizeof(*region)); + *region =3D (EFI_HOB_RESOURCE_DESCRIPTOR) { + .Header =3D { + .HobType =3D EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, + .HobLength =3D cpu_to_le16(sizeof(*region)), + .Reserved =3D cpu_to_le32(0), + }, + .Owner =3D EFI_HOB_OWNER_ZERO, + .ResourceType =3D cpu_to_le32(resource_type), + .ResourceAttribute =3D cpu_to_le32(attr), + .PhysicalStart =3D cpu_to_le64(e->address), + .ResourceLength =3D cpu_to_le64(e->length), + }; + } +} + +void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob) +{ + TdvfHob hob =3D { + .hob_addr =3D td_hob->address, + .size =3D td_hob->size, + .ptr =3D td_hob->mem_ptr, + + .current =3D td_hob->mem_ptr, + .end =3D td_hob->mem_ptr + td_hob->size, + }; + + EFI_HOB_GENERIC_HEADER *last_hob; + EFI_HOB_HANDOFF_INFO_TABLE *hit; + + /* Note, Efi{Free}Memory{Bottom,Top} are ignored, leave 'em zeroed. */ + hit =3D tdvf_get_area(&hob, sizeof(*hit)); + *hit =3D (EFI_HOB_HANDOFF_INFO_TABLE) { + .Header =3D { + .HobType =3D EFI_HOB_TYPE_HANDOFF, + .HobLength =3D cpu_to_le16(sizeof(*hit)), + .Reserved =3D cpu_to_le32(0), + }, + .Version =3D cpu_to_le32(EFI_HOB_HANDOFF_TABLE_VERSION), + .BootMode =3D cpu_to_le32(0), + .EfiMemoryTop =3D cpu_to_le64(0), + .EfiMemoryBottom =3D cpu_to_le64(0), + .EfiFreeMemoryTop =3D cpu_to_le64(0), + .EfiFreeMemoryBottom =3D cpu_to_le64(0), + .EfiEndOfHobList =3D cpu_to_le64(0), /* initialized later */ + }; + + tdvf_hob_add_memory_resources(tdx, &hob); + + last_hob =3D tdvf_get_area(&hob, sizeof(*last_hob)); + *last_hob =3D (EFI_HOB_GENERIC_HEADER) { + .HobType =3D EFI_HOB_TYPE_END_OF_HOB_LIST, + .HobLength =3D cpu_to_le16(sizeof(*last_hob)), + .Reserved =3D cpu_to_le32(0), + }; + hit->EfiEndOfHobList =3D tdvf_current_guest_addr(&hob); +} diff --git a/hw/i386/tdvf-hob.h b/hw/i386/tdvf-hob.h new file mode 100644 index 000000000000..1b737e946a8d --- /dev/null +++ b/hw/i386/tdvf-hob.h @@ -0,0 +1,24 @@ +#ifndef HW_I386_TD_HOB_H +#define HW_I386_TD_HOB_H + +#include "hw/i386/tdvf.h" +#include "target/i386/kvm/tdx.h" + +void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob); + +#define EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE \ + (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED) + +#define EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED \ + (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED) + +#define EFI_RESOURCE_ATTRIBUTE_TDVF_MMIO \ + (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE) + +#endif diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c index 59cff141b4f3..944f2f5b6921 100644 --- a/target/i386/kvm/tdx.c +++ b/target/i386/kvm/tdx.c @@ -22,6 +22,7 @@ #include "hw/i386/e820_memory_layout.h" #include "hw/i386/x86.h" #include "hw/i386/tdvf.h" +#include "hw/i386/tdvf-hob.h" #include "kvm_i386.h" #include "tdx.h" #include "../cpu-internal.h" @@ -454,6 +455,19 @@ static void update_tdx_cpuid_lookup_by_tdx_caps(void) (tdx_caps->xfam_fixed1 & CPUID_XSTATE_XSS_MASK) >> 32; } =20 +static TdxFirmwareEntry *tdx_get_hob_entry(TdxGuest *tdx) +{ + TdxFirmwareEntry *entry; + + for_each_tdx_fw_entry(&tdx->tdvf, entry) { + if (entry->type =3D=3D TDVF_SECTION_TYPE_TD_HOB) { + return entry; + } + } + error_report("TDVF metadata doesn't specify TD_HOB location."); + exit(1); +} + static void tdx_add_ram_entry(uint64_t address, uint64_t length, uint32_t = type) { uint32_t nr_entries =3D tdx_guest->nr_ram_entries; @@ -584,6 +598,8 @@ static void tdx_finalize_vm(Notifier *notifier, void *u= nused) =20 qsort(tdx_guest->ram_entries, tdx_guest->nr_ram_entries, sizeof(TdxRamEntry), &tdx_ram_entry_compare); + + tdvf_hob_create(tdx_guest, tdx_get_hob_entry(tdx_guest)); } =20 static Notifier tdx_machine_done_notify =3D { --=20 2.27.0