ia64/xen-unstable

changeset 12271:f95c943adbeb

[HVM] Fix 64-bit HVM domain creation.
1. vlapic must be initialised before VMX-specific init.
2. various shadow tweaks (e.g., check d->vcpu[0] before use).
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@localhost.localdomain
date Tue Nov 07 00:02:52 2006 +0000 (2006-11-07)
parents ad8f0e049d63
children 8f552314e45a
files xen/arch/x86/hvm/hvm.c xen/arch/x86/mm/shadow/common.c
line diff
     1.1 --- a/xen/arch/x86/hvm/hvm.c	Mon Nov 06 20:47:10 2006 +0000
     1.2 +++ b/xen/arch/x86/hvm/hvm.c	Tue Nov 07 00:02:52 2006 +0000
     1.3 @@ -157,12 +157,12 @@ int hvm_vcpu_initialise(struct vcpu *v)
     1.4      struct hvm_domain *platform;
     1.5      int rc;
     1.6  
     1.7 -    if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 )
     1.8 +    if ( (rc = vlapic_init(v)) != 0 )
     1.9          return rc;
    1.10  
    1.11 -    if ( (rc = vlapic_init(v)) != 0 )
    1.12 +    if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 )
    1.13      {
    1.14 -        hvm_funcs.vcpu_destroy(v);
    1.15 +        vlapic_destroy(v);
    1.16          return rc;
    1.17      }
    1.18  
     2.1 --- a/xen/arch/x86/mm/shadow/common.c	Mon Nov 06 20:47:10 2006 +0000
     2.2 +++ b/xen/arch/x86/mm/shadow/common.c	Tue Nov 07 00:02:52 2006 +0000
     2.3 @@ -578,6 +578,7 @@ void shadow_prealloc(struct domain *d, u
     2.4      v = current;
     2.5      if ( v->domain != d )
     2.6          v = d->vcpu[0];
     2.7 +    ASSERT(v != NULL);
     2.8  
     2.9      /* Stage one: walk the list of top-level pages, unpinning them */
    2.10      perfc_incrc(shadow_prealloc_1);
    2.11 @@ -941,9 +942,9 @@ p2m_next_level(struct domain *d, mfn_t *
    2.12          }
    2.13  #endif
    2.14          /* The P2M can be shadowed: keep the shadows synced */
    2.15 -        if ( d->vcpu[0] )
    2.16 +        if ( d->vcpu[0] != NULL )
    2.17              (void)__shadow_validate_guest_entry(d->vcpu[0], *table_mfn,
    2.18 -                                                 p2m_entry, sizeof *p2m_entry);
    2.19 +                                                p2m_entry, sizeof *p2m_entry);
    2.20      }
    2.21      *table_mfn = _mfn(l1e_get_pfn(*p2m_entry));
    2.22      next = sh_map_domain_page(*table_mfn);
    2.23 @@ -997,8 +998,9 @@ shadow_set_p2m_entry(struct domain *d, u
    2.24          *p2m_entry = l1e_empty();
    2.25  
    2.26      /* The P2M can be shadowed: keep the shadows synced */
    2.27 -    (void) __shadow_validate_guest_entry(d->vcpu[0], table_mfn, 
    2.28 -                                          p2m_entry, sizeof *p2m_entry);
    2.29 +    if ( d->vcpu[0] != NULL )
    2.30 +        (void)__shadow_validate_guest_entry(
    2.31 +            d->vcpu[0], table_mfn, p2m_entry, sizeof(*p2m_entry));
    2.32  
    2.33      sh_unmap_domain_page(table);
    2.34  
    2.35 @@ -1015,9 +1017,11 @@ shadow_set_p2m_entry(struct domain *d, u
    2.36  static int
    2.37  shadow_alloc_p2m_table(struct domain *d)
    2.38  {
    2.39 -    mfn_t p2m_top;
    2.40 +    mfn_t p2m_top, mfn;
    2.41      struct list_head *entry;
    2.42 +    struct page_info *page;
    2.43      unsigned int page_count = 0;
    2.44 +    unsigned long gfn;
    2.45      
    2.46      SHADOW_PRINTK("allocating p2m table\n");
    2.47      ASSERT(pagetable_get_pfn(d->arch.phys_table) == 0);
    2.48 @@ -1041,13 +1045,19 @@ shadow_alloc_p2m_table(struct domain *d)
    2.49  
    2.50      SHADOW_PRINTK("populating p2m table\n");
    2.51   
    2.52 +    /* Initialise physmap tables for slot zero. Other code assumes this. */
    2.53 +    gfn = 0;
    2.54 +    mfn = _mfn(INVALID_MFN);
    2.55 +    if ( !shadow_set_p2m_entry(d, gfn, mfn) )
    2.56 +        goto error;
    2.57 +
    2.58      for ( entry = d->page_list.next;
    2.59            entry != &d->page_list;
    2.60            entry = entry->next )
    2.61      {
    2.62 -        struct page_info *page = list_entry(entry, struct page_info, list);
    2.63 -        mfn_t mfn = page_to_mfn(page);
    2.64 -        unsigned long gfn = get_gpfn_from_mfn(mfn_x(mfn));
    2.65 +        page = list_entry(entry, struct page_info, list);
    2.66 +        mfn = page_to_mfn(page);
    2.67 +        gfn = get_gpfn_from_mfn(mfn_x(mfn));
    2.68          page_count++;
    2.69          if (
    2.70  #ifdef __x86_64__
    2.71 @@ -1057,15 +1067,16 @@ shadow_alloc_p2m_table(struct domain *d)
    2.72  #endif
    2.73               && gfn != INVALID_M2P_ENTRY
    2.74               && !shadow_set_p2m_entry(d, gfn, mfn) )
    2.75 -        {
    2.76 -            SHADOW_PRINTK("failed to initialize p2m table, gfn=%05lx, mfn=%" SH_PRI_mfn "\n",
    2.77 -                           gfn, mfn_x(mfn));
    2.78 -            return 0;
    2.79 -        }
    2.80 +            goto error;
    2.81      }
    2.82  
    2.83      SHADOW_PRINTK("p2m table initialised (%u pages)\n", page_count);
    2.84      return 1;
    2.85 +
    2.86 + error:
    2.87 +    SHADOW_PRINTK("failed to initialize p2m table, gfn=%05lx, mfn=%"
    2.88 +                  SH_PRI_mfn "\n", gfn, mfn_x(mfn));
    2.89 +    return 0;
    2.90  }
    2.91  
    2.92  mfn_t
    2.93 @@ -2837,15 +2848,18 @@ sh_p2m_remove_page(struct domain *d, uns
    2.94      if ( v->domain != d )
    2.95          v = d->vcpu[0];
    2.96  
    2.97 -
    2.98      SHADOW_DEBUG(P2M, "removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
    2.99  
   2.100      ASSERT(mfn_x(sh_gfn_to_mfn(d, gfn)) == mfn);
   2.101      //ASSERT(sh_mfn_to_gfn(d, mfn) == gfn);
   2.102  
   2.103 -    shadow_remove_all_shadows_and_parents(v, _mfn(mfn));
   2.104 -    if ( shadow_remove_all_mappings(v, _mfn(mfn)) )
   2.105 -        flush_tlb_mask(d->domain_dirty_cpumask);
   2.106 +    if ( v != NULL )
   2.107 +    {
   2.108 +        shadow_remove_all_shadows_and_parents(v, _mfn(mfn));
   2.109 +        if ( shadow_remove_all_mappings(v, _mfn(mfn)) )
   2.110 +            flush_tlb_mask(d->domain_dirty_cpumask);
   2.111 +    }
   2.112 +
   2.113      shadow_set_p2m_entry(d, gfn, _mfn(INVALID_MFN));
   2.114      set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
   2.115  }
   2.116 @@ -2865,17 +2879,12 @@ void
   2.117  shadow_guest_physmap_add_page(struct domain *d, unsigned long gfn,
   2.118                                 unsigned long mfn)
   2.119  {
   2.120 -    struct vcpu *v;
   2.121      unsigned long ogfn;
   2.122      mfn_t omfn;
   2.123  
   2.124      if ( !shadow_mode_translate(d) )
   2.125          return;
   2.126  
   2.127 -    v = current;
   2.128 -    if ( v->domain != d )
   2.129 -        v = d->vcpu[0];
   2.130 -
   2.131      shadow_lock(d);
   2.132      shadow_audit_p2m(d);
   2.133  
   2.134 @@ -2885,11 +2894,17 @@ shadow_guest_physmap_add_page(struct dom
   2.135      if ( valid_mfn(omfn) )
   2.136      {
   2.137          /* Get rid of the old mapping, especially any shadows */
   2.138 -        shadow_remove_all_shadows_and_parents(v, omfn);
   2.139 -        if ( shadow_remove_all_mappings(v, omfn) )
   2.140 -            flush_tlb_mask(d->domain_dirty_cpumask);
   2.141 +        struct vcpu *v = current;
   2.142 +        if ( v->domain != d )
   2.143 +            v = d->vcpu[0];
   2.144 +        if ( v != NULL )
   2.145 +        {
   2.146 +            shadow_remove_all_shadows_and_parents(v, omfn);
   2.147 +            if ( shadow_remove_all_mappings(v, omfn) )
   2.148 +                flush_tlb_mask(d->domain_dirty_cpumask);
   2.149 +        }
   2.150          set_gpfn_from_mfn(mfn_x(omfn), INVALID_M2P_ENTRY);
   2.151 -    }        
   2.152 +    }
   2.153  
   2.154      ogfn = sh_mfn_to_gfn(d, _mfn(mfn));
   2.155      if (
   2.156 @@ -2961,7 +2976,8 @@ static int shadow_log_dirty_op(
   2.157          list_for_each_safe(l, t, &d->arch.shadow.toplevel_shadows)
   2.158          {
   2.159              pg = list_entry(l, struct page_info, list);
   2.160 -            shadow_unhook_mappings(d->vcpu[0], page_to_mfn(pg));
   2.161 +            if ( d->vcpu[0] != NULL )
   2.162 +                shadow_unhook_mappings(d->vcpu[0], page_to_mfn(pg));
   2.163          }
   2.164  
   2.165          d->arch.shadow.fault_count = 0;