[PATCH] txt: 4/6 - ACPI Generic Address Structure for tboot shutdown

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] txt: 4/6 - ACPI Generic Address Structure for tboot shutdown

Cihula, Joseph
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 <[hidden email]>
Signed-off-by: Joseph Cihula <[hidden email]>

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
[hidden email]
http://lists.xensource.com/xense-devel

xen-txt-04-acpi_gas_support.patch (10K) Download Attachment