linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] intel_txt: fix the build errors of intel_txt patch on non-X86 platforms (resend)
@ 2009-09-01  8:52 Shane Wang
  2009-09-27  9:07 ` [PATCH] intel_txt: add s3 userspace memory integrity verification Shane Wang
  0 siblings, 1 reply; 32+ messages in thread
From: Shane Wang @ 2009-09-01  8:52 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org
  Cc: Ingo Molnar, H. Peter Anvin, Cihula, Joseph,
	arjan@linux.intel.com, andi@firstfloor.org, chrisw@sous-sol.org,
	jmorris@namei.org, jbeulich@novell.com, peterm@redhat.com,
	shane.wang

[-- Attachment #1: Type: text/plain, Size: 17874 bytes --]

Move tboot.h from asm to linux to fix the build errors of intel_txt patch on 
non-X86 platforms. Remove the tboot code from generic code init/main.c and 
kernel/cpu.c.

---
  arch/x86/Kconfig              |    4
  arch/x86/include/asm/tboot.h  |  197 --------------------------------
  arch/x86/kernel/reboot.c      |    3
  arch/x86/kernel/setup.c       |    3
  arch/x86/kernel/smpboot.c     |    2
  arch/x86/kernel/tboot.c       |   58 +++++++--
  drivers/acpi/acpica/hwsleep.c |    2
  drivers/pci/dmar.c            |    2
  drivers/pci/intel-iommu.c     |    2
  include/linux/tboot.h         |  162 ++++++++++++++++++++++++++
  init/main.c                   |    3
  kernel/cpu.c                  |    6
  security/Kconfig              |    2
  13 files changed, 221 insertions(+), 225 deletions(-)


Signed-off-by: Shane Wang <shane.wang@intel.com>

diff -r c6f74b152a32 arch/x86/Kconfig
--- a/arch/x86/Kconfig	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/Kconfig	Tue Sep 01 07:28:21 2009 -0700
@@ -179,6 +179,10 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING

  config ARCH_SUPPORTS_DEBUG_PAGEALLOC
  	def_bool y
+
+config HAVE_INTEL_TXT
+	def_bool y
+	depends on EXPERIMENTAL && DMAR && ACPI

  # Use the generic interrupt handling code in kernel/irq/:
  config GENERIC_HARDIRQS
diff -r c6f74b152a32 arch/x86/include/asm/tboot.h
--- a/arch/x86/include/asm/tboot.h	Tue Sep 01 07:24:42 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * tboot.h: shared data structure with tboot and kernel and functions
- *          used by kernel for runtime support of Intel(R) Trusted
- *          Execution Technology
- *
- * Copyright (c) 2006-2009, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _ASM_TBOOT_H
-#define _ASM_TBOOT_H
-
-#include <acpi/acpi.h>
-
-/* these must have the values from 0-5 in this order */
-enum {
-	TB_SHUTDOWN_REBOOT = 0,
-	TB_SHUTDOWN_S5,
-	TB_SHUTDOWN_S4,
-	TB_SHUTDOWN_S3,
-	TB_SHUTDOWN_HALT,
-	TB_SHUTDOWN_WFS
-};
-
-#ifdef CONFIG_INTEL_TXT
-
-/* used to communicate between tboot and the launched kernel */
-
-#define TB_KEY_SIZE             64   /* 512 bits */
-
-#define MAX_TB_MAC_REGIONS      32
-
-struct tboot_mac_region {
-	u64  start;         /* must be 64 byte -aligned */
-	u32  size;          /* must be 64 byte -granular */
-} __packed;
-
-/* GAS - Generic Address Structure (ACPI 2.0+) */
-struct tboot_acpi_generic_address {
-	u8  space_id;
-	u8  bit_width;
-	u8  bit_offset;
-	u8  access_width;
-	u64 address;
-} __packed;
-
-/*
- * combines Sx info from FADT and FACS tables per ACPI 2.0+ spec
- * (http://www.acpi.info/)
- */
-struct tboot_acpi_sleep_info {
-	struct tboot_acpi_generic_address pm1a_cnt_blk;
-	struct tboot_acpi_generic_address pm1b_cnt_blk;
-	struct tboot_acpi_generic_address pm1a_evt_blk;
-	struct tboot_acpi_generic_address pm1b_evt_blk;
-	u16 pm1a_cnt_val;
-	u16 pm1b_cnt_val;
-	u64 wakeup_vector;
-	u32 vector_width;
-	u64 kernel_s3_resume_vector;
-} __packed;
-
-/*
- * shared memory page used for communication between tboot and kernel
- */
-struct tboot {
-	/*
-	 * version 3+ fields:
-	 */
-
-	/* TBOOT_UUID */
-	u8 uuid[16];
-
-	/* version number: 5 is current */
-	u32 version;
-
-	/* physical addr of tb_log_t log */
-	u32 log_addr;
-
-	/*
-	 * physical addr of entry point for tboot shutdown and
-	 * type of shutdown (TB_SHUTDOWN_*) being requested
-	 */
-	u32 shutdown_entry;
-	u32 shutdown_type;
-
-	/* kernel-specified ACPI info for Sx shutdown */
-	struct tboot_acpi_sleep_info acpi_sinfo;
-
-	/* tboot location in memory (physical) */
-	u32 tboot_base;
-	u32 tboot_size;
-
-	/* memory regions (phys addrs) for tboot to MAC on S3 */
-	u8 num_mac_regions;
-	struct tboot_mac_region mac_regions[MAX_TB_MAC_REGIONS];
-
-
-	/*
-	 * version 4+ fields:
-	 */
-
-	/* symmetric key for use by kernel; will be encrypted on S3 */
-	u8 s3_key[TB_KEY_SIZE];
-
-
-	/*
-	 * version 5+ fields:
-	 */
-
-	/* used to 4byte-align num_in_wfs */
-	u8 reserved_align[3];
-
-	/* number of processors in wait-for-SIPI */
-	u32 num_in_wfs;
-} __packed;
-
-/*
- * UUID for tboot data struct to facilitate matching
- * defined as {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} by tboot, which is
- * represented as {} in the char array used here
- */
-#define TBOOT_UUID	{0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\
-			 0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8}
-
-extern struct tboot *tboot;
-
-static inline int tboot_enabled(void)
-{
-	return tboot != NULL;
-}
-
-extern void tboot_probe(void);
-extern void tboot_create_trampoline(void);
-extern void tboot_shutdown(u32 shutdown_type);
-extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control);
-extern int tboot_wait_for_aps(int num_aps);
-extern struct acpi_table_header *tboot_get_dmar_table(
-				      struct acpi_table_header *dmar_tbl);
-extern int tboot_force_iommu(void);
-
-#else     /* CONFIG_INTEL_TXT */
-
-static inline int tboot_enabled(void)
-{
-	return 0;
-}
-
-static inline void tboot_probe(void)
-{
-}
-
-static inline void tboot_create_trampoline(void)
-{
-}
-
-static inline void tboot_shutdown(u32 shutdown_type)
-{
-}
-
-static inline void tboot_sleep(u8 sleep_state, u32 pm1a_control,
-			       u32 pm1b_control)
-{
-}
-
-static inline int tboot_wait_for_aps(int num_aps)
-{
-	return 0;
-}
-
-static inline struct acpi_table_header *tboot_get_dmar_table(
-					struct acpi_table_header *dmar_tbl)
-{
-	return dmar_tbl;
-}
-
-static inline int tboot_force_iommu(void)
-{
-	return 0;
-}
-
-#endif /* !CONFIG_INTEL_TXT */
-
-#endif /* _ASM_TBOOT_H */
diff -r c6f74b152a32 arch/x86/kernel/reboot.c
--- a/arch/x86/kernel/reboot.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/reboot.c	Tue Sep 01 07:28:21 2009 -0700
@@ -4,6 +4,7 @@
  #include <linux/pm.h>
  #include <linux/efi.h>
  #include <linux/dmi.h>
+#include <linux/tboot.h>
  #include <acpi/reboot.h>
  #include <asm/io.h>
  #include <asm/apic.h>
@@ -23,8 +24,6 @@
  #else
  # include <asm/iommu.h>
  #endif
-
-#include <asm/tboot.h>

  /*
   * Power off function, if any
diff -r c6f74b152a32 arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/setup.c	Tue Sep 01 07:28:21 2009 -0700
@@ -66,6 +66,7 @@

  #include <linux/percpu.h>
  #include <linux/crash_dump.h>
+#include <linux/tboot.h>

  #include <video/edid.h>

@@ -140,8 +141,6 @@ struct boot_params __initdata boot_param
  #else
  struct boot_params boot_params;
  #endif
-
-#include <asm/tboot.h>

  /*
   * Machine setup..
diff -r c6f74b152a32 arch/x86/kernel/smpboot.c
--- a/arch/x86/kernel/smpboot.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/smpboot.c	Tue Sep 01 07:28:21 2009 -0700
@@ -47,6 +47,7 @@
  #include <linux/bootmem.h>
  #include <linux/err.h>
  #include <linux/nmi.h>
+#include <linux/tboot.h>

  #include <asm/acpi.h>
  #include <asm/desc.h>
@@ -62,7 +63,6 @@
  #include <asm/vmi.h>
  #include <asm/apic.h>
  #include <asm/setup.h>
-#include <asm/tboot.h>
  #include <asm/uv/uv.h>
  #include <asm/debugreg.h>
  #include <linux/mc146818rtc.h>
diff -r c6f74b152a32 arch/x86/kernel/tboot.c
--- a/arch/x86/kernel/tboot.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/tboot.c	Tue Sep 01 07:28:21 2009 -0700
@@ -22,11 +22,14 @@
  #include <linux/dma_remapping.h>
  #include <linux/init_task.h>
  #include <linux/spinlock.h>
+#include <linux/delay.h>
  #include <linux/sched.h>
  #include <linux/init.h>
  #include <linux/dmar.h>
+#include <linux/cpu.h>
  #include <linux/pfn.h>
  #include <linux/mm.h>
+#include <linux/tboot.h>

  #include <asm/trampoline.h>
  #include <asm/processor.h>
@@ -36,7 +39,6 @@
  #include <asm/fixmap.h>
  #include <asm/proto.h>
  #include <asm/setup.h>
-#include <asm/tboot.h>
  #include <asm/e820.h>
  #include <asm/io.h>

@@ -154,12 +156,9 @@ static int map_tboot_pages(unsigned long
  	return 0;
  }

-void tboot_create_trampoline(void)
+static void tboot_create_trampoline(void)
  {
  	u32 map_base, map_size;
-
-	if (!tboot_enabled())
-		return;

  	/* Create identity map for tboot shutdown code. */
  	map_base = PFN_DOWN(tboot->tboot_base);
@@ -295,20 +294,57 @@ void tboot_sleep(u8 sleep_state, u32 pm1
  	tboot_shutdown(acpi_shutdown_map[sleep_state]);
  }

-int tboot_wait_for_aps(int num_aps)
+static atomic_t ap_wfs_count;
+
+static int tboot_wait_for_aps(int num_aps)
  {
  	unsigned long timeout;

+	timeout = AP_WAIT_TIMEOUT*HZ;
+	while (atomic_read((atomic_t *)&tboot->num_in_wfs) != num_aps &&
+	       timeout) {
+		mdelay(1);
+		timeout--;
+	}
+
+	if (timeout)
+		pr_warning("tboot wait for APs timeout\n");
+
+	return !(atomic_read((atomic_t *)&tboot->num_in_wfs) == num_aps);
+}
+
+static int __cpuinit tboot_cpu_callback(struct notifier_block *nfb,
+			unsigned long action, void *hcpu)
+{
+	switch (action) {
+	case CPU_DYING:
+		atomic_inc(&ap_wfs_count);
+		if (num_online_cpus() == 1)
+			if (tboot_wait_for_aps(atomic_read(&ap_wfs_count)))
+				return NOTIFY_BAD;
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block tboot_cpu_notifier __cpuinitdata =
+{
+	.notifier_call = tboot_cpu_callback,
+};
+
+static __init int tboot_late_init(void)
+{
  	if (!tboot_enabled())
  		return 0;

-	timeout = jiffies + AP_WAIT_TIMEOUT*HZ;
-	while (atomic_read((atomic_t *)&tboot->num_in_wfs) != num_aps &&
-	       time_before(jiffies, timeout))
-		cpu_relax();
+	tboot_create_trampoline();

-	return time_before(jiffies, timeout) ? 0 : 1;
+	atomic_set(&ap_wfs_count, 0);
+	register_hotcpu_notifier(&tboot_cpu_notifier);
+	return 0;
  }
+
+late_initcall(tboot_late_init);

  /*
   * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE)
diff -r c6f74b152a32 drivers/acpi/acpica/hwsleep.c
--- a/drivers/acpi/acpica/hwsleep.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/drivers/acpi/acpica/hwsleep.c	Tue Sep 01 07:28:21 2009 -0700
@@ -45,7 +45,7 @@
  #include <acpi/acpi.h>
  #include "accommon.h"
  #include "actables.h"
-#include <asm/tboot.h>
+#include <linux/tboot.h>

  #define _COMPONENT          ACPI_HARDWARE
  ACPI_MODULE_NAME("hwsleep")
diff -r c6f74b152a32 drivers/pci/dmar.c
--- a/drivers/pci/dmar.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/drivers/pci/dmar.c	Tue Sep 01 07:28:21 2009 -0700
@@ -33,7 +33,7 @@
  #include <linux/timer.h>
  #include <linux/irq.h>
  #include <linux/interrupt.h>
-#include <asm/tboot.h>
+#include <linux/tboot.h>

  #undef PREFIX
  #define PREFIX "DMAR:"
diff -r c6f74b152a32 drivers/pci/intel-iommu.c
--- a/drivers/pci/intel-iommu.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/drivers/pci/intel-iommu.c	Tue Sep 01 07:28:21 2009 -0700
@@ -37,8 +37,8 @@
  #include <linux/iommu.h>
  #include <linux/intel-iommu.h>
  #include <linux/sysdev.h>
+#include <linux/tboot.h>
  #include <asm/cacheflush.h>
-#include <asm/tboot.h>
  #include <asm/iommu.h>
  #include "pci.h"

diff -r c6f74b152a32 include/linux/tboot.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/linux/tboot.h	Tue Sep 01 07:28:21 2009 -0700
@@ -0,0 +1,162 @@
+/*
+ * tboot.h: shared data structure with tboot and kernel and functions
+ *          used by kernel for runtime support of Intel(R) Trusted
+ *          Execution Technology
+ *
+ * Copyright (c) 2006-2009, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LINUX_TBOOT_H
+#define _LINUX_TBOOT_H
+
+/* these must have the values from 0-5 in this order */
+enum {
+	TB_SHUTDOWN_REBOOT = 0,
+	TB_SHUTDOWN_S5,
+	TB_SHUTDOWN_S4,
+	TB_SHUTDOWN_S3,
+	TB_SHUTDOWN_HALT,
+	TB_SHUTDOWN_WFS
+};
+
+#ifdef CONFIG_INTEL_TXT
+#include <acpi/acpi.h>
+/* used to communicate between tboot and the launched kernel */
+
+#define TB_KEY_SIZE             64   /* 512 bits */
+
+#define MAX_TB_MAC_REGIONS      32
+
+struct tboot_mac_region {
+	u64  start;         /* must be 64 byte -aligned */
+	u32  size;          /* must be 64 byte -granular */
+} __packed;
+
+/* GAS - Generic Address Structure (ACPI 2.0+) */
+struct tboot_acpi_generic_address {
+	u8  space_id;
+	u8  bit_width;
+	u8  bit_offset;
+	u8  access_width;
+	u64 address;
+} __packed;
+
+/*
+ * combines Sx info from FADT and FACS tables per ACPI 2.0+ spec
+ * (http://www.acpi.info/)
+ */
+struct tboot_acpi_sleep_info {
+	struct tboot_acpi_generic_address pm1a_cnt_blk;
+	struct tboot_acpi_generic_address pm1b_cnt_blk;
+	struct tboot_acpi_generic_address pm1a_evt_blk;
+	struct tboot_acpi_generic_address pm1b_evt_blk;
+	u16 pm1a_cnt_val;
+	u16 pm1b_cnt_val;
+	u64 wakeup_vector;
+	u32 vector_width;
+	u64 kernel_s3_resume_vector;
+} __packed;
+
+/*
+ * shared memory page used for communication between tboot and kernel
+ */
+struct tboot {
+	/*
+	 * version 3+ fields:
+	 */
+
+	/* TBOOT_UUID */
+	u8 uuid[16];
+
+	/* version number: 5 is current */
+	u32 version;
+
+	/* physical addr of tb_log_t log */
+	u32 log_addr;
+
+	/*
+	 * physical addr of entry point for tboot shutdown and
+	 * type of shutdown (TB_SHUTDOWN_*) being requested
+	 */
+	u32 shutdown_entry;
+	u32 shutdown_type;
+
+	/* kernel-specified ACPI info for Sx shutdown */
+	struct tboot_acpi_sleep_info acpi_sinfo;
+
+	/* tboot location in memory (physical) */
+	u32 tboot_base;
+	u32 tboot_size;
+
+	/* memory regions (phys addrs) for tboot to MAC on S3 */
+	u8 num_mac_regions;
+	struct tboot_mac_region mac_regions[MAX_TB_MAC_REGIONS];
+
+
+	/*
+	 * version 4+ fields:
+	 */
+
+	/* symmetric key for use by kernel; will be encrypted on S3 */
+	u8 s3_key[TB_KEY_SIZE];
+
+
+	/*
+	 * version 5+ fields:
+	 */
+
+	/* used to 4byte-align num_in_wfs */
+	u8 reserved_align[3];
+
+	/* number of processors in wait-for-SIPI */
+	u32 num_in_wfs;
+} __packed;
+
+/*
+ * UUID for tboot data struct to facilitate matching
+ * defined as {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} by tboot, which is
+ * represented as {} in the char array used here
+ */
+#define TBOOT_UUID	{0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\
+			 0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8}
+
+extern struct tboot *tboot;
+
+static inline int tboot_enabled(void)
+{
+	return tboot != NULL;
+}
+
+extern void tboot_probe(void);
+extern void tboot_shutdown(u32 shutdown_type);
+extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control);
+extern struct acpi_table_header *tboot_get_dmar_table(
+				      struct acpi_table_header *dmar_tbl);
+extern int tboot_force_iommu(void);
+
+#else
+
+#define tboot_probe()			do { } while (0)
+#define tboot_shutdown(shutdown_type)	do { } while (0)
+#define tboot_sleep(sleep_state, pm1a_control, pm1b_control)	\
+					do { } while (0)
+#define tboot_get_dmar_table(dmar_tbl)	(dmar_tbl)
+#define tboot_force_iommu()		0
+
+#endif /* !CONFIG_INTEL_TXT */
+
+#endif /* _LINUX_TBOOT_H */
diff -r c6f74b152a32 init/main.c
--- a/init/main.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/init/main.c	Tue Sep 01 07:28:21 2009 -0700
@@ -73,7 +73,6 @@
  #include <asm/io.h>
  #include <asm/bugs.h>
  #include <asm/setup.h>
-#include <asm/tboot.h>
  #include <asm/sections.h>
  #include <asm/cacheflush.h>

@@ -716,8 +715,6 @@ asmlinkage void __init start_kernel(void

  	ftrace_init();

-	tboot_create_trampoline();
-
  	/* Do the rest non-__init'ed, we're now alive */
  	rest_init();
  }
diff -r c6f74b152a32 kernel/cpu.c
--- a/kernel/cpu.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/kernel/cpu.c	Tue Sep 01 07:28:21 2009 -0700
@@ -14,7 +14,6 @@
  #include <linux/kthread.h>
  #include <linux/stop_machine.h>
  #include <linux/mutex.h>
-#include <asm/tboot.h>

  #ifdef CONFIG_SMP
  /* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -377,7 +376,7 @@ static cpumask_var_t frozen_cpus;

  int disable_nonboot_cpus(void)
  {
-	int cpu, first_cpu, error, num_cpus = 0;
+	int cpu, first_cpu, error;

  	error = stop_machine_create();
  	if (error)
@@ -392,7 +391,6 @@ int disable_nonboot_cpus(void)
  	for_each_online_cpu(cpu) {
  		if (cpu == first_cpu)
  			continue;
-		num_cpus++;
  		error = _cpu_down(cpu, 1);
  		if (!error) {
  			cpumask_set_cpu(cpu, frozen_cpus);
@@ -403,8 +401,6 @@ int disable_nonboot_cpus(void)
  			break;
  		}
  	}
-	/* ensure all CPUs have gone into wait-for-SIPI */
-	error |= tboot_wait_for_aps(num_cpus);

  	if (!error) {
  		BUG_ON(num_online_cpus() > 1);
diff -r c6f74b152a32 security/Kconfig
--- a/security/Kconfig	Tue Sep 01 07:24:42 2009 -0700
+++ b/security/Kconfig	Tue Sep 01 07:28:21 2009 -0700
@@ -131,7 +131,7 @@ config LSM_MMAP_MIN_ADDR

  config INTEL_TXT
  	bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
-	depends on EXPERIMENTAL && X86 && DMAR && ACPI
+	depends on HAVE_INTEL_TXT
  	help
  	  This option enables support for booting the kernel with the
  	  Trusted Boot (tboot) module. This will utilize


[-- Attachment #2: tboot_fix.patch --]
[-- Type: text/plain, Size: 17146 bytes --]

Move tboot.h from asm to linux to fix the build errors of intel_txt patch on non-X86 platforms. Remove the tboot code from generic code init/main.c and kernel/cpu.c.

Signed-off-by: Shane Wang <shane.wang@intel.com>

diff -r c6f74b152a32 arch/x86/Kconfig
--- a/arch/x86/Kconfig	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/Kconfig	Tue Sep 01 07:28:21 2009 -0700
@@ -179,6 +179,10 @@ config ARCH_SUPPORTS_OPTIMIZED_INLINING
 
 config ARCH_SUPPORTS_DEBUG_PAGEALLOC
 	def_bool y
+
+config HAVE_INTEL_TXT
+	def_bool y
+	depends on EXPERIMENTAL && DMAR && ACPI
 
 # Use the generic interrupt handling code in kernel/irq/:
 config GENERIC_HARDIRQS
diff -r c6f74b152a32 arch/x86/include/asm/tboot.h
--- a/arch/x86/include/asm/tboot.h	Tue Sep 01 07:24:42 2009 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * tboot.h: shared data structure with tboot and kernel and functions
- *          used by kernel for runtime support of Intel(R) Trusted
- *          Execution Technology
- *
- * Copyright (c) 2006-2009, Intel Corporation
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef _ASM_TBOOT_H
-#define _ASM_TBOOT_H
-
-#include <acpi/acpi.h>
-
-/* these must have the values from 0-5 in this order */
-enum {
-	TB_SHUTDOWN_REBOOT = 0,
-	TB_SHUTDOWN_S5,
-	TB_SHUTDOWN_S4,
-	TB_SHUTDOWN_S3,
-	TB_SHUTDOWN_HALT,
-	TB_SHUTDOWN_WFS
-};
-
-#ifdef CONFIG_INTEL_TXT
-
-/* used to communicate between tboot and the launched kernel */
-
-#define TB_KEY_SIZE             64   /* 512 bits */
-
-#define MAX_TB_MAC_REGIONS      32
-
-struct tboot_mac_region {
-	u64  start;         /* must be 64 byte -aligned */
-	u32  size;          /* must be 64 byte -granular */
-} __packed;
-
-/* GAS - Generic Address Structure (ACPI 2.0+) */
-struct tboot_acpi_generic_address {
-	u8  space_id;
-	u8  bit_width;
-	u8  bit_offset;
-	u8  access_width;
-	u64 address;
-} __packed;
-
-/*
- * combines Sx info from FADT and FACS tables per ACPI 2.0+ spec
- * (http://www.acpi.info/)
- */
-struct tboot_acpi_sleep_info {
-	struct tboot_acpi_generic_address pm1a_cnt_blk;
-	struct tboot_acpi_generic_address pm1b_cnt_blk;
-	struct tboot_acpi_generic_address pm1a_evt_blk;
-	struct tboot_acpi_generic_address pm1b_evt_blk;
-	u16 pm1a_cnt_val;
-	u16 pm1b_cnt_val;
-	u64 wakeup_vector;
-	u32 vector_width;
-	u64 kernel_s3_resume_vector;
-} __packed;
-
-/*
- * shared memory page used for communication between tboot and kernel
- */
-struct tboot {
-	/*
-	 * version 3+ fields:
-	 */
-
-	/* TBOOT_UUID */
-	u8 uuid[16];
-
-	/* version number: 5 is current */
-	u32 version;
-
-	/* physical addr of tb_log_t log */
-	u32 log_addr;
-
-	/*
-	 * physical addr of entry point for tboot shutdown and
-	 * type of shutdown (TB_SHUTDOWN_*) being requested
-	 */
-	u32 shutdown_entry;
-	u32 shutdown_type;
-
-	/* kernel-specified ACPI info for Sx shutdown */
-	struct tboot_acpi_sleep_info acpi_sinfo;
-
-	/* tboot location in memory (physical) */
-	u32 tboot_base;
-	u32 tboot_size;
-
-	/* memory regions (phys addrs) for tboot to MAC on S3 */
-	u8 num_mac_regions;
-	struct tboot_mac_region mac_regions[MAX_TB_MAC_REGIONS];
-
-
-	/*
-	 * version 4+ fields:
-	 */
-
-	/* symmetric key for use by kernel; will be encrypted on S3 */
-	u8 s3_key[TB_KEY_SIZE];
-
-
-	/*
-	 * version 5+ fields:
-	 */
-
-	/* used to 4byte-align num_in_wfs */
-	u8 reserved_align[3];
-
-	/* number of processors in wait-for-SIPI */
-	u32 num_in_wfs;
-} __packed;
-
-/*
- * UUID for tboot data struct to facilitate matching
- * defined as {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} by tboot, which is
- * represented as {} in the char array used here
- */
-#define TBOOT_UUID	{0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\
-			 0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8}
-
-extern struct tboot *tboot;
-
-static inline int tboot_enabled(void)
-{
-	return tboot != NULL;
-}
-
-extern void tboot_probe(void);
-extern void tboot_create_trampoline(void);
-extern void tboot_shutdown(u32 shutdown_type);
-extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control);
-extern int tboot_wait_for_aps(int num_aps);
-extern struct acpi_table_header *tboot_get_dmar_table(
-				      struct acpi_table_header *dmar_tbl);
-extern int tboot_force_iommu(void);
-
-#else     /* CONFIG_INTEL_TXT */
-
-static inline int tboot_enabled(void)
-{
-	return 0;
-}
-
-static inline void tboot_probe(void)
-{
-}
-
-static inline void tboot_create_trampoline(void)
-{
-}
-
-static inline void tboot_shutdown(u32 shutdown_type)
-{
-}
-
-static inline void tboot_sleep(u8 sleep_state, u32 pm1a_control,
-			       u32 pm1b_control)
-{
-}
-
-static inline int tboot_wait_for_aps(int num_aps)
-{
-	return 0;
-}
-
-static inline struct acpi_table_header *tboot_get_dmar_table(
-					struct acpi_table_header *dmar_tbl)
-{
-	return dmar_tbl;
-}
-
-static inline int tboot_force_iommu(void)
-{
-	return 0;
-}
-
-#endif /* !CONFIG_INTEL_TXT */
-
-#endif /* _ASM_TBOOT_H */
diff -r c6f74b152a32 arch/x86/kernel/reboot.c
--- a/arch/x86/kernel/reboot.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/reboot.c	Tue Sep 01 07:28:21 2009 -0700
@@ -4,6 +4,7 @@
 #include <linux/pm.h>
 #include <linux/efi.h>
 #include <linux/dmi.h>
+#include <linux/tboot.h>
 #include <acpi/reboot.h>
 #include <asm/io.h>
 #include <asm/apic.h>
@@ -23,8 +24,6 @@
 #else
 # include <asm/iommu.h>
 #endif
-
-#include <asm/tboot.h>
 
 /*
  * Power off function, if any
diff -r c6f74b152a32 arch/x86/kernel/setup.c
--- a/arch/x86/kernel/setup.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/setup.c	Tue Sep 01 07:28:21 2009 -0700
@@ -66,6 +66,7 @@
 
 #include <linux/percpu.h>
 #include <linux/crash_dump.h>
+#include <linux/tboot.h>
 
 #include <video/edid.h>
 
@@ -140,8 +141,6 @@ struct boot_params __initdata boot_param
 #else
 struct boot_params boot_params;
 #endif
-
-#include <asm/tboot.h>
 
 /*
  * Machine setup..
diff -r c6f74b152a32 arch/x86/kernel/smpboot.c
--- a/arch/x86/kernel/smpboot.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/smpboot.c	Tue Sep 01 07:28:21 2009 -0700
@@ -47,6 +47,7 @@
 #include <linux/bootmem.h>
 #include <linux/err.h>
 #include <linux/nmi.h>
+#include <linux/tboot.h>
 
 #include <asm/acpi.h>
 #include <asm/desc.h>
@@ -62,7 +63,6 @@
 #include <asm/vmi.h>
 #include <asm/apic.h>
 #include <asm/setup.h>
-#include <asm/tboot.h>
 #include <asm/uv/uv.h>
 #include <asm/debugreg.h>
 #include <linux/mc146818rtc.h>
diff -r c6f74b152a32 arch/x86/kernel/tboot.c
--- a/arch/x86/kernel/tboot.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/arch/x86/kernel/tboot.c	Tue Sep 01 07:28:21 2009 -0700
@@ -22,11 +22,14 @@
 #include <linux/dma_remapping.h>
 #include <linux/init_task.h>
 #include <linux/spinlock.h>
+#include <linux/delay.h>
 #include <linux/sched.h>
 #include <linux/init.h>
 #include <linux/dmar.h>
+#include <linux/cpu.h>
 #include <linux/pfn.h>
 #include <linux/mm.h>
+#include <linux/tboot.h>
 
 #include <asm/trampoline.h>
 #include <asm/processor.h>
@@ -36,7 +39,6 @@
 #include <asm/fixmap.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
-#include <asm/tboot.h>
 #include <asm/e820.h>
 #include <asm/io.h>
 
@@ -154,12 +156,9 @@ static int map_tboot_pages(unsigned long
 	return 0;
 }
 
-void tboot_create_trampoline(void)
+static void tboot_create_trampoline(void)
 {
 	u32 map_base, map_size;
-
-	if (!tboot_enabled())
-		return;
 
 	/* Create identity map for tboot shutdown code. */
 	map_base = PFN_DOWN(tboot->tboot_base);
@@ -295,20 +294,57 @@ void tboot_sleep(u8 sleep_state, u32 pm1
 	tboot_shutdown(acpi_shutdown_map[sleep_state]);
 }
 
-int tboot_wait_for_aps(int num_aps)
+static atomic_t ap_wfs_count;
+
+static int tboot_wait_for_aps(int num_aps)
 {
 	unsigned long timeout;
 
+	timeout = AP_WAIT_TIMEOUT*HZ;
+	while (atomic_read((atomic_t *)&tboot->num_in_wfs) != num_aps &&
+	       timeout) {
+		mdelay(1);
+		timeout--;
+	}
+
+	if (timeout)
+		pr_warning("tboot wait for APs timeout\n");
+
+	return !(atomic_read((atomic_t *)&tboot->num_in_wfs) == num_aps);
+}
+
+static int __cpuinit tboot_cpu_callback(struct notifier_block *nfb,
+			unsigned long action, void *hcpu)
+{
+	switch (action) {
+	case CPU_DYING:
+		atomic_inc(&ap_wfs_count);
+		if (num_online_cpus() == 1)
+			if (tboot_wait_for_aps(atomic_read(&ap_wfs_count)))
+				return NOTIFY_BAD;
+		break;
+	}
+	return NOTIFY_OK;
+}
+
+static struct notifier_block tboot_cpu_notifier __cpuinitdata =
+{
+	.notifier_call = tboot_cpu_callback,
+};
+
+static __init int tboot_late_init(void)
+{
 	if (!tboot_enabled())
 		return 0;
 
-	timeout = jiffies + AP_WAIT_TIMEOUT*HZ;
-	while (atomic_read((atomic_t *)&tboot->num_in_wfs) != num_aps &&
-	       time_before(jiffies, timeout))
-		cpu_relax();
+	tboot_create_trampoline();
 
-	return time_before(jiffies, timeout) ? 0 : 1;
+	atomic_set(&ap_wfs_count, 0);
+	register_hotcpu_notifier(&tboot_cpu_notifier);
+	return 0;
 }
+
+late_initcall(tboot_late_init);
 
 /*
  * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE)
diff -r c6f74b152a32 drivers/acpi/acpica/hwsleep.c
--- a/drivers/acpi/acpica/hwsleep.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/drivers/acpi/acpica/hwsleep.c	Tue Sep 01 07:28:21 2009 -0700
@@ -45,7 +45,7 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "actables.h"
-#include <asm/tboot.h>
+#include <linux/tboot.h>
 
 #define _COMPONENT          ACPI_HARDWARE
 ACPI_MODULE_NAME("hwsleep")
diff -r c6f74b152a32 drivers/pci/dmar.c
--- a/drivers/pci/dmar.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/drivers/pci/dmar.c	Tue Sep 01 07:28:21 2009 -0700
@@ -33,7 +33,7 @@
 #include <linux/timer.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
-#include <asm/tboot.h>
+#include <linux/tboot.h>
 
 #undef PREFIX
 #define PREFIX "DMAR:"
diff -r c6f74b152a32 drivers/pci/intel-iommu.c
--- a/drivers/pci/intel-iommu.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/drivers/pci/intel-iommu.c	Tue Sep 01 07:28:21 2009 -0700
@@ -37,8 +37,8 @@
 #include <linux/iommu.h>
 #include <linux/intel-iommu.h>
 #include <linux/sysdev.h>
+#include <linux/tboot.h>
 #include <asm/cacheflush.h>
-#include <asm/tboot.h>
 #include <asm/iommu.h>
 #include "pci.h"
 
diff -r c6f74b152a32 include/linux/tboot.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/linux/tboot.h	Tue Sep 01 07:28:21 2009 -0700
@@ -0,0 +1,162 @@
+/*
+ * tboot.h: shared data structure with tboot and kernel and functions
+ *          used by kernel for runtime support of Intel(R) Trusted
+ *          Execution Technology
+ *
+ * Copyright (c) 2006-2009, Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _LINUX_TBOOT_H
+#define _LINUX_TBOOT_H
+
+/* these must have the values from 0-5 in this order */
+enum {
+	TB_SHUTDOWN_REBOOT = 0,
+	TB_SHUTDOWN_S5,
+	TB_SHUTDOWN_S4,
+	TB_SHUTDOWN_S3,
+	TB_SHUTDOWN_HALT,
+	TB_SHUTDOWN_WFS
+};
+
+#ifdef CONFIG_INTEL_TXT
+#include <acpi/acpi.h>
+/* used to communicate between tboot and the launched kernel */
+
+#define TB_KEY_SIZE             64   /* 512 bits */
+
+#define MAX_TB_MAC_REGIONS      32
+
+struct tboot_mac_region {
+	u64  start;         /* must be 64 byte -aligned */
+	u32  size;          /* must be 64 byte -granular */
+} __packed;
+
+/* GAS - Generic Address Structure (ACPI 2.0+) */
+struct tboot_acpi_generic_address {
+	u8  space_id;
+	u8  bit_width;
+	u8  bit_offset;
+	u8  access_width;
+	u64 address;
+} __packed;
+
+/*
+ * combines Sx info from FADT and FACS tables per ACPI 2.0+ spec
+ * (http://www.acpi.info/)
+ */
+struct tboot_acpi_sleep_info {
+	struct tboot_acpi_generic_address pm1a_cnt_blk;
+	struct tboot_acpi_generic_address pm1b_cnt_blk;
+	struct tboot_acpi_generic_address pm1a_evt_blk;
+	struct tboot_acpi_generic_address pm1b_evt_blk;
+	u16 pm1a_cnt_val;
+	u16 pm1b_cnt_val;
+	u64 wakeup_vector;
+	u32 vector_width;
+	u64 kernel_s3_resume_vector;
+} __packed;
+
+/*
+ * shared memory page used for communication between tboot and kernel
+ */
+struct tboot {
+	/*
+	 * version 3+ fields:
+	 */
+
+	/* TBOOT_UUID */
+	u8 uuid[16];
+
+	/* version number: 5 is current */
+	u32 version;
+
+	/* physical addr of tb_log_t log */
+	u32 log_addr;
+
+	/*
+	 * physical addr of entry point for tboot shutdown and
+	 * type of shutdown (TB_SHUTDOWN_*) being requested
+	 */
+	u32 shutdown_entry;
+	u32 shutdown_type;
+
+	/* kernel-specified ACPI info for Sx shutdown */
+	struct tboot_acpi_sleep_info acpi_sinfo;
+
+	/* tboot location in memory (physical) */
+	u32 tboot_base;
+	u32 tboot_size;
+
+	/* memory regions (phys addrs) for tboot to MAC on S3 */
+	u8 num_mac_regions;
+	struct tboot_mac_region mac_regions[MAX_TB_MAC_REGIONS];
+
+
+	/*
+	 * version 4+ fields:
+	 */
+
+	/* symmetric key for use by kernel; will be encrypted on S3 */
+	u8 s3_key[TB_KEY_SIZE];
+
+
+	/*
+	 * version 5+ fields:
+	 */
+
+	/* used to 4byte-align num_in_wfs */
+	u8 reserved_align[3];
+
+	/* number of processors in wait-for-SIPI */
+	u32 num_in_wfs;
+} __packed;
+
+/*
+ * UUID for tboot data struct to facilitate matching
+ * defined as {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} by tboot, which is
+ * represented as {} in the char array used here
+ */
+#define TBOOT_UUID	{0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\
+			 0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8}
+
+extern struct tboot *tboot;
+
+static inline int tboot_enabled(void)
+{
+	return tboot != NULL;
+}
+
+extern void tboot_probe(void);
+extern void tboot_shutdown(u32 shutdown_type);
+extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control);
+extern struct acpi_table_header *tboot_get_dmar_table(
+				      struct acpi_table_header *dmar_tbl);
+extern int tboot_force_iommu(void);
+
+#else
+
+#define tboot_probe()			do { } while (0)
+#define tboot_shutdown(shutdown_type)	do { } while (0)
+#define tboot_sleep(sleep_state, pm1a_control, pm1b_control)	\
+					do { } while (0)
+#define tboot_get_dmar_table(dmar_tbl)	(dmar_tbl)
+#define tboot_force_iommu()		0
+
+#endif /* !CONFIG_INTEL_TXT */
+
+#endif /* _LINUX_TBOOT_H */
diff -r c6f74b152a32 init/main.c
--- a/init/main.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/init/main.c	Tue Sep 01 07:28:21 2009 -0700
@@ -73,7 +73,6 @@
 #include <asm/io.h>
 #include <asm/bugs.h>
 #include <asm/setup.h>
-#include <asm/tboot.h>
 #include <asm/sections.h>
 #include <asm/cacheflush.h>
 
@@ -716,8 +715,6 @@ asmlinkage void __init start_kernel(void
 
 	ftrace_init();
 
-	tboot_create_trampoline();
-
 	/* Do the rest non-__init'ed, we're now alive */
 	rest_init();
 }
diff -r c6f74b152a32 kernel/cpu.c
--- a/kernel/cpu.c	Tue Sep 01 07:24:42 2009 -0700
+++ b/kernel/cpu.c	Tue Sep 01 07:28:21 2009 -0700
@@ -14,7 +14,6 @@
 #include <linux/kthread.h>
 #include <linux/stop_machine.h>
 #include <linux/mutex.h>
-#include <asm/tboot.h>
 
 #ifdef CONFIG_SMP
 /* Serializes the updates to cpu_online_mask, cpu_present_mask */
@@ -377,7 +376,7 @@ static cpumask_var_t frozen_cpus;
 
 int disable_nonboot_cpus(void)
 {
-	int cpu, first_cpu, error, num_cpus = 0;
+	int cpu, first_cpu, error;
 
 	error = stop_machine_create();
 	if (error)
@@ -392,7 +391,6 @@ int disable_nonboot_cpus(void)
 	for_each_online_cpu(cpu) {
 		if (cpu == first_cpu)
 			continue;
-		num_cpus++;
 		error = _cpu_down(cpu, 1);
 		if (!error) {
 			cpumask_set_cpu(cpu, frozen_cpus);
@@ -403,8 +401,6 @@ int disable_nonboot_cpus(void)
 			break;
 		}
 	}
-	/* ensure all CPUs have gone into wait-for-SIPI */
-	error |= tboot_wait_for_aps(num_cpus);
 
 	if (!error) {
 		BUG_ON(num_online_cpus() > 1);
diff -r c6f74b152a32 security/Kconfig
--- a/security/Kconfig	Tue Sep 01 07:24:42 2009 -0700
+++ b/security/Kconfig	Tue Sep 01 07:28:21 2009 -0700
@@ -131,7 +131,7 @@ config LSM_MMAP_MIN_ADDR
 
 config INTEL_TXT
 	bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
-	depends on EXPERIMENTAL && X86 && DMAR && ACPI
+	depends on HAVE_INTEL_TXT
 	help
 	  This option enables support for booting the kernel with the
 	  Trusted Boot (tboot) module. This will utilize

^ permalink raw reply	[flat|nested] 32+ messages in thread
* [PATCH] intel_txt: add s3 userspace memory integrity verification
@ 2009-12-04  9:12 Shane Wang
  2009-12-04  8:29 ` Pavel Machek
  2009-12-04 11:05 ` Andi Kleen
  0 siblings, 2 replies; 32+ messages in thread
From: Shane Wang @ 2009-12-04  9:12 UTC (permalink / raw)
  To: linux-kernel@vger.kernel.org, Ingo Molnar, H. Peter Anvin,
	Cihula, Joseph, arjan@linux.intel.com, Andi Kleen,
	chrisw@sous-sol.org, jmorris@namei.org, jbeulich@novell.com,
	peterm@redhat.com, len.brown, Pavel Machek, Rafael J. Wysocki,
	linux-pm, shane.wang

[-- Attachment #1: Type: text/plain, Size: 10630 bytes --]

This patch added verification for userspace memory integrity after S3 resume.
Integrity verification for other memory (say kernel itself) has been done by tboot.

Thanks
Shane

---
  arch/x86/kernel/entry_64.S |   20 +++
  arch/x86/kernel/tboot.c    |  226 +++++++++++++++++++++++++++++++++++
  drivers/acpi/sleep.c       |    3
  include/linux/mm.h         |    8 -
  include/linux/tboot.h      |    3
  security/Kconfig           |    2
  6 files changed, 256 insertions(+), 6 deletions(-)

Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>

diff -r c878d454dc8b arch/x86/kernel/entry_64.S
--- a/arch/x86/kernel/entry_64.S	Wed Dec 02 01:06:32 2009 -0800
+++ b/arch/x86/kernel/entry_64.S	Thu Dec 03 07:22:17 2009 -0800
@@ -1275,6 +1275,26 @@ ENTRY(call_softirq)
  	CFI_ENDPROC
  END(call_softirq)

+#ifdef CONFIG_INTEL_TXT
+/* void tboot_switch_stack_call(void (*target_func)(void), u64 new_rsp) */
+ENTRY(tboot_switch_stack_call)
+	CFI_STARTPROC
+	push %rbp
+	CFI_ADJUST_CFA_OFFSET	8
+	CFI_REL_OFFSET	rbp,0
+	mov %rsp, %rbp
+	CFI_DEF_CFA_REGISTER	rbp
+	mov %rsi, %rsp
+	push %rbp
+	call *%rdi
+	leaveq
+	CFI_DEF_CFA_REGISTER	rsp
+	CFI_ADJUST_CFA_OFFSET	-8
+	ret
+	CFI_ENDPROC
+END(tboot_switch_stack_call)
+#endif
+
  #ifdef CONFIG_XEN
  zeroentry xen_hypervisor_callback xen_do_hypervisor_callback

diff -r c878d454dc8b arch/x86/kernel/tboot.c
--- a/arch/x86/kernel/tboot.c	Wed Dec 02 01:06:32 2009 -0800
+++ b/arch/x86/kernel/tboot.c	Thu Dec 03 07:22:17 2009 -0800
@@ -20,6 +20,7 @@
   */

  #include <linux/dma_remapping.h>
+#include <linux/scatterlist.h>
  #include <linux/init_task.h>
  #include <linux/spinlock.h>
  #include <linux/delay.h>
@@ -30,12 +31,17 @@
  #include <linux/pfn.h>
  #include <linux/mm.h>
  #include <linux/tboot.h>
+#include <linux/random.h>
+
+#include <crypto/vmac.h>
+#include <crypto/hash.h>

  #include <asm/trampoline.h>
  #include <asm/processor.h>
  #include <asm/bootparam.h>
  #include <asm/pgtable.h>
  #include <asm/pgalloc.h>
+#include <asm/percpu.h>
  #include <asm/fixmap.h>
  #include <asm/proto.h>
  #include <asm/setup.h>
@@ -168,6 +174,159 @@ static void tboot_create_trampoline(void
  		      map_base, map_size);
  }

+#ifdef CONFIG_X86_64
+static char *new_stack, *new_stack_ptr;
+
+static int tboot_pre_stack_switch(void)
+{
+	BUG_ON((new_stack != NULL) || (new_stack_ptr != NULL));
+
+	/*
+	 * as long as thread info is above 4G, then switch stack,
+	 * since tboot can't access >4G stack for MACing
+	 */
+	if (!((PFN_PHYS(PFN_DOWN(virt_to_phys(current_thread_info())))
+		+ (PFN_UP(THREAD_SIZE) << PAGE_SHIFT))
+		& 0xffffffff00000000UL))
+		return -1;
+
+	new_stack = (char *)__get_free_pages(GFP_DMA32, IRQ_STACK_ORDER);
+
+	BUG_ON(new_stack == NULL);
+	memset(new_stack, 0, IRQ_STACK_SIZE);
+	new_stack_ptr = new_stack + IRQ_STACK_SIZE - 64;
+
+	return 0;
+}
+
+static void tboot_post_stack_switch(void)
+{
+	BUG_ON((new_stack == NULL) || (new_stack_ptr == NULL));
+
+	free_pages((unsigned long)new_stack, IRQ_STACK_ORDER);
+	new_stack = NULL;
+	new_stack_ptr = NULL;
+}
+
+extern void tboot_switch_stack_call(void (*target_func)(void), u64 new_rsp);
+
+#else /* CONFIG_X86_32 */
+
+#define tboot_pre_stack_switch()			(-1)
+#define tboot_post_stack_switch()			do { } while (0)
+#define tboot_switch_stack_call(target_func, new_rsp)	do { } while (0)
+
+#endif
+
+static vmac_t mem_mac;
+static struct crypto_hash *tfm;
+
+static int tboot_gen_mem_integrity(const uint8_t key[], vmac_t *mac)
+{
+	int i, j, ret;
+	pg_data_t *pgdat;
+	struct hash_desc desc;
+	struct scatterlist sg[1];
+	struct page *page;
+	uint64_t paddr, rstart, rend;
+	unsigned long pfn;
+	uint8_t zeroed_key[VMAC_KEY_LEN];
+
+	if (!tfm)
+		tfm = crypto_alloc_hash("vmac(aes)", 0, CRYPTO_ALG_ASYNC);
+
+	if (IS_ERR(tfm)) {
+		tfm = NULL;
+		return -ENOMEM;
+	}
+
+	desc.tfm = tfm;
+	desc.flags = 0;
+
+	sg_init_table(sg, 1);
+
+	ret = crypto_hash_init(&desc);
+	if (ret)
+		return ret;
+	ret = crypto_hash_setkey(desc.tfm, key, VMAC_KEY_LEN);
+	if (ret)
+		return ret;
+
+	for_each_online_pgdat(pgdat) {
+		unsigned long flags;
+
+		pgdat_resize_lock(pgdat, &flags);
+		for (i = 0, pfn = pgdat->node_start_pfn;
+			i < pgdat->node_spanned_pages;
+			i++, pfn = pgdat->node_start_pfn + i) {
+
+			if (!pfn_valid(pfn) || !page_is_ram(pfn))
+				continue;
+
+			page = pfn_to_page(pfn);
+			paddr = page_to_phys(page);
+
+			/* If pg will be MACed by tboot, no need to MAC here */
+			for (j = 0; j < tboot->num_mac_regions; j++) {
+				rstart = tboot->mac_regions[j].start;
+				rend = rstart +	tboot->mac_regions[j].size;
+				if (((paddr + PAGE_SIZE) <= rstart)
+					|| (rend <= paddr))
+					continue;
+				break;
+			}
+
+			if (j == tboot->num_mac_regions) {
+				sg_set_page(sg, page, PAGE_SIZE, 0);
+#ifdef CONFIG_DEBUG_PAGEALLOC
+			/*
+			 * check if the page we are going to MAC is marked as
+			 * present in the kernel page tables.
+			 */
+			if (!kernel_page_present(page)) {
+				kernel_map_pages(page, 1, 1);
+				ret = crypto_hash_update(&desc, sg, PAGE_SIZE);
+				kernel_map_pages(page, 1, 0);
+			} else
+#endif
+				ret = crypto_hash_update(&desc, sg, PAGE_SIZE);
+				if (ret) {
+					pgdat_resize_unlock(pgdat, &flags);
+					return ret;
+				}
+			}
+		}
+		pgdat_resize_unlock(pgdat, &flags);
+	}
+
+#ifdef CONFIG_X86_64
+	/*
+	 * for stack > 4G, we should MAC the stack in the kernel after switch,
+	 * for stack < 4G, the stack is MACed by tboot
+	 */
+	if (new_stack) {
+		for (i = 0, page = virt_to_page((void *)current_thread_info());
+			i < (1 << THREAD_ORDER);
+			i++, page++) {
+			sg_set_page(sg, page, PAGE_SIZE, 0);
+			ret = crypto_hash_update(&desc, sg, PAGE_SIZE);
+			if (ret)
+				return ret;
+		}
+	}
+#endif
+
+	ret = crypto_hash_final(&desc, (uint8_t *)mac);
+	if (ret)
+		return ret;
+
+	/* Clean the key */
+	memset(zeroed_key, 0, sizeof(zeroed_key));
+	crypto_hash_setkey(desc.tfm, zeroed_key, VMAC_KEY_LEN);
+
+	return 0;
+}
+
  #ifdef CONFIG_ACPI_SLEEP

  static void add_mac_region(phys_addr_t start, unsigned long size)
@@ -196,6 +355,27 @@ static int tboot_setup_sleep(void)

  	/* kernel code + data + bss */
  	add_mac_region(virt_to_phys(_text), _end - _text);
+
+	/* stack */
+#ifdef CONFIG_X86_64
+	/*
+	 * if stack > 4G, we should MAC the stack in the kernel after switch,
+	 * if stack < 4G, the stack is MACed by tboot
+	 */
+	if (new_stack)
+		add_mac_region(virt_to_phys(new_stack),
+				IRQ_STACK_SIZE); /* > 4G */
+	else
+#endif
+		add_mac_region(virt_to_phys(current_thread_info()),
+				THREAD_SIZE); /* < 4G */
+
+	/* MAC userspace memory not handled by tboot */
+	get_random_bytes(tboot->s3_key, sizeof(tboot->s3_key));
+	if (tboot_gen_mem_integrity(tboot->s3_key, &mem_mac)) {
+		panic("tboot: vmac generation failed\n");
+		return -1;
+	}

  	tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address;

@@ -292,6 +472,52 @@ void tboot_sleep(u8 sleep_state, u32 pm1
  	}

  	tboot_shutdown(acpi_shutdown_map[sleep_state]);
+}
+
+static void tboot_sx_resume(void)
+{
+	vmac_t mac;
+
+	if (tboot_gen_mem_integrity(tboot->s3_key, &mac))
+		panic("tboot: vmac generation failed\n");
+	else if (mac != mem_mac)
+#ifdef CONFIG_DEBUG_KERNEL
+		pr_debug("tboot: memory integrity %llx -> %llx\n",
+				mem_mac, mac);
+#else
+		panic("tboot: memory integrity was lost on resume\n");
+#endif
+	else
+		pr_info("memory integrity OK\n");
+
+	/* Clean s3_key */
+	memset(tboot->s3_key, 0, sizeof(tboot->s3_key));
+}
+
+extern void do_suspend_lowlevel(void);
+
+static void tboot_do_suspend_lowlevel_call(void)
+{
+	do_suspend_lowlevel();
+	tboot_sx_resume();
+}
+
+void tboot_do_suspend_lowlevel(void)
+{
+	int ret = -1;
+
+	if (!tboot_enabled()) {
+		do_suspend_lowlevel();
+		return;
+	}
+
+	ret = tboot_pre_stack_switch();
+	if (!ret) {
+		tboot_switch_stack_call(tboot_do_suspend_lowlevel_call,
+					(u64)new_stack_ptr);
+		tboot_post_stack_switch();
+	} else
+		tboot_do_suspend_lowlevel_call();
  }

  static atomic_t ap_wfs_count;
diff -r c878d454dc8b drivers/acpi/sleep.c
--- a/drivers/acpi/sleep.c	Wed Dec 02 01:06:32 2009 -0800
+++ b/drivers/acpi/sleep.c	Thu Dec 03 07:22:17 2009 -0800
@@ -16,6 +16,7 @@
  #include <linux/device.h>
  #include <linux/suspend.h>
  #include <linux/reboot.h>
+#include <linux/tboot.h>

  #include <asm/io.h>

@@ -244,7 +245,7 @@ static int acpi_suspend_enter(suspend_st
  		break;

  	case ACPI_STATE_S3:
-		do_suspend_lowlevel();
+		tboot_do_suspend_lowlevel();
  		break;
  	}

diff -r c878d454dc8b include/linux/mm.h
--- a/include/linux/mm.h	Wed Dec 02 01:06:32 2009 -0800
+++ b/include/linux/mm.h	Thu Dec 03 07:22:17 2009 -0800
@@ -1263,18 +1263,18 @@ static inline void enable_debug_pageallo
  {
  	debug_pagealloc_enabled = 1;
  }
-#ifdef CONFIG_HIBERNATION
+#if defined(CONFIG_HIBERNATION) || defined(CONFIG_INTEL_TXT)
  extern bool kernel_page_present(struct page *page);
-#endif /* CONFIG_HIBERNATION */
+#endif /* CONFIG_HIBERNATION || CONFIG_INTEL_TXT */
  #else
  static inline void
  kernel_map_pages(struct page *page, int numpages, int enable) {}
  static inline void enable_debug_pagealloc(void)
  {
  }
-#ifdef CONFIG_HIBERNATION
+#if defined(CONFIG_HIBERNATION) || defined(CONFIG_INTEL_TXT)
  static inline bool kernel_page_present(struct page *page) { return true; }
-#endif /* CONFIG_HIBERNATION */
+#endif /* CONFIG_HIBERNATION || CONFIG_INTEL_TXT */
  #endif

  extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
diff -r c878d454dc8b include/linux/tboot.h
--- a/include/linux/tboot.h	Wed Dec 02 01:06:32 2009 -0800
+++ b/include/linux/tboot.h	Thu Dec 03 07:22:17 2009 -0800
@@ -147,7 +147,7 @@ extern struct acpi_table_header *tboot_g
  extern struct acpi_table_header *tboot_get_dmar_table(
  				      struct acpi_table_header *dmar_tbl);
  extern int tboot_force_iommu(void);
-
+extern void tboot_do_suspend_lowlevel(void);
  #else

  #define tboot_probe()			do { } while (0)
@@ -156,6 +156,7 @@ extern int tboot_force_iommu(void);
  					do { } while (0)
  #define tboot_get_dmar_table(dmar_tbl)	(dmar_tbl)
  #define tboot_force_iommu()		0
+#define tboot_do_suspend_lowlevel()	do_suspend_lowlevel()

  #endif /* !CONFIG_INTEL_TXT */

diff -r c878d454dc8b security/Kconfig
--- a/security/Kconfig	Wed Dec 02 01:06:32 2009 -0800
+++ b/security/Kconfig	Thu Dec 03 07:22:17 2009 -0800
@@ -116,6 +116,8 @@ config INTEL_TXT
  config INTEL_TXT
  	bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
  	depends on HAVE_INTEL_TXT
+	select CRYPTO_VMAC
+	select CRYPTO_AES
  	help
  	  This option enables support for booting the kernel with the
  	  Trusted Boot (tboot) module. This will utilize

[-- Attachment #2: s3.patch --]
[-- Type: text/plain, Size: 10252 bytes --]

This patch added verification for userspace memory integrity after S3 resume.
Integrity verification for other memory (say kernel itself) has been done by tboot.

Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>

diff -r c878d454dc8b arch/x86/kernel/entry_64.S
--- a/arch/x86/kernel/entry_64.S	Wed Dec 02 01:06:32 2009 -0800
+++ b/arch/x86/kernel/entry_64.S	Thu Dec 03 07:22:17 2009 -0800
@@ -1275,6 +1275,26 @@ ENTRY(call_softirq)
 	CFI_ENDPROC
 END(call_softirq)
 
+#ifdef CONFIG_INTEL_TXT
+/* void tboot_switch_stack_call(void (*target_func)(void), u64 new_rsp) */
+ENTRY(tboot_switch_stack_call)
+	CFI_STARTPROC
+	push %rbp
+	CFI_ADJUST_CFA_OFFSET	8
+	CFI_REL_OFFSET	rbp,0
+	mov %rsp, %rbp
+	CFI_DEF_CFA_REGISTER	rbp
+	mov %rsi, %rsp
+	push %rbp
+	call *%rdi
+	leaveq
+	CFI_DEF_CFA_REGISTER	rsp
+	CFI_ADJUST_CFA_OFFSET	-8
+	ret
+	CFI_ENDPROC
+END(tboot_switch_stack_call)
+#endif
+
 #ifdef CONFIG_XEN
 zeroentry xen_hypervisor_callback xen_do_hypervisor_callback
 
diff -r c878d454dc8b arch/x86/kernel/tboot.c
--- a/arch/x86/kernel/tboot.c	Wed Dec 02 01:06:32 2009 -0800
+++ b/arch/x86/kernel/tboot.c	Thu Dec 03 07:22:17 2009 -0800
@@ -20,6 +20,7 @@
  */
 
 #include <linux/dma_remapping.h>
+#include <linux/scatterlist.h>
 #include <linux/init_task.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
@@ -30,12 +31,17 @@
 #include <linux/pfn.h>
 #include <linux/mm.h>
 #include <linux/tboot.h>
+#include <linux/random.h>
+
+#include <crypto/vmac.h>
+#include <crypto/hash.h>
 
 #include <asm/trampoline.h>
 #include <asm/processor.h>
 #include <asm/bootparam.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/percpu.h>
 #include <asm/fixmap.h>
 #include <asm/proto.h>
 #include <asm/setup.h>
@@ -168,6 +174,159 @@ static void tboot_create_trampoline(void
 		      map_base, map_size);
 }
 
+#ifdef CONFIG_X86_64
+static char *new_stack, *new_stack_ptr;
+
+static int tboot_pre_stack_switch(void)
+{
+	BUG_ON((new_stack != NULL) || (new_stack_ptr != NULL));
+
+	/*
+	 * as long as thread info is above 4G, then switch stack,
+	 * since tboot can't access >4G stack for MACing
+	 */
+	if (!((PFN_PHYS(PFN_DOWN(virt_to_phys(current_thread_info())))
+		+ (PFN_UP(THREAD_SIZE) << PAGE_SHIFT))
+		& 0xffffffff00000000UL))
+		return -1;
+
+	new_stack = (char *)__get_free_pages(GFP_DMA32, IRQ_STACK_ORDER);
+
+	BUG_ON(new_stack == NULL);
+	memset(new_stack, 0, IRQ_STACK_SIZE);
+	new_stack_ptr = new_stack + IRQ_STACK_SIZE - 64;
+
+	return 0;
+}
+
+static void tboot_post_stack_switch(void)
+{
+	BUG_ON((new_stack == NULL) || (new_stack_ptr == NULL));
+
+	free_pages((unsigned long)new_stack, IRQ_STACK_ORDER);
+	new_stack = NULL;
+	new_stack_ptr = NULL;
+}
+
+extern void tboot_switch_stack_call(void (*target_func)(void), u64 new_rsp);
+
+#else /* CONFIG_X86_32 */
+
+#define tboot_pre_stack_switch()			(-1)
+#define tboot_post_stack_switch()			do { } while (0)
+#define tboot_switch_stack_call(target_func, new_rsp)	do { } while (0)
+
+#endif
+
+static vmac_t mem_mac;
+static struct crypto_hash *tfm;
+
+static int tboot_gen_mem_integrity(const uint8_t key[], vmac_t *mac)
+{
+	int i, j, ret;
+	pg_data_t *pgdat;
+	struct hash_desc desc;
+	struct scatterlist sg[1];
+	struct page *page;
+	uint64_t paddr, rstart, rend;
+	unsigned long pfn;
+	uint8_t zeroed_key[VMAC_KEY_LEN];
+
+	if (!tfm)
+		tfm = crypto_alloc_hash("vmac(aes)", 0, CRYPTO_ALG_ASYNC);
+
+	if (IS_ERR(tfm)) {
+		tfm = NULL;
+		return -ENOMEM;
+	}
+
+	desc.tfm = tfm;
+	desc.flags = 0;
+
+	sg_init_table(sg, 1);
+
+	ret = crypto_hash_init(&desc);
+	if (ret)
+		return ret;
+	ret = crypto_hash_setkey(desc.tfm, key, VMAC_KEY_LEN);
+	if (ret)
+		return ret;
+
+	for_each_online_pgdat(pgdat) {
+		unsigned long flags;
+
+		pgdat_resize_lock(pgdat, &flags);
+		for (i = 0, pfn = pgdat->node_start_pfn;
+			i < pgdat->node_spanned_pages;
+			i++, pfn = pgdat->node_start_pfn + i) {
+
+			if (!pfn_valid(pfn) || !page_is_ram(pfn))
+				continue;
+
+			page = pfn_to_page(pfn);
+			paddr = page_to_phys(page);
+
+			/* If pg will be MACed by tboot, no need to MAC here */
+			for (j = 0; j < tboot->num_mac_regions; j++) {
+				rstart = tboot->mac_regions[j].start;
+				rend = rstart +	tboot->mac_regions[j].size;
+				if (((paddr + PAGE_SIZE) <= rstart)
+					|| (rend <= paddr))
+					continue;
+				break;
+			}
+
+			if (j == tboot->num_mac_regions) {
+				sg_set_page(sg, page, PAGE_SIZE, 0);
+#ifdef CONFIG_DEBUG_PAGEALLOC
+			/*
+			 * check if the page we are going to MAC is marked as
+			 * present in the kernel page tables.
+			 */
+			if (!kernel_page_present(page)) {
+				kernel_map_pages(page, 1, 1);
+				ret = crypto_hash_update(&desc, sg, PAGE_SIZE);
+				kernel_map_pages(page, 1, 0);
+			} else
+#endif
+				ret = crypto_hash_update(&desc, sg, PAGE_SIZE);
+				if (ret) {
+					pgdat_resize_unlock(pgdat, &flags);
+					return ret;
+				}
+			}
+		}
+		pgdat_resize_unlock(pgdat, &flags);
+	}
+
+#ifdef CONFIG_X86_64
+	/*
+	 * for stack > 4G, we should MAC the stack in the kernel after switch,
+	 * for stack < 4G, the stack is MACed by tboot
+	 */
+	if (new_stack) {
+		for (i = 0, page = virt_to_page((void *)current_thread_info());
+			i < (1 << THREAD_ORDER);
+			i++, page++) {
+			sg_set_page(sg, page, PAGE_SIZE, 0);
+			ret = crypto_hash_update(&desc, sg, PAGE_SIZE);
+			if (ret)
+				return ret;
+		}
+	}
+#endif
+
+	ret = crypto_hash_final(&desc, (uint8_t *)mac);
+	if (ret)
+		return ret;
+
+	/* Clean the key */
+	memset(zeroed_key, 0, sizeof(zeroed_key));
+	crypto_hash_setkey(desc.tfm, zeroed_key, VMAC_KEY_LEN);
+
+	return 0;
+}
+
 #ifdef CONFIG_ACPI_SLEEP
 
 static void add_mac_region(phys_addr_t start, unsigned long size)
@@ -196,6 +355,27 @@ static int tboot_setup_sleep(void)
 
 	/* kernel code + data + bss */
 	add_mac_region(virt_to_phys(_text), _end - _text);
+
+	/* stack */
+#ifdef CONFIG_X86_64
+	/*
+	 * if stack > 4G, we should MAC the stack in the kernel after switch,
+	 * if stack < 4G, the stack is MACed by tboot
+	 */
+	if (new_stack)
+		add_mac_region(virt_to_phys(new_stack),
+				IRQ_STACK_SIZE); /* > 4G */
+	else
+#endif
+		add_mac_region(virt_to_phys(current_thread_info()),
+				THREAD_SIZE); /* < 4G */
+
+	/* MAC userspace memory not handled by tboot */
+	get_random_bytes(tboot->s3_key, sizeof(tboot->s3_key));
+	if (tboot_gen_mem_integrity(tboot->s3_key, &mem_mac)) {
+		panic("tboot: vmac generation failed\n");
+		return -1;
+	}
 
 	tboot->acpi_sinfo.kernel_s3_resume_vector = acpi_wakeup_address;
 
@@ -292,6 +472,52 @@ void tboot_sleep(u8 sleep_state, u32 pm1
 	}
 
 	tboot_shutdown(acpi_shutdown_map[sleep_state]);
+}
+
+static void tboot_sx_resume(void)
+{
+	vmac_t mac;
+
+	if (tboot_gen_mem_integrity(tboot->s3_key, &mac))
+		panic("tboot: vmac generation failed\n");
+	else if (mac != mem_mac)
+#ifdef CONFIG_DEBUG_KERNEL
+		pr_debug("tboot: memory integrity %llx -> %llx\n",
+				mem_mac, mac);
+#else
+		panic("tboot: memory integrity was lost on resume\n");
+#endif
+	else
+		pr_info("memory integrity OK\n");
+
+	/* Clean s3_key */
+	memset(tboot->s3_key, 0, sizeof(tboot->s3_key));
+}
+
+extern void do_suspend_lowlevel(void);
+
+static void tboot_do_suspend_lowlevel_call(void)
+{
+	do_suspend_lowlevel();
+	tboot_sx_resume();
+}
+
+void tboot_do_suspend_lowlevel(void)
+{
+	int ret = -1;
+
+	if (!tboot_enabled()) {
+		do_suspend_lowlevel();
+		return;
+	}
+
+	ret = tboot_pre_stack_switch();
+	if (!ret) {
+		tboot_switch_stack_call(tboot_do_suspend_lowlevel_call,
+					(u64)new_stack_ptr);
+		tboot_post_stack_switch();
+	} else
+		tboot_do_suspend_lowlevel_call();
 }
 
 static atomic_t ap_wfs_count;
diff -r c878d454dc8b drivers/acpi/sleep.c
--- a/drivers/acpi/sleep.c	Wed Dec 02 01:06:32 2009 -0800
+++ b/drivers/acpi/sleep.c	Thu Dec 03 07:22:17 2009 -0800
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/suspend.h>
 #include <linux/reboot.h>
+#include <linux/tboot.h>
 
 #include <asm/io.h>
 
@@ -244,7 +245,7 @@ static int acpi_suspend_enter(suspend_st
 		break;
 
 	case ACPI_STATE_S3:
-		do_suspend_lowlevel();
+		tboot_do_suspend_lowlevel();
 		break;
 	}
 
diff -r c878d454dc8b include/linux/mm.h
--- a/include/linux/mm.h	Wed Dec 02 01:06:32 2009 -0800
+++ b/include/linux/mm.h	Thu Dec 03 07:22:17 2009 -0800
@@ -1263,18 +1263,18 @@ static inline void enable_debug_pageallo
 {
 	debug_pagealloc_enabled = 1;
 }
-#ifdef CONFIG_HIBERNATION
+#if defined(CONFIG_HIBERNATION) || defined(CONFIG_INTEL_TXT)
 extern bool kernel_page_present(struct page *page);
-#endif /* CONFIG_HIBERNATION */
+#endif /* CONFIG_HIBERNATION || CONFIG_INTEL_TXT */
 #else
 static inline void
 kernel_map_pages(struct page *page, int numpages, int enable) {}
 static inline void enable_debug_pagealloc(void)
 {
 }
-#ifdef CONFIG_HIBERNATION
+#if defined(CONFIG_HIBERNATION) || defined(CONFIG_INTEL_TXT)
 static inline bool kernel_page_present(struct page *page) { return true; }
-#endif /* CONFIG_HIBERNATION */
+#endif /* CONFIG_HIBERNATION || CONFIG_INTEL_TXT */
 #endif
 
 extern struct vm_area_struct *get_gate_vma(struct task_struct *tsk);
diff -r c878d454dc8b include/linux/tboot.h
--- a/include/linux/tboot.h	Wed Dec 02 01:06:32 2009 -0800
+++ b/include/linux/tboot.h	Thu Dec 03 07:22:17 2009 -0800
@@ -147,7 +147,7 @@ extern struct acpi_table_header *tboot_g
 extern struct acpi_table_header *tboot_get_dmar_table(
 				      struct acpi_table_header *dmar_tbl);
 extern int tboot_force_iommu(void);
-
+extern void tboot_do_suspend_lowlevel(void);
 #else
 
 #define tboot_probe()			do { } while (0)
@@ -156,6 +156,7 @@ extern int tboot_force_iommu(void);
 					do { } while (0)
 #define tboot_get_dmar_table(dmar_tbl)	(dmar_tbl)
 #define tboot_force_iommu()		0
+#define tboot_do_suspend_lowlevel()	do_suspend_lowlevel()
 
 #endif /* !CONFIG_INTEL_TXT */
 
diff -r c878d454dc8b security/Kconfig
--- a/security/Kconfig	Wed Dec 02 01:06:32 2009 -0800
+++ b/security/Kconfig	Thu Dec 03 07:22:17 2009 -0800
@@ -116,6 +116,8 @@ config INTEL_TXT
 config INTEL_TXT
 	bool "Enable Intel(R) Trusted Execution Technology (Intel(R) TXT)"
 	depends on HAVE_INTEL_TXT
+	select CRYPTO_VMAC
+	select CRYPTO_AES
 	help
 	  This option enables support for booting the kernel with the
 	  Trusted Boot (tboot) module. This will utilize

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2010-03-19 21:19 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-09-01  8:52 [PATCH] intel_txt: fix the build errors of intel_txt patch on non-X86 platforms (resend) Shane Wang
2009-09-27  9:07 ` [PATCH] intel_txt: add s3 userspace memory integrity verification Shane Wang
2009-09-29  2:27   ` [PATCH] intel_txt: fix the buggy timeout warning logic in tboot Shane Wang
2009-10-04 18:58   ` [PATCH] intel_txt: add s3 userspace memory integrity verification Pavel Machek
2009-10-04 23:26     ` Andi Kleen
2009-10-15  7:57     ` Wang, Shane
2009-12-04  9:07     ` Wang, Shane
2009-12-04  8:19       ` Pavel Machek
2009-12-04 16:46         ` Cihula, Joseph
2009-12-04 17:13           ` Andi Kleen
2009-12-04 17:41             ` Cihula, Joseph
2009-12-04 20:09               ` Andi Kleen
2009-12-04 20:17                 ` Cihula, Joseph
2009-12-04 20:31                   ` Andi Kleen
2009-12-04 21:27                   ` H. Peter Anvin
2009-12-04 17:53             ` H. Peter Anvin
2009-12-04 20:10               ` Andi Kleen
2009-12-04 22:25               ` Pavel Machek
2009-12-04 22:15           ` Pavel Machek
2009-12-04 22:24             ` H. Peter Anvin
2009-12-04 22:39               ` Pavel Machek
2009-12-04 22:46                 ` H. Peter Anvin
2010-03-09  8:52     ` [PATCH v2] intel_txt: add support for S3 memory integrity protection within Intel(R) TXT launched kernel Wang, Shane
2010-03-09  9:06       ` Pavel Machek
2010-03-10  6:36       ` [PATCH v3] " Shane Wang
2010-03-10 20:31         ` Rafael J. Wysocki
2010-03-19 21:18         ` [tip:x86/txt] x86, tboot: Add support for S3 memory integrity protection tip-bot for Shane Wang
  -- strict thread matches above, loose matches on Subject: below --
2009-12-04  9:12 [PATCH] intel_txt: add s3 userspace memory integrity verification Shane Wang
2009-12-04  8:29 ` Pavel Machek
2009-12-04 16:52   ` Cihula, Joseph
2009-12-04 22:20     ` Pavel Machek
2009-12-04 11:05 ` Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).