File tboot-Configure-IOMMU-before-executing-GETSEC-SENTER.patch of Package tboot.18210
From 4ab3384cd765def9a4ca00791341d47c35b8912a Mon Sep 17 00:00:00 2001
From: Lukasz Hawrylko <lukasz.hawrylko@intel.com>
Date: Mon, 21 Oct 2019 12:09:04 +0200
Subject: [PATCH] Configure IOMMU before executing GETSEC[SENTER]
SINIT required that following IOMMU features are disabled:
- DMA remapping (done in TBOOT)
- Queued Invalidation (done in SINIT)
- Interrupt Remapping (done in SINIT)
Signed-off-by: Lukasz Hawrylko <lukasz.hawrylko@intel.com>
---
tboot/Makefile | 2 +-
tboot/common/acpi.c | 77 +----------
tboot/common/tboot.c | 7 +-
tboot/common/vtd.c | 220 ++++++++++++++++++++++++++++++++
tboot/include/acpi.h | 3 +-
tboot/include/txt/config_regs.h | 27 ++--
tboot/include/vtd.h | 64 ++++++++++
tboot/txt/txt.c | 41 +++++-
tboot/txt/verify.c | 1 +
9 files changed, 355 insertions(+), 87 deletions(-)
create mode 100644 tboot/common/vtd.c
create mode 100644 tboot/include/vtd.h
Index: tboot-1.9.8/tboot/Makefile
===================================================================
--- tboot-1.9.8.orig/tboot/Makefile
+++ tboot-1.9.8/tboot/Makefile
@@ -13,7 +13,7 @@ TARGET := $(CURDIR)/tboot
# boot.o must be first
obj-y := common/boot.o
-obj-y += common/acpi.o common/cmdline.o common/com.o common/e820.o
+obj-y += common/acpi.o common/cmdline.o common/com.o common/e820.o common/vtd.o
obj-y += common/elf.o common/hash.o common/index.o common/integrity.o
obj-y += common/linux.o common/loader.o common/memcmp.o common/memcpy.o
obj-y += common/misc.o common/mutex.o common/paging.o common/pci_cfgreg.o
Index: tboot-1.9.8/tboot/common/acpi.c
===================================================================
--- tboot-1.9.8.orig/tboot/common/acpi.c
+++ tboot-1.9.8/tboot/common/acpi.c
@@ -53,8 +53,6 @@
#endif
static struct acpi_rsdp *rsdp;
-static struct acpi_table_header *g_dmar_table;
-static __data bool g_hide_dmar;
static void dump_gas(const char *reg_name,
const tboot_acpi_generic_address_t *reg)
@@ -216,76 +214,6 @@ static struct acpi_table_header *find_ta
return NULL;
}
-static struct acpi_dmar *get_vtd_dmar_table(void)
-{
- return (struct acpi_dmar *)find_table(DMAR_SIG);
-}
-
-bool vtd_bios_enabled(void)
-{
- return find_table(DMAR_SIG) != NULL;
-}
-
-bool save_vtd_dmar_table(void)
-{
- /* find DMAR table and save it */
- g_dmar_table = (struct acpi_table_header *)get_vtd_dmar_table();
-
- printk(TBOOT_DETA"DMAR table @ %p saved.\n", g_dmar_table);
- return true;
-}
-
-bool restore_vtd_dmar_table(void)
-{
- struct acpi_table_header *hdr;
-
- g_hide_dmar = false;
-
- /* find DMAR table first */
- hdr = (struct acpi_table_header *)get_vtd_dmar_table();
- if ( hdr != NULL ) {
- printk(TBOOT_DETA"DMAR table @ %p is still there, skip restore step.\n", hdr);
- return true;
- }
-
- /* check saved DMAR table */
- if ( g_dmar_table == NULL ) {
- printk(TBOOT_ERR"No DMAR table saved, abort restore step.\n");
- return false;
- }
-
- /* restore DMAR if needed */
- memcpy(g_dmar_table->signature, DMAR_SIG, sizeof(g_dmar_table->signature));
-
- /* need to hide DMAR table while resume from S3 */
- g_hide_dmar = true;
- printk(TBOOT_DETA"DMAR table @ %p restored.\n", hdr);
- return true;
-}
-
-bool remove_vtd_dmar_table(void)
-{
- struct acpi_table_header *hdr;
-
- /* check whether it is needed */
- if ( !g_hide_dmar ) {
- printk(TBOOT_DETA"No need to hide DMAR table.\n");
- return true;
- }
-
- /* find DMAR table */
- hdr = (struct acpi_table_header *)get_vtd_dmar_table();
- if ( hdr == NULL ) {
- printk(TBOOT_DETA"No DMAR table, skip remove step.\n");
- return true;
- }
-
- /* remove DMAR table */
- hdr->signature[0] = '\0';
- printk(TBOOT_DETA"DMAR table @ %p removed.\n", hdr);
- return true;
-}
-
static struct acpi_madt *get_apic_table(void)
{
return (struct acpi_madt *)find_table(MADT_SIG);
@@ -333,6 +261,11 @@ struct acpi_mcfg *get_acpi_mcfg_table(vo
return (struct acpi_mcfg *)find_table(MCFG_SIG);
}
+struct acpi_dmar *get_vtd_dmar_table(void)
+{
+ return (struct acpi_dmar *)find_table(DMAR_SIG);
+}
+
static bool write_to_reg(const tboot_acpi_generic_address_t *reg,
uint32_t val)
{
Index: tboot-1.9.8/tboot/common/tboot.c
===================================================================
--- tboot-1.9.8.orig/tboot/common/tboot.c
+++ tboot-1.9.8/tboot/common/tboot.c
@@ -70,6 +70,7 @@
#include <integrity.h>
#include <cmdline.h>
#include <tpm_20.h>
+#include <vtd.h>
extern void _prot_to_real(uint32_t dist_addr);
extern bool set_policy(void);
@@ -170,7 +171,7 @@ static void post_launch(void)
/* backup DMAR table */
if ( get_tboot_save_vtd() )
- save_vtd_dmar_table();
+ vtd_save_dmar_table();
if ( s3_flag )
s3_launch();
@@ -475,7 +476,7 @@ void s3_launch(void)
/* remove DMAR table if necessary */
if ( get_tboot_save_vtd() )
- remove_vtd_dmar_table();
+ vtd_remove_dmar_table();
if ( !is_launched() )
apply_policy(TB_ERR_S3_INTEGRITY);
@@ -594,7 +595,7 @@ void shutdown(void)
if ( _tboot_shared.shutdown_type == TB_SHUTDOWN_S3 ) {
/* restore DMAR table if needed */
if ( get_tboot_save_vtd() )
- restore_vtd_dmar_table();
+ vtd_restore_dmar_table();
if ( tpm->major == TPM20_VER_MAJOR ) {
tpm_fp->context_flush(tpm, tpm->cur_loc, handle2048);
tpm_fp->context_load(tpm, tpm->cur_loc, &tpm2_context_saved, &handle2048);
Index: tboot-1.9.8/tboot/common/vtd.c
===================================================================
--- /dev/null
+++ tboot-1.9.8/tboot/common/vtd.c
@@ -0,0 +1,220 @@
+/*
+ * vtd.c: VT-d support functions
+ *
+ * Copyright (c) 2019, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <types.h>
+#include <stdbool.h>
+#include <compiler.h>
+#include <processor.h>
+#include <printk.h>
+#include <tboot.h>
+#include <loader.h>
+#include <string.h>
+#include <acpi.h>
+#include <txt/config_regs.h>
+
+#include <vtd.h>
+
+static struct acpi_table_header *g_dmar_table;
+static __data bool g_hide_dmar;
+
+bool vtd_bios_enabled(void)
+{
+ return get_vtd_dmar_table() != NULL;
+}
+
+bool vtd_save_dmar_table(void)
+{
+ /* find DMAR table and save it */
+ g_dmar_table = (struct acpi_table_header *)get_vtd_dmar_table();
+
+ printk(TBOOT_DETA"DMAR table @ %p saved.\n", g_dmar_table);
+ return true;
+}
+
+bool vtd_restore_dmar_table(void)
+{
+ struct acpi_table_header *hdr;
+
+ g_hide_dmar = false;
+
+ /* find DMAR table first */
+ hdr = (struct acpi_table_header *)get_vtd_dmar_table();
+ if ( hdr != NULL ) {
+ printk(TBOOT_DETA"DMAR table @ %p is still there, skip restore step.\n", hdr);
+ return true;
+ }
+
+ /* check saved DMAR table */
+ if ( g_dmar_table == NULL ) {
+ printk(TBOOT_ERR"No DMAR table saved, abort restore step.\n");
+ return false;
+ }
+
+ /* restore DMAR if needed */
+ memcpy(g_dmar_table->signature, DMAR_SIG, sizeof(g_dmar_table->signature));
+
+ /* need to hide DMAR table while resume from S3 */
+ g_hide_dmar = true;
+ printk(TBOOT_DETA"DMAR table @ %p restored.\n", hdr);
+ return true;
+}
+
+bool vtd_remove_dmar_table(void)
+{
+ struct acpi_table_header *hdr;
+
+ /* check whether it is needed */
+ if ( !g_hide_dmar ) {
+ printk(TBOOT_DETA"No need to hide DMAR table.\n");
+ return true;
+ }
+
+ /* find DMAR table */
+ hdr = (struct acpi_table_header *)get_vtd_dmar_table();
+ if ( hdr == NULL ) {
+ printk(TBOOT_DETA"No DMAR table, skip remove step.\n");
+ return true;
+ }
+
+ /* remove DMAR table */
+ hdr->signature[0] = '\0';
+ printk(TBOOT_DETA"DMAR table @ %p removed.\n", hdr);
+ return true;
+}
+
+struct dmar_remapping *vtd_get_dmar_remap(uint32_t *remap_length)
+{
+ struct acpi_dmar *dmar = get_vtd_dmar_table();
+
+ if (dmar == NULL || remap_length == NULL) {
+ return NULL;
+ }
+
+ *remap_length = dmar->hdr.length - sizeof(*dmar);
+ return (struct dmar_remapping*)(dmar->table_offsets);
+}
+
+bool vtd_disable_dma_remap(struct dmar_remapping *rs)
+{
+ if (rs->type != DMAR_REMAPPING_DRHD) {
+ return false;
+ }
+
+ uint32_t timeout;
+ uint32_t gsts = read_reg32(rs->register_base_address, VTD_GSTS_OFFSET) & 0x96FFFFFF;
+
+ if (gsts & TE_STAT) {
+ /* Clear TE_STAT bit and write back to GCMD */
+ gsts &= ~TE_STAT;
+ write_reg32(rs->register_base_address, VTD_GCMD_OFFSET, gsts);
+
+ /* Wait until GSTS indicates that operation is completed */
+ timeout = VTD_OPERATION_TIMEOUT;
+ while (read_reg32(rs->register_base_address, VTD_GSTS_OFFSET) & TE_STAT) {
+ cpu_relax();
+ if (--timeout == 0) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool vtd_disable_qie(struct dmar_remapping *rs)
+{
+ if (rs->type != DMAR_REMAPPING_DRHD) {
+ return false;
+ }
+
+ uint32_t timeout;
+ uint32_t gsts = read_reg32(rs->register_base_address, VTD_GSTS_OFFSET) & 0x96FFFFFF;
+
+ if (gsts & QIE_STAT) {
+ /* Wait for HW to complete pending invalidation requests */
+ timeout = VTD_OPERATION_TIMEOUT;
+ while (read_reg64(rs->register_base_address, VTD_IQT_OFFSET) !=
+ read_reg64(rs->register_base_address, VTD_IQH_OFFSET)) {
+ cpu_relax();
+ if (--timeout == 0) {
+ return false;
+ }
+ }
+
+ /* Clear QIE_STAT bit and write back to GCMD */
+ gsts &= ~QIE_STAT;
+ write_reg32(rs->register_base_address, VTD_GCMD_OFFSET, gsts);
+
+ /* Wait until GSTS indicates that operation is completed */
+ timeout = VTD_OPERATION_TIMEOUT;
+ while (read_reg32(rs->register_base_address, VTD_GSTS_OFFSET) & QIE_STAT) {
+ cpu_relax();
+ if (--timeout == 0) {
+ return false;
+ }
+ }
+
+ /* Set IQT to 0 (IQH was set by HW) */
+ write_reg64(rs->register_base_address, VTD_IQT_OFFSET, 0);
+ }
+
+ return true;
+}
+
+bool vtd_disable_ire(struct dmar_remapping *rs)
+{
+ if (rs->type != DMAR_REMAPPING_DRHD) {
+ return false;
+ }
+
+ uint32_t timeout;
+ uint32_t gsts = read_reg32(rs->register_base_address, VTD_GSTS_OFFSET) & 0x96FFFFFF;
+
+ if (gsts & IRE_STAT) {
+ /* Clear IRE_STAT bit and write back to GCMD */
+ gsts &= ~IRE_STAT;
+ write_reg32(rs->register_base_address, VTD_GCMD_OFFSET, gsts);
+
+ /* Wait until GSTS indicates that operation is completed */
+ timeout = VTD_OPERATION_TIMEOUT;
+ while (read_reg32(rs->register_base_address, VTD_GSTS_OFFSET) & IRE_STAT) {
+ cpu_relax();
+ if (--timeout == 0) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
\ No newline at end of file
Index: tboot-1.9.8/tboot/include/acpi.h
===================================================================
--- tboot-1.9.8.orig/tboot/include/acpi.h
+++ tboot-1.9.8/tboot/include/acpi.h
@@ -356,7 +356,7 @@ struct dmar_remapping {
u_int8_t reserved;
u_int16_t segment_number;
- u_int8_t register_base_address[8];
+ u_int64_t register_base_address;
struct device_scope device_scope_entry[1]; /* Device Scope starts here */
} __packed;
@@ -498,6 +498,7 @@ extern bool remove_vtd_dmar_table(void);
extern struct acpi_table_ioapic *get_acpi_ioapic_table(void);
extern struct acpi_mcfg *get_acpi_mcfg_table(void);
+extern struct acpi_dmar *get_vtd_dmar_table(void);
extern void disable_smis(void);
extern bool machine_sleep(const tboot_acpi_sleep_info_t *);
Index: tboot-1.9.8/tboot/include/txt/config_regs.h
===================================================================
--- tboot-1.9.8.orig/tboot/include/txt/config_regs.h
+++ tboot-1.9.8/tboot/include/txt/config_regs.h
@@ -190,39 +190,48 @@ typedef struct {
* fns to read/write TXT config regs
*/
-#ifndef IS_INCLUDED
-static inline uint64_t read_config_reg(uint32_t config_regs_base, uint32_t reg)
+static inline uint64_t read_reg64(uint32_t config_regs_base, uint32_t reg)
{
/* these are MMIO so make sure compiler doesn't optimize */
return *(volatile uint64_t *)(unsigned long)(config_regs_base + reg);
}
-#endif
-static inline void write_config_reg(uint32_t config_regs_base, uint32_t reg,
- uint64_t val)
+static inline uint32_t read_reg32(uint32_t config_regs_base, uint32_t reg)
+{
+ /* these are MMIO so make sure compiler doesn't optimize */
+ return *(volatile uint32_t *)(unsigned long)(config_regs_base + reg);
+}
+
+static inline void write_reg64(uint32_t config_regs_base, uint32_t reg, uint64_t val)
{
/* these are MMIO so make sure compiler doesn't optimize */
*(volatile uint64_t *)(unsigned long)(config_regs_base + reg) = val;
}
+static inline void write_reg32(uint32_t config_regs_base, uint32_t reg, uint32_t val)
+{
+ /* these are MMIO so make sure compiler doesn't optimize */
+ *(volatile uint32_t *)(unsigned long)(config_regs_base + reg) = val;
+}
+
static inline uint64_t read_pub_config_reg(uint32_t reg)
{
- return read_config_reg(TXT_PUB_CONFIG_REGS_BASE, reg);
+ return read_reg64(TXT_PUB_CONFIG_REGS_BASE, reg);
}
static inline void write_pub_config_reg(uint32_t reg, uint64_t val)
{
- write_config_reg(TXT_PUB_CONFIG_REGS_BASE, reg, val);
+ write_reg64(TXT_PUB_CONFIG_REGS_BASE, reg, val);
}
static inline uint64_t read_priv_config_reg(uint32_t reg)
{
- return read_config_reg(TXT_PRIV_CONFIG_REGS_BASE, reg);
+ return read_reg64(TXT_PRIV_CONFIG_REGS_BASE, reg);
}
static inline void write_priv_config_reg(uint32_t reg, uint64_t val)
{
- write_config_reg(TXT_PRIV_CONFIG_REGS_BASE, reg, val);
+ write_reg64(TXT_PRIV_CONFIG_REGS_BASE, reg, val);
}
#endif /* __TXT_CONFIG_REGS_H__ */
Index: tboot-1.9.8/tboot/include/vtd.h
===================================================================
--- /dev/null
+++ tboot-1.9.8/tboot/include/vtd.h
@@ -0,0 +1,64 @@
+/*
+ * vtd.c: VT-d support functions
+ *
+ * Copyright (c) 2019, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of the Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __VTD_H__
+#define __VTD_H__
+
+#define VTD_OPERATION_TIMEOUT 0x10000000
+
+#define VTD_GCMD_OFFSET 0x18
+ #define TE_EN (1 << 31)
+ #define QIE_EN (1 << 26)
+ #define IRE_EN (1 << 25)
+
+#define VTD_GSTS_OFFSET 0x1C
+ #define TE_STAT (1 << 31)
+ #define QIE_STAT (1 << 26)
+ #define IRE_STAT (1 << 25)
+
+#define VTD_IQH_OFFSET 0x80
+#define VTD_IQT_OFFSET 0x88
+
+bool vtd_bios_enabled(void);
+bool vtd_save_dmar_table(void);
+bool vtd_restore_dmar_table(void);
+bool vtd_remove_dmar_table(void);
+
+struct dmar_remapping *vtd_get_dmar_remap(uint32_t *remap_length);
+bool vtd_disable_dma_remap(struct dmar_remapping *rs);
+bool vtd_disable_qie(struct dmar_remapping *rs);
+bool vtd_disable_ire(struct dmar_remapping *rs);
+
+#endif
\ No newline at end of file
Index: tboot-1.9.8/tboot/txt/txt.c
===================================================================
--- tboot-1.9.8.orig/tboot/txt/txt.c
+++ tboot-1.9.8/tboot/txt/txt.c
@@ -56,6 +56,7 @@
#include <hash.h>
#include <cmdline.h>
#include <acpi.h>
+#include <vtd.h>
#include <txt/txt.h>
#include <txt/config_regs.h>
#include <txt/mtrrs.h>
@@ -527,6 +528,42 @@ bool evtlog_append(uint8_t pcr, hash_lis
__data uint32_t g_using_da = 0;
__data acm_hdr_t *g_sinit = 0;
+static void configure_vtd(void)
+{
+ uint32_t remap_length;
+ struct dmar_remapping *dmar_remap = vtd_get_dmar_remap(&remap_length);
+
+ if (dmar_remap == NULL) {
+ printk("cannot get DMAR remapping strucutues, skiping configuration\n");
+ return;
+ } else {
+ printk("configuring DMAR remapping\n");
+ }
+
+ struct dmar_remapping *iter, *next;
+ struct dmar_remapping *end = ((void *)dmar_remap) + remap_length;
+
+ for (iter = dmar_remap; iter < end; iter = next) {
+ next = (void *)iter + iter->length;
+ if (iter->length == 0) {
+ /* Avoid looping forever on bad ACPI tables */
+ printk(" invalid 0-length structure\n");
+ break;
+ } else if (next > end) {
+ /* Avoid passing table end */
+ printk(" record passes table end\n");
+ break;
+ }
+
+ if (iter->type == DMAR_REMAPPING_DRHD) {
+ if (!vtd_disable_dma_remap(iter)) {
+ printk(" vtd_disable_dma_remap failed!\n");
+ }
+ }
+ }
+
+}
+
/*
* sets up TXT heap
*/
@@ -811,6 +848,8 @@ tb_error_t txt_launch_environment(loader
if ( mle_ptab_base == NULL )
return TB_ERR_FATAL;
+ configure_vtd();
+
/* initialize TXT heap */
txt_heap = init_txt_heap(mle_ptab_base, g_sinit, lctx);
if ( txt_heap == NULL )
@@ -867,7 +906,7 @@ bool txt_s3_launch_environment(void)
return false;
}
/* initialize event log in os_sinit_data, so that events will not */
- /* repeat when s3 */
+ /* repeat when s3 */
if ( log_type == EVTLOG_TPM12 && g_elog ) {
g_elog = (event_log_container_t *)init_event_log();
} else if ( log_type == EVTLOG_TPM2_TCG && g_elog_2_1) {
Index: tboot-1.9.8/tboot/txt/verify.c
===================================================================
--- tboot-1.9.8.orig/tboot/txt/verify.c
+++ tboot-1.9.8/tboot/txt/verify.c
@@ -53,6 +53,7 @@
#include <hash.h>
#include <integrity.h>
#include <cmdline.h>
+#include <vtd.h>
#include <txt/txt.h>
#include <txt/smx.h>
#include <txt/mtrrs.h>