mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Intel(R) Trusted Execution Technology (Intel(R) TXT) support for Xen.
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
This commit is contained in:
1 parent
cb9e907b6f
commit
ca560bd3f5
10 files changed
+250
-10
No files matched your search
@@ -46,6 +46,7 @@ obj-y += usercopy.o
|
||||
obj-y += x86_emulate.o
|
||||
obj-y += machine_kexec.o
|
||||
obj-y += crash.o
|
||||
obj-y += tboot.o
|
||||
|
||||
obj-$(crash_debug) += gdbstub.o
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <xen/domain.h>
|
||||
#include <xen/console.h>
|
||||
#include <public/platform.h>
|
||||
#include <asm/tboot.h>
|
||||
|
||||
#define pmprintk(_l, _f, _a...) printk(_l "<PM> " _f "\n", ## _a )
|
||||
|
||||
@@ -94,11 +95,19 @@ 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);
|
||||
{
|
||||
*(uint32_t *)wakeup_vector_va =
|
||||
tboot_in_measured_env() ?
|
||||
(uint32_t)g_tboot_shared->s3_tb_wakeup_entry :
|
||||
(uint32_t)bootsym_phys(wakeup_start);
|
||||
}
|
||||
else
|
||||
*(uint64_t *)wakeup_vector_va =
|
||||
(uint64_t)bootsym_phys(wakeup_start);
|
||||
{
|
||||
*(uint64_t *)wakeup_vector_va =
|
||||
tboot_in_measured_env() ?
|
||||
(uint64_t)g_tboot_shared->s3_tb_wakeup_entry :
|
||||
(uint64_t)bootsym_phys(wakeup_start);
|
||||
}
|
||||
}
|
||||
|
||||
static void acpi_sleep_post(u32 state) {}
|
||||
@@ -221,9 +230,43 @@ static int acpi_get_wake_status(void)
|
||||
return val;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
tboot_shutdown(shutdown_type);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
@@ -170,6 +170,12 @@ cmdline_parse_early:
|
||||
test %eax,%eax
|
||||
setnz bootsym_phys(skip_realmode)
|
||||
|
||||
/* Check for 'tboot=' command-line option. */
|
||||
movl $sym_phys(.Ltboot_opt),4(%esp)
|
||||
call .Lfind_option
|
||||
test %eax,%eax
|
||||
setnz bootsym_phys(skip_realmode) /* tboot= implies no-real-mode */
|
||||
|
||||
.Lparse_edd:
|
||||
/* Check for 'edd=' command-line option. */
|
||||
movl $sym_phys(.Ledd_opt),4(%esp)
|
||||
@@ -346,6 +352,8 @@ cmdline_parse_early:
|
||||
.asciz "current"
|
||||
.Lno_rm_opt:
|
||||
.asciz "no-real-mode"
|
||||
.Ltboot_opt:
|
||||
.asciz "tboot"
|
||||
.Ledid_opt:
|
||||
.asciz "edid"
|
||||
.Ledid_force:
|
||||
|
||||
@@ -990,14 +990,16 @@ int __init construct_dom0(
|
||||
rc |= iomem_deny_access(dom0, mfn, mfn);
|
||||
}
|
||||
|
||||
/* Remove access to E820_UNUSABLE I/O regions. */
|
||||
/* Remove access to E820_UNUSABLE I/O regions above 1MB. */
|
||||
for ( i = 0; i < e820.nr_map; i++ )
|
||||
{
|
||||
if ( e820.map[i].type != E820_UNUSABLE)
|
||||
continue;
|
||||
mfn = paddr_to_pfn(e820.map[i].addr);
|
||||
nr_pages = (e820.map[i].size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
rc |= iomem_deny_access(dom0, mfn, mfn + nr_pages - 1);
|
||||
unsigned long sfn, efn;
|
||||
sfn = max_t(unsigned long, paddr_to_pfn(e820.map[i].addr), 0x100ul);
|
||||
efn = paddr_to_pfn(e820.map[i].addr + e820.map[i].size - 1);
|
||||
if ( (e820.map[i].type == E820_UNUSABLE) &&
|
||||
(e820.map[i].size != 0) &&
|
||||
(sfn <= efn) )
|
||||
rc |= iomem_deny_access(dom0, sfn, efn);
|
||||
}
|
||||
|
||||
BUG_ON(rc != 0);
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <xen/kernel.h>
|
||||
#include <xen/keyhandler.h>
|
||||
#include <asm/shadow.h>
|
||||
#include <asm/tboot.h>
|
||||
|
||||
/* Dynamic (run-time adjusted) execution control flags. */
|
||||
u32 vmx_pin_based_exec_control __read_mostly;
|
||||
@@ -277,6 +278,13 @@ int vmx_cpu_up(void)
|
||||
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();
|
||||
|
||||
INIT_LIST_HEAD(&this_cpu(active_vmcs_list));
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <xen/kexec.h>
|
||||
#include <asm/edd.h>
|
||||
#include <xsm/xsm.h>
|
||||
#include <asm/tboot.h>
|
||||
|
||||
#if defined(CONFIG_X86_64)
|
||||
#define BOOTSTRAP_DIRECTMAP_END (1UL << 32) /* 4GB */
|
||||
@@ -846,6 +847,8 @@ void __init __start_xen(unsigned long mbi_p)
|
||||
|
||||
paging_init();
|
||||
|
||||
tboot_probe();
|
||||
|
||||
/* Unmap the first page of CPU0's stack. */
|
||||
memguard_guard_stack(cpu0_stack);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/tboot.h>
|
||||
|
||||
/* reboot_str: comma-separated list of reboot options. */
|
||||
static char __initdata reboot_str[10] = "";
|
||||
@@ -219,6 +220,9 @@ void machine_restart(void)
|
||||
|
||||
smp_send_stop();
|
||||
|
||||
if ( tboot_in_measured_env() )
|
||||
tboot_shutdown(TB_SHUTDOWN_REBOOT);
|
||||
|
||||
/* Rebooting needs to touch the page at absolute address 0. */
|
||||
*((unsigned short *)__va(0x472)) = reboot_mode;
|
||||
|
||||
@@ -328,3 +332,13 @@ 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:
|
||||
*/
|
||||
@@ -0,0 +1,70 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/types.h>
|
||||
#include <xen/lib.h>
|
||||
#include <xen/sched.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/tboot.h>
|
||||
|
||||
/* tboot=<physical address of shared page> */
|
||||
static char opt_tboot[20] = "";
|
||||
string_param("tboot", opt_tboot);
|
||||
|
||||
/* Global pointer to shared data; NULL means no measured launch. */
|
||||
tboot_shared_t *g_tboot_shared;
|
||||
|
||||
static const uuid_t tboot_shared_uuid = TBOOT_SHARED_UUID;
|
||||
|
||||
void __init tboot_probe(void)
|
||||
{
|
||||
tboot_shared_t *tboot_shared;
|
||||
unsigned long p_tboot_shared;
|
||||
|
||||
/* Look for valid page-aligned address for shared page. */
|
||||
p_tboot_shared = simple_strtoul(opt_tboot, NULL, 0);
|
||||
if ( (p_tboot_shared == 0) || ((p_tboot_shared & ~PAGE_MASK) != 0) )
|
||||
return;
|
||||
|
||||
/* Map and check for tboot UUID. */
|
||||
set_fixmap(FIX_TBOOT_SHARED_BASE, p_tboot_shared);
|
||||
tboot_shared = (tboot_shared_t *)fix_to_virt(FIX_TBOOT_SHARED_BASE);
|
||||
if ( memcmp(&tboot_shared_uuid, (uuid_t *)tboot_shared, sizeof(uuid_t)) )
|
||||
return;
|
||||
|
||||
g_tboot_shared = tboot_shared;
|
||||
printk("TBOOT: found shared page at phys addr %lx:\n", p_tboot_shared);
|
||||
printk(" version: %d\n", tboot_shared->version);
|
||||
printk(" log_addr: 0x%08x\n", tboot_shared->log_addr);
|
||||
printk(" shutdown_entry32: 0x%08x\n", tboot_shared->shutdown_entry32);
|
||||
printk(" shutdown_entry64: 0x%08x\n", tboot_shared->shutdown_entry64);
|
||||
printk(" shutdown_type: %d\n", tboot_shared->shutdown_type);
|
||||
printk(" s3_tb_wakeup_entry: 0x%08x\n", tboot_shared->s3_tb_wakeup_entry);
|
||||
printk(" s3_k_wakeup_entry: 0x%08x\n", tboot_shared->s3_k_wakeup_entry);
|
||||
printk(" &acpi_sinfo: 0x%p\n", &tboot_shared->acpi_sinfo);
|
||||
}
|
||||
|
||||
void tboot_shutdown(uint32_t shutdown_type)
|
||||
{
|
||||
g_tboot_shared->shutdown_type = 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__
|
||||
asm volatile ( "call *%%rdi" :: "D" (g_tboot_shared->shutdown_entry64) );
|
||||
#else
|
||||
asm volatile ( "call *%0" :: "r" (g_tboot_shared->shutdown_entry32) );
|
||||
#endif
|
||||
|
||||
BUG(); /* should not reach here */
|
||||
}
|
||||
|
||||
int tboot_in_measured_env(void)
|
||||
{
|
||||
return (g_tboot_shared != NULL);
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* tboot.h: shared data structure with MLE and kernel and functions
|
||||
* used by kernel for runtime support
|
||||
*
|
||||
* Copyright (c) 2006-2007, 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 __TBOOT_H__
|
||||
#define __TBOOT_H__
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) {
|
||||
uint32_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
uint16_t data4;
|
||||
uint8_t data5[6];
|
||||
} uuid_t;
|
||||
|
||||
/* used to communicate between tboot and the launched kernel (i.e. Xen) */
|
||||
#define MAX_TB_ACPI_SINFO_SIZE 64
|
||||
|
||||
typedef struct __attribute__ ((__packed__)) {
|
||||
uuid_t uuid; /* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */
|
||||
uint32_t version; /* 0x01 */
|
||||
uint32_t log_addr; /* physical addr of tb_log_t log */
|
||||
uint32_t shutdown_entry32; /* entry point for tboot shutdown from 32b */
|
||||
uint32_t shutdown_entry64; /* entry point for tboot shutdown from 64b */
|
||||
uint32_t shutdown_type; /* type of shutdown (TB_SHUTDOWN_*) */
|
||||
uint32_t s3_tb_wakeup_entry;/* entry point for tboot s3 wake up */
|
||||
uint32_t s3_k_wakeup_entry; /* entry point for xen s3 wake up */
|
||||
uint8_t acpi_sinfo[MAX_TB_ACPI_SINFO_SIZE];
|
||||
/* where kernel put acpi sleep info in Sx */
|
||||
} tboot_shared_t;
|
||||
|
||||
#define TB_SHUTDOWN_REBOOT 0
|
||||
#define TB_SHUTDOWN_S5 1
|
||||
#define TB_SHUTDOWN_S4 2
|
||||
#define TB_SHUTDOWN_S3 3
|
||||
#define TB_SHUTDOWN_HALT 4
|
||||
|
||||
/* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */
|
||||
#define TBOOT_SHARED_UUID { 0x663c8dff, 0xe8b3, 0x4b82, 0xaabf, \
|
||||
{ 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8 } };
|
||||
|
||||
extern tboot_shared_t *g_tboot_shared;
|
||||
|
||||
void tboot_probe(void);
|
||||
void tboot_shutdown(uint32_t shutdown_type);
|
||||
int tboot_in_measured_env(void);
|
||||
|
||||
#endif /* __TBOOT_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
* c-set-style: "BSD"
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||