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>
