On Thu, Mar 17, 2022 at 09:58:55PM +0800, Xiaoyao Li <xiaoyao.li@xxxxxxxxx> wrote: > diff --git a/hw/i386/tdvf.c b/hw/i386/tdvf.c > new file mode 100644 > index 000000000000..02da1d2c12dd > --- /dev/null > +++ b/hw/i386/tdvf.c > @@ -0,0 +1,196 @@ > +/* > + * SPDX-License-Identifier: GPL-2.0-or-later > + > + * Copyright (c) 2020 Intel Corporation > + * Author: Isaku Yamahata <isaku.yamahata at gmail.com> > + * <isaku.yamahata at intel.com> > + * > + * 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 <http://www.gnu.org/licenses/>. > + */ > + > +#include "qemu/osdep.h" > +#include "hw/i386/pc.h" > +#include "hw/i386/tdvf.h" > +#include "sysemu/kvm.h" > + > +#define TDX_METADATA_GUID "e47a6535-984a-4798-865e-4685a7bf8ec2" > +#define TDX_METADATA_VERSION 1 > +#define TDVF_SIGNATURE_LE32 0x46564454 /* TDVF as little endian */ _LE32 doesn't make sense. qemu doesn't provide macro version for byteswap. Let's convert at the usage point. > + > +typedef struct { > + uint32_t DataOffset; > + uint32_t RawDataSize; > + uint64_t MemoryAddress; > + uint64_t MemoryDataSize; > + uint32_t Type; > + uint32_t Attributes; > +} TdvfSectionEntry; > + > +typedef struct { > + uint32_t Signature; > + uint32_t Length; > + uint32_t Version; > + uint32_t NumberOfSectionEntries; > + TdvfSectionEntry SectionEntries[]; > +} TdvfMetadata; > + > +struct tdx_metadata_offset { > + uint32_t offset; > +}; > + > +static TdvfMetadata *tdvf_get_metadata(void *flash_ptr, int size) > +{ > + TdvfMetadata *metadata; > + uint32_t offset = 0; > + uint8_t *data; > + > + if ((uint32_t) size != size) { > + return NULL; > + } > + > + if (pc_system_ovmf_table_find(TDX_METADATA_GUID, &data, NULL)) { > + offset = size - le32_to_cpu(((struct tdx_metadata_offset *)data)->offset); > + > + if (offset + sizeof(*metadata) > size) { > + return NULL; > + } > + } else { > + error_report("Cannot find TDX_METADATA_GUID\n"); > + return NULL; > + } > + > + metadata = flash_ptr + offset; > + > + /* Finally, verify the signature to determine if this is a TDVF image. */ > + if (metadata->Signature != TDVF_SIGNATURE_LE32) { metadata->Signature = le32_to_cpu(metadata->Signature); metadata->Signature != TDVF_SIGNATURE for consistency. -- Isaku Yamahata <isaku.yamahata@xxxxxxxxx>