ia64/xen-unstable

changeset 19116:202afa5384c4

tboot: tboot no longer marks TXT regions as E820_UNUSABLE, so Xen must
explicitly disallow them itself.

Signed-off-by: Shane Wang <shane.wang@intel.com>
Signed-off-by: Joseph Cihula <joseph.cihula@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jan 29 12:10:39 2009 +0000 (2009-01-29)
parents 378a85ff1260
children 31798b19f25c
files xen/arch/x86/e820.c xen/arch/x86/setup.c xen/arch/x86/tboot.c xen/include/asm-x86/e820.h xen/include/asm-x86/tboot.h
line diff
     1.1 --- a/xen/arch/x86/e820.c	Thu Jan 29 11:36:09 2009 +0000
     1.2 +++ b/xen/arch/x86/e820.c	Thu Jan 29 12:10:39 2009 +0000
     1.3 @@ -391,8 +391,9 @@ static void __init machine_specific_memo
     1.4      reserve_dmi_region();
     1.5  }
     1.6  
     1.7 -/* Reserve RAM area (@s,@e) in the specified e820 map. */
     1.8 -int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
     1.9 +int __init e820_change_range_type(
    1.10 +    struct e820map *e820, uint64_t s, uint64_t e,
    1.11 +    uint32_t orig_type, uint32_t new_type)
    1.12  {
    1.13      uint64_t rs = 0, re = 0;
    1.14      int i;
    1.15 @@ -406,55 +407,79 @@ int __init reserve_e820_ram(struct e820m
    1.16              break;
    1.17      }
    1.18  
    1.19 -    if ( (i == e820->nr_map) || (e820->map[i].type != E820_RAM) )
    1.20 +    if ( (i == e820->nr_map) || (e820->map[i].type != orig_type) )
    1.21          return 0;
    1.22  
    1.23      if ( (s == rs) && (e == re) )
    1.24      {
    1.25 -        /* Complete excision. */
    1.26 -        memmove(&e820->map[i], &e820->map[i+1],
    1.27 -                (e820->nr_map-i-1) * sizeof(e820->map[0]));
    1.28 -        e820->nr_map--;
    1.29 +        e820->map[i].type = new_type;
    1.30      }
    1.31 -    else if ( s == rs )
    1.32 +    else if ( (s == rs) || (e == re) )
    1.33      {
    1.34 -        /* Truncate start. */
    1.35 -        e820->map[i].addr += e - s;
    1.36 -        e820->map[i].size -= e - s;
    1.37 -    }
    1.38 -    else if ( e == re )
    1.39 -    {
    1.40 -        /* Truncate end. */
    1.41 -        e820->map[i].size -= e - s;
    1.42 -    }
    1.43 -    else if ( e820->nr_map < ARRAY_SIZE(e820->map) )
    1.44 -    {
    1.45 -        /* Split in two. */
    1.46 +        if ( (e820->nr_map + 1) > ARRAY_SIZE(e820->map) )
    1.47 +            goto overflow;
    1.48 +
    1.49          memmove(&e820->map[i+1], &e820->map[i],
    1.50                  (e820->nr_map-i) * sizeof(e820->map[0]));
    1.51          e820->nr_map++;
    1.52 -        e820->map[i].size = s - rs;
    1.53 -        i++;
    1.54 -        e820->map[i].addr = e;
    1.55 -        e820->map[i].size = re - e;
    1.56 -    }
    1.57 -    else
    1.58 -    {
    1.59 -        /* e820map is at maximum size. We have to leak some space. */
    1.60 -        if ( (s - rs) > (re - e) )
    1.61 +
    1.62 +        if ( s == rs )
    1.63          {
    1.64 -            printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", e, re);
    1.65 -            e820->map[i].size = s - rs;
    1.66 +            e820->map[i].size = e - s;
    1.67 +            e820->map[i].type = new_type;
    1.68 +            e820->map[i+1].addr = e;
    1.69 +            e820->map[i+1].size = re - e;
    1.70          }
    1.71          else
    1.72          {
    1.73 -            printk("e820 overflow: leaking RAM %"PRIx64"-%"PRIx64"\n", rs, s);
    1.74 -            e820->map[i].addr = e;
    1.75 -            e820->map[i].size = re - e;
    1.76 +            e820->map[i].size = s - rs;
    1.77 +            e820->map[i+1].addr = s;
    1.78 +            e820->map[i+1].size = e - s;
    1.79 +            e820->map[i+1].type = new_type;
    1.80          }
    1.81      }
    1.82 +    else if ( e820->nr_map+1 < ARRAY_SIZE(e820->map) )
    1.83 +    {
    1.84 +        if ( (e820->nr_map + 2) > ARRAY_SIZE(e820->map) )
    1.85 +            goto overflow;
    1.86 +
    1.87 +        memmove(&e820->map[i+2], &e820->map[i],
    1.88 +                (e820->nr_map-i) * sizeof(e820->map[0]));
    1.89 +        e820->nr_map += 2;
    1.90 +
    1.91 +        e820->map[i].size = s - rs;
    1.92 +        e820->map[i+1].addr = s;
    1.93 +        e820->map[i+1].size = e - s;
    1.94 +        e820->map[i+1].type = new_type;
    1.95 +        e820->map[i+2].addr = e;
    1.96 +        e820->map[i+2].size = re - e;
    1.97 +    }
    1.98 +
    1.99 +    /* Finally, look for any opportunities to merge adjacent e820 entries. */
   1.100 +    for ( i = 0; i < (e820->nr_map - 1); i++ )
   1.101 +    {
   1.102 +        if ( (e820->map[i].type != e820->map[i+1].type) ||
   1.103 +             ((e820->map[i].addr + e820->map[i].size) != e820->map[i+1].addr) )
   1.104 +            continue;
   1.105 +        e820->map[i].size += e820->map[i+1].size;
   1.106 +        memmove(&e820->map[i+1], &e820->map[i+2],
   1.107 +                (e820->nr_map-i-2) * sizeof(e820->map[0]));
   1.108 +        e820->nr_map--;
   1.109 +        i--;
   1.110 +    }
   1.111  
   1.112      return 1;
   1.113 +
   1.114 + overflow:
   1.115 +    printk("Overflow in e820 while reserving region %"PRIx64"-%"PRIx64"\n",
   1.116 +           s, e);
   1.117 +    return 0;
   1.118 +}
   1.119 +
   1.120 +/* Set E820_RAM area (@s,@e) as RESERVED in specified e820 map. */
   1.121 +int __init reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e)
   1.122 +{
   1.123 +    return e820_change_range_type(e820, s, e, E820_RAM, E820_RESERVED);
   1.124  }
   1.125  
   1.126  unsigned long __init init_e820(
     2.1 --- a/xen/arch/x86/setup.c	Thu Jan 29 11:36:09 2009 +0000
     2.2 +++ b/xen/arch/x86/setup.c	Thu Jan 29 12:10:39 2009 +0000
     2.3 @@ -1035,6 +1035,9 @@ void __init __start_xen(unsigned long mb
     2.4      if ( xen_cpuidle )
     2.5          xen_processor_pmbits |= XEN_PROCESSOR_PM_CX;
     2.6  
     2.7 +    if ( !tboot_protect_mem_regions() )
     2.8 +        panic("Could not protect TXT memory regions\n");
     2.9 +
    2.10      /*
    2.11       * We're going to setup domain0 using the module(s) that we stashed safely
    2.12       * above our heap. The second module, if present, is an initrd ramdisk.
     3.1 --- a/xen/arch/x86/tboot.c	Thu Jan 29 11:36:09 2009 +0000
     3.2 +++ b/xen/arch/x86/tboot.c	Thu Jan 29 12:10:39 2009 +0000
     3.3 @@ -6,6 +6,7 @@
     3.4  #include <asm/fixmap.h>
     3.5  #include <asm/page.h>
     3.6  #include <asm/processor.h>
     3.7 +#include <asm/e820.h>
     3.8  #include <asm/tboot.h>
     3.9  
    3.10  /* tboot=<physical address of shared page> */
    3.11 @@ -17,6 +18,23 @@ tboot_shared_t *g_tboot_shared;
    3.12  
    3.13  static const uuid_t tboot_shared_uuid = TBOOT_SHARED_UUID;
    3.14  
    3.15 +/*
    3.16 + * TXT configuration registers (offsets from TXT_{PUB, PRIV}_CONFIG_REGS_BASE)
    3.17 + */
    3.18 +
    3.19 +#define TXT_PUB_CONFIG_REGS_BASE       0xfed30000
    3.20 +#define TXT_PRIV_CONFIG_REGS_BASE      0xfed20000
    3.21 +
    3.22 +/* # pages for each config regs space - used by fixmap */
    3.23 +#define NR_TXT_CONFIG_PAGES     ((TXT_PUB_CONFIG_REGS_BASE -                \
    3.24 +                                  TXT_PRIV_CONFIG_REGS_BASE) >> PAGE_SHIFT)
    3.25 +
    3.26 +/* offsets from pub/priv config space */
    3.27 +#define TXTCR_SINIT_BASE            0x0270
    3.28 +#define TXTCR_SINIT_SIZE            0x0278
    3.29 +#define TXTCR_HEAP_BASE             0x0300
    3.30 +#define TXTCR_HEAP_SIZE             0x0308
    3.31 +
    3.32  extern char __init_begin[], __per_cpu_start[], __per_cpu_end[], __bss_start[];
    3.33  
    3.34  void __init tboot_probe(void)
    3.35 @@ -105,6 +123,53 @@ int tboot_in_measured_env(void)
    3.36      return (g_tboot_shared != NULL);
    3.37  }
    3.38  
    3.39 +int __init tboot_protect_mem_regions(void)
    3.40 +{
    3.41 +    uint64_t base, size;
    3.42 +    uint32_t map_base, map_size;
    3.43 +    unsigned long map_addr;
    3.44 +    int rc;
    3.45 +
    3.46 +    if ( !tboot_in_measured_env() )
    3.47 +        return 1;
    3.48 +
    3.49 +    map_base = PFN_DOWN(TXT_PUB_CONFIG_REGS_BASE);
    3.50 +    map_size = PFN_UP(NR_TXT_CONFIG_PAGES * PAGE_SIZE);
    3.51 +    map_addr = (unsigned long)__va(map_base << PAGE_SHIFT);
    3.52 +    if ( map_pages_to_xen(map_addr, map_base, map_size, __PAGE_HYPERVISOR) )
    3.53 +        return 0;
    3.54 +
    3.55 +    /* TXT Heap */
    3.56 +    base = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_BASE);
    3.57 +    size = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_HEAP_SIZE);
    3.58 +    rc = e820_change_range_type(
    3.59 +        &e820, base, base + size, E820_RESERVED, E820_UNUSABLE);
    3.60 +    if ( !rc )
    3.61 +        return 0;
    3.62 +
    3.63 +    /* SINIT */
    3.64 +    base = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_BASE);
    3.65 +    size = *(uint64_t *)__va(TXT_PUB_CONFIG_REGS_BASE + TXTCR_SINIT_SIZE);
    3.66 +    rc = e820_change_range_type(
    3.67 +        &e820, base, base + size, E820_RESERVED, E820_UNUSABLE);
    3.68 +    if ( !rc )
    3.69 +        return 0;
    3.70 +
    3.71 +    /* TXT Private Space */
    3.72 +    rc = e820_change_range_type(
    3.73 +        &e820, TXT_PRIV_CONFIG_REGS_BASE,
    3.74 +        TXT_PRIV_CONFIG_REGS_BASE + NR_TXT_CONFIG_PAGES * PAGE_SIZE,
    3.75 +        E820_RESERVED, E820_UNUSABLE);
    3.76 +    if ( !rc )
    3.77 +        return 0;
    3.78 +
    3.79 +    destroy_xen_mappings(
    3.80 +        (unsigned long)__va(map_base << PAGE_SHIFT),
    3.81 +        (unsigned long)__va((map_base + map_size) << PAGE_SHIFT));
    3.82 +
    3.83 +    return 1;
    3.84 +}
    3.85 +
    3.86  /*
    3.87   * Local variables:
    3.88   * mode: C
     4.1 --- a/xen/include/asm-x86/e820.h	Thu Jan 29 11:36:09 2009 +0000
     4.2 +++ b/xen/include/asm-x86/e820.h	Thu Jan 29 12:10:39 2009 +0000
     4.3 @@ -24,6 +24,9 @@ struct e820map {
     4.4  };
     4.5  
     4.6  extern int reserve_e820_ram(struct e820map *e820, uint64_t s, uint64_t e);
     4.7 +extern int e820_change_range_type(
     4.8 +    struct e820map *e820, uint64_t s, uint64_t e,
     4.9 +    uint32_t orig_type, uint32_t new_type);
    4.10  extern unsigned long init_e820(const char *, struct e820entry *, int *);
    4.11  extern struct e820map e820;
    4.12  
     5.1 --- a/xen/include/asm-x86/tboot.h	Thu Jan 29 11:36:09 2009 +0000
     5.2 +++ b/xen/include/asm-x86/tboot.h	Thu Jan 29 12:10:39 2009 +0000
     5.3 @@ -109,6 +109,7 @@ extern tboot_shared_t *g_tboot_shared;
     5.4  void tboot_probe(void);
     5.5  void tboot_shutdown(uint32_t shutdown_type);
     5.6  int tboot_in_measured_env(void);
     5.7 +int tboot_protect_mem_regions(void);
     5.8  
     5.9  #endif /* __TBOOT_H__ */
    5.10