# HG changeset patch # User Joseph Cihula # Date 1193445705 25200 # Node ID fa65033bc763209a1852d0807dba38fd264e3ce4 # Parent b28ae5f00553ea053bd4e4576634d8ea49e77bc3 Intel(R) Trusted Execution Technology (Intel(R) TXT) support for Xen Signed-off-by: Joseph Cihula diff -r b28ae5f00553 -r fa65033bc763 Makefile --- a/Makefile Tue Oct 23 09:26:43 2007 +0100 +++ b/Makefile Fri Oct 26 17:41:45 2007 -0700 @@ -19,10 +19,11 @@ endif # build and install everything into the standard system directories .PHONY: install -install: install-xen install-kernels install-tools install-docs +install: install-tboot install-xen install-kernels install-tools install-docs .PHONY: build -build: kernels +build: kernels download_tboot + $(MAKE) -C tboot build $(MAKE) -C xen build $(MAKE) -C tools build $(MAKE) -C docs build @@ -37,7 +38,7 @@ test: # build and install everything into local dist directory .PHONY: dist dist: DESTDIR=$(DISTDIR)/install -dist: dist-xen dist-kernels dist-tools dist-docs +dist: dist-tboot dist-xen dist-kernels dist-tools dist-docs $(INSTALL_DIR) $(DISTDIR)/check $(INSTALL_DATA) ./COPYING $(DISTDIR) $(INSTALL_DATA) ./README $(DISTDIR) @@ -48,15 +49,20 @@ dist-%: install-% @: # do nothing # Legacy dist targets -.PHONY: xen tools kernels docs +.PHONY: xen tools kernels docs tboot xen: dist-xen tools: dist-tools kernels: dist-kernels docs: dist-docs +tboot: dist-tboot .PHONY: prep-kernels prep-kernels: for i in $(XKERNELS) ; do $(MAKE) $$i-prep || exit 1; done + +.PHONY: install-tboot +install-tboot: download_tboot + $(MAKE) -C tboot install .PHONY: install-xen install-xen: @@ -103,10 +109,11 @@ world: # clean doesn't do a kclean .PHONY: clean -clean:: +clean:: $(MAKE) -C xen clean $(MAKE) -C tools clean $(MAKE) -C docs clean + [ ! -d tboot ] || $(MAKE) -C tboot clean # clean, but blow away kernel build tree plus tarballs .PHONY: distclean @@ -114,6 +121,7 @@ distclean: $(MAKE) -C xen distclean $(MAKE) -C tools distclean $(MAKE) -C docs distclean + [ ! -d tboot ] || $(MAKE) -C tboot distclean rm -rf dist patches/tmp for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done rm -rf patches/*/.makedep @@ -130,6 +138,7 @@ help: @echo ' install-tools - build and install the control tools' @echo ' install-kernels - build and install guest kernels' @echo ' install-docs - build and install user documentation' + @echo ' install-tboot - build and install the tboot module' @echo '' @echo 'Building targets:' @echo ' dist - build and install everything into local dist directory' @@ -141,6 +150,7 @@ help: @echo ' kbuild - synonym for make kernels' @echo ' docs - build and install user documentation' @echo ' dev-docs - build developer-only documentation' + @echo ' tboot - build and install tboot module' @echo '' @echo 'Cleaning targets:' @echo ' clean - clean the Xen, tools and docs (but not guest kernel trees)' @@ -194,8 +204,23 @@ uninstall: rm -rf $(D)/usr/share/xen rm -rf $(D)/usr/share/man/man1/xen* rm -rf $(D)/usr/share/man/man8/xen* + rm -rf $(D)/boot/tboot* # Legacy targets for compatibility .PHONY: linux26 linux26: $(MAKE) 'KERNELS=linux-2.6*' kernels + + +TBOOT_TARFILE = tboot-20071026.tar.gz +TBOOT_BASE_URL = http://downloads.sourceforge.net/tboot + +.PHONY: download_tboot +download_tboot: tboot/Makefile + +tboot/Makefile: tboot/$(TBOOT_TARFILE) + [ -e tboot/Makefile ] || tar -xzf tboot/$(TBOOT_TARFILE) -C tboot/ --strip-components 1 + +tboot/$(TBOOT_TARFILE): + mkdir -p tboot + wget -O tboot/$(TBOOT_TARFILE) $(TBOOT_BASE_URL)/$(TBOOT_TARFILE) diff -r b28ae5f00553 -r fa65033bc763 xen/arch/x86/acpi/power.c --- a/xen/arch/x86/acpi/power.c Tue Oct 23 09:26:43 2007 +0100 +++ b/xen/arch/x86/acpi/power.c Fri Oct 26 17:41:45 2007 -0700 @@ -10,6 +10,7 @@ * Slimmed with Xen specific support. */ +#include #include #include #include @@ -25,6 +26,9 @@ #include #include #include +#include + +extern void trap_in_tboot(uint32_t shutdown_type); #define pmprintk(_l, _f, _a...) printk(_l " " _f "\n", ## _a ) @@ -94,15 +98,48 @@ static void acpi_sleep_prepare(u32 state wakeup_vector_va = __acpi_map_table( acpi_sinfo.wakeup_vector, sizeof(uint64_t)); if ( acpi_sinfo.vector_width == 32 ) - *(uint32_t *)wakeup_vector_va = - (uint32_t)bootsym_phys(wakeup_start); + if ( tboot_in_measured_env() ) + *(uint32_t *)wakeup_vector_va = + (uint32_t)g_tboot_shared->s3_tb_wakeup_entry; + else + *(uint32_t *)wakeup_vector_va = + (uint32_t)bootsym_phys(wakeup_start); else - *(uint64_t *)wakeup_vector_va = - (uint64_t)bootsym_phys(wakeup_start); + if ( tboot_in_measured_env() ) + *(uint64_t *)wakeup_vector_va = + (uint64_t)g_tboot_shared->s3_tb_wakeup_entry; + else + *(uint64_t *)wakeup_vector_va = + (uint64_t)bootsym_phys(wakeup_start); } static void acpi_sleep_post(u32 state) {} +static inline void tboot_sleep(u8 sleep_state) +{ + uint32_t shutdown_type; + + *((struct acpi_sleep_info *)(unsigned long)g_tboot_shared->acpi_sinfo) = + acpi_sinfo; + + switch(sleep_state) { + case ACPI_STATE_S3: + shutdown_type = TB_SHUTDOWN_S3; + g_tboot_shared->s3_k_wakeup_entry = + (uint32_t)bootsym_phys(wakeup_start); + break; + case ACPI_STATE_S4: + shutdown_type = TB_SHUTDOWN_S4; + break; + case ACPI_STATE_S5: + shutdown_type = TB_SHUTDOWN_S5; + break; + default: + return; + } + trap_in_tboot(shutdown_type); +} + /* Main interface to do xen specific suspend/resume */ static int enter_state(u32 state) { @@ -220,6 +257,12 @@ static int acpi_get_wake_status(void) /* System is really put into sleep state by this stub */ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) { + if ( tboot_in_measured_env() ) { + tboot_sleep(sleep_state); + pmprintk(XENLOG_ERR, "TBOOT failed entering s3 state\n"); + return_ACPI_STATUS(AE_ERROR); + } + ACPI_FLUSH_CPU_CACHE(); outw((u16)acpi_sinfo.pm1a_cnt_val, acpi_sinfo.pm1a_cnt); diff -r b28ae5f00553 -r fa65033bc763 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Tue Oct 23 09:26:43 2007 +0100 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Oct 26 17:41:45 2007 -0700 @@ -16,6 +16,7 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. */ +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include /* Dynamic (run-time adjusted) execution control flags. */ u32 vmx_pin_based_exec_control __read_mostly; @@ -275,6 +277,12 @@ int vmx_cpu_up(void) IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX | IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_INSIDE_SMX); wrmsr(IA32_FEATURE_CONTROL_MSR, eax, 0); + } + + if ( !tboot_in_measured_env() && + !(eax & IA32_FEATURE_CONTROL_MSR_ENABLE_VMXON_OUTSIDE_SMX) ) { + printk("VMX only allowed in SMX but SMX not active\n"); + return 0; } vmx_init_vmcs_config(); diff -r b28ae5f00553 -r fa65033bc763 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Tue Oct 23 09:26:43 2007 +0100 +++ b/xen/arch/x86/setup.c Fri Oct 26 17:41:45 2007 -0700 @@ -1,3 +1,4 @@ +#include #include #include #include @@ -37,6 +38,10 @@ #include #include #include +#include + +/* global holding pointer to shared data; NULL means no measured launch */ +tboot_shared_t *g_tboot_shared = NULL; #if defined(CONFIG_X86_64) #define BOOTSTRAP_DIRECTMAP_END (1UL << 32) /* 4GB */ @@ -844,6 +849,45 @@ void __init __start_xen(unsigned long mb paging_init(); + /* look for tboot shared page: type is E820_RESERVED */ + /* and has {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} UUID */ + for ( i = 0; i < e820.nr_map; i++ ) + { + void *tboot_shared; + uint64_t addr; + static const uuid_t tboot_shared_uuid = TBOOT_SHARED_UUID; + + if ( e820.map[i].type != E820_RESERVED ) + continue; + + /* because Xen combines regions of same type, we need to check all */ + /* pages within region */ + for ( addr = e820.map[i].addr; + addr < (e820.map[i].addr + e820.map[i].size); + addr += PAGE_SIZE ) + { + /* check for TBOOT_SHARED uuid (need to fixmap to check) */ + set_fixmap(FIX_TBOOT_SHARED_BASE, addr); + tboot_shared = (void *)fix_to_virt(FIX_TBOOT_SHARED_BASE); + if ( memcmp(&tboot_shared_uuid, (uuid_t *)tboot_shared, + sizeof(uuid_t)) == 0 ) + { + /* found it, so make type E820_UNUSABLE to prevent */ + /* dom0 access */ + /* TBD: un-define when fix dom0 crash */ + /* e820.map[i].type = E820_UNUSABLE; */ + g_tboot_shared = tboot_shared; + printk("TBOOT: found shared page at phys addr " + "%Lx\n", (unsigned long long)addr); + printk("TBOOT: shared page fixmap-ed to %p:\n", + g_tboot_shared); + print_tboot_shared(g_tboot_shared); + goto found_shared_page; + } + } + } + + found_shared_page: /* Unmap the first page of CPU0's stack. */ memguard_guard_stack(cpu0_stack); diff -r b28ae5f00553 -r fa65033bc763 xen/arch/x86/shutdown.c --- a/xen/arch/x86/shutdown.c Tue Oct 23 09:26:43 2007 +0100 +++ b/xen/arch/x86/shutdown.c Fri Oct 26 17:41:45 2007 -0700 @@ -4,6 +4,7 @@ * x86-specific shutdown handling. */ +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include /* reboot_str: comma-separated list of reboot options. */ static char __initdata reboot_str[10] = ""; @@ -198,6 +200,37 @@ static void machine_real_restart(const u #endif +/* + * prepare the environment for running tboot including: + * setup page tabble to map both tboot and xen + */ +void trap_in_tboot(uint32_t shutdown_type) +{ + g_tboot_shared->shutdown_type = shutdown_type; + + printk("transfering control from xen to tboot:\n"); + printk("\t shutdown_type=%x\n", g_tboot_shared->shutdown_type); + + local_irq_disable(); + + /* create identity map for 0-640k to include tboot code */ + map_pages_to_xen(0, 0, PFN_UP(0xa0000), __PAGE_HYPERVISOR); + write_ptbase(idle_vcpu[0]); + +#ifdef __x86_64__ + printk("\t shutdown_entry64=0x%x\n", g_tboot_shared->shutdown_entry64); + __asm__ __volatile__ ( + "call *%%rdi" :: "D" (g_tboot_shared->shutdown_entry64) ); +#else + printk("\t shutdown_entry32=0x%x\n", g_tboot_shared->shutdown_entry32); + __asm__ __volatile__ ( + "call *%0" :: "r" (g_tboot_shared->shutdown_entry32) ); +#endif + + /* not reach here as no support return back to xen */ + printk("exit trap_in_tboot.\n"); +} + void machine_restart(void) { int i; @@ -210,6 +243,7 @@ void machine_restart(void) /* Ensure we are the boot CPU. */ if ( GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_physical_apicid ) { + printk("machine_teardown() not called on BSP\n"); /* Send IPI to the boot CPU (logical cpu 0). */ on_selected_cpus(cpumask_of_cpu(0), (void *)machine_restart, NULL, 1, 0); @@ -217,7 +251,16 @@ void machine_restart(void) halt(); } + printk("before smp_send_stop: num_online_cpus=%d\n", num_online_cpus()); smp_send_stop(); + printk("after smp_send_stop: num_online_cpus=%d\n", num_online_cpus()); + + /* if tboot launched us, let it exit measured environment properly */ + if ( tboot_in_measured_env() ) { + trap_in_tboot(TB_SHUTDOWN_REBOOT); + /* we should never return back here */ + printk("tboot_shutdown should never have returned\n"); + } /* Rebooting needs to touch the page at absolute address 0. */ *((unsigned short *)__va(0x472)) = reboot_mode; @@ -328,3 +371,15 @@ static int __init reboot_init(void) return 0; } __initcall(reboot_init); + + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff -r b28ae5f00553 -r fa65033bc763 xen/include/asm-x86/fixmap.h --- a/xen/include/asm-x86/fixmap.h Tue Oct 23 09:26:43 2007 +0100 +++ b/xen/include/asm-x86/fixmap.h Fri Oct 26 17:41:45 2007 -0700 @@ -46,6 +46,7 @@ enum fixed_addresses { FIX_IOMMU_REGS_END = FIX_IOMMU_REGS_BASE_0 + MAX_IOMMUS-1, FIX_IOMMU_MMIO_BASE_0, FIX_IOMMU_MMIO_END = FIX_IOMMU_MMIO_BASE_0 + IOMMU_PAGES -1, + FIX_TBOOT_SHARED_BASE, __end_of_fixed_addresses };