Cihula, Joseph
2009-Jan-20 05:49 UTC
[Xense-devel] [PATCH] txt: 4/6 - ACPI Generic Address Structure for tboot shutdown
New versions of tboot support ACPI GAS (Generic Address Structure) for handling sleep states. This required a change to the tboot_shared_t data structure that is not backwards compatible. This patch requires that new version makes use of GAS when invoking tboot on shutdown. Signed-off-by: Shane Wang <shane.wang@intel.com> Signed-off-by: Joseph Cihula <joseph.cihula@intel.com> diff -r a851239c01cb -r feb5e3c4a82d xen/arch/x86/acpi/power.c --- a/xen/arch/x86/acpi/power.c Fri Jan 16 13:43:15 2009 -0800 +++ b/xen/arch/x86/acpi/power.c Fri Jan 16 13:44:38 2009 -0800 @@ -276,39 +276,76 @@ static int acpi_get_wake_status(void) return val; } +static int verify_acpi_ptr(tboot_acpi_generic_address_t blk) +{ + struct page_info *pg; + struct domain *d; + uint64_t addr; + + if ( blk.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY ) + return -1; + + ACPI_MOVE_64_TO_64(&addr, &blk.address); + + if ( (addr >= bootsym_phys(trampoline_start)) + && (addr <= bootsym_phys(trampoline_end)) ) + { + gdprintk(XENLOG_ERR, "ACPI Pointer in trampoline code\n"); + return 0; + } + + pg = maddr_to_page(addr); + if ( is_xen_heap_page(pg) ) + { + gdprintk(XENLOG_ERR, "ACPI Pointer in Xen\n"); + return 0; + } + + d = maddr_get_owner(addr); + if ( d != NULL ) + { + gdprintk(XENLOG_ERR, "ACPI Pointer in Domain %u\n", d->domain_id); + return 0; + } + + return -1; +} + static void tboot_sleep(u8 sleep_state) { - uint32_t shutdown_type; + uint32_t shutdown_type; - g_tboot_shared->acpi_sinfo.pm1a_cnt - (uint16_t)acpi_sinfo.pm1a_cnt_blk.address; - g_tboot_shared->acpi_sinfo.pm1b_cnt - (uint16_t)acpi_sinfo.pm1b_cnt_blk.address; - g_tboot_shared->acpi_sinfo.pm1a_evt - (uint16_t)acpi_sinfo.pm1a_evt_blk.address; - g_tboot_shared->acpi_sinfo.pm1b_evt - (uint16_t)acpi_sinfo.pm1b_evt_blk.address; - g_tboot_shared->acpi_sinfo.pm1a_cnt_val = acpi_sinfo.pm1a_cnt_val; - g_tboot_shared->acpi_sinfo.pm1b_cnt_val = acpi_sinfo.pm1b_cnt_val; + /* Verify ACPI addresses */ + if ( !verify_acpi_ptr(acpi_sinfo.pm1a_cnt_blk) ) + return; + if ( !verify_acpi_ptr(acpi_sinfo.pm1b_cnt_blk) ) + return; + if ( !verify_acpi_ptr(acpi_sinfo.pm1a_evt_blk) ) + return; + if ( !verify_acpi_ptr(acpi_sinfo.pm1b_evt_blk) ) + return; - 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; - } + memcpy(&g_tboot_shared->acpi_sinfo, &acpi_sinfo, + sizeof(tboot_acpi_sleep_info)); - tboot_shutdown(shutdown_type); + 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 */ diff -r a851239c01cb -r feb5e3c4a82d xen/arch/x86/tboot.c --- a/xen/arch/x86/tboot.c Fri Jan 16 13:43:15 2009 -0800 +++ b/xen/arch/x86/tboot.c Fri Jan 16 13:44:38 2009 -0800 @@ -42,6 +42,12 @@ void __init tboot_probe(void) if ( memcmp(&tboot_shared_uuid, (uuid_t *)tboot_shared, sizeof(uuid_t)) ) return; + /* new tboot_shared (w/ GAS support) is not backwards compatible */ + if ( tboot_shared->version < 3 ) { + printk("unsupported version of tboot (%u)\n", tboot_shared->version); + 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); @@ -52,11 +58,8 @@ void __init tboot_probe(void) 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); - if ( tboot_shared->version >= 0x02 ) - { - printk(" tboot_base: 0x%08x\n", tboot_shared->tboot_base); - printk(" tboot_size: 0x%x\n", tboot_shared->tboot_size); - } + printk(" tboot_base: 0x%08x\n", tboot_shared->tboot_base); + printk(" tboot_size: 0x%x\n", tboot_shared->tboot_size); /* Get TXT heaps/SINIT/Private Space addresses. */ map_base = PFN_DOWN(TXT_PUB_CONFIG_REGS_BASE); @@ -98,16 +101,8 @@ void tboot_shutdown(uint32_t shutdown_ty local_irq_disable(); /* Create identity map for tboot shutdown code. */ - if ( g_tboot_shared->version >= 0x02 ) - { - map_base = PFN_DOWN(g_tboot_shared->tboot_base); - map_size = PFN_UP(g_tboot_shared->tboot_size); - } - else - { - map_base = 0; - map_size = PFN_UP(0xa0000); - } + map_base = PFN_DOWN(g_tboot_shared->tboot_base); + map_size = PFN_UP(g_tboot_shared->tboot_size); err = map_pages_to_xen(map_base << PAGE_SHIFT, map_base, map_size, __PAGE_HYPERVISOR); @@ -136,7 +131,7 @@ int tboot_in_measured_env(void) int tboot_in_range(paddr_t start, paddr_t end) { - if ( g_tboot_shared == NULL || g_tboot_shared->version < 0x02 ) + if ( !tboot_in_measured_env() ) return 0; start = max_t(paddr_t, start, g_tboot_shared->tboot_base); diff -r a851239c01cb -r feb5e3c4a82d xen/include/asm-x86/tboot.h --- a/xen/include/asm-x86/tboot.h Fri Jan 16 13:43:15 2009 -0800 +++ b/xen/include/asm-x86/tboot.h Fri Jan 16 13:44:38 2009 -0800 @@ -53,19 +53,21 @@ typedef struct __packed { /* used to communicate between tboot and the launched kernel (i.e. Xen) */ +typedef struct acpi_generic_address tboot_acpi_generic_address_t; + typedef struct __packed { - uint16_t pm1a_cnt; - uint16_t pm1b_cnt; - uint16_t pm1a_evt; - uint16_t pm1b_evt; + tboot_acpi_generic_address_t pm1a_cnt_blk; + tboot_acpi_generic_address_t pm1b_cnt_blk; + tboot_acpi_generic_address_t pm1a_evt_blk; + tboot_acpi_generic_address_t pm1b_evt_blk; uint16_t pm1a_cnt_val; uint16_t pm1b_cnt_val; } tboot_acpi_sleep_info; typedef struct __packed { - /* version 0x01+ fields: */ + /* version 3+ fields: */ uuid_t uuid; /* {663C8DFF-E8B3-4b82-AABF-19EA4D057A08} */ - uint32_t version; /* Version number: 0x01, 0x02, ... */ + uint32_t version; /* Version number; currently supports 0.3 */ 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 */ @@ -74,8 +76,6 @@ typedef struct __packed { uint32_t s3_k_wakeup_entry; /* entry point for xen s3 wake up */ tboot_acpi_sleep_info acpi_sinfo; /* where kernel put acpi sleep info in Sx */ - uint8_t reserved[52]; /* this pad is for compat with old field */ - /* version 0x02+ fields: */ uint32_t tboot_base; /* starting addr for tboot */ uint32_t tboot_size; /* size of tboot */ } tboot_shared_t; _______________________________________________ Xense-devel mailing list Xense-devel@lists.xensource.com http://lists.xensource.com/xense-devel