direct-io.hg

changeset 14689:f0f9533b2a23

hvm hap: P2M page table cleanup and bug fix.

Force P2M top-level page table to be allocated below 4GB
memory space when Xen is running under PAE mode. Also remove
hap.p2m_freelists because hap mode does not have P2M batch
allocation. The backpointer parameter of hap_alloc() function is
removed since this parameter is unused.

Signed-off-by: Wei Huang <wei.huang2@amd.com>
author kfraser@localhost.localdomain
date Mon Apr 02 13:05:59 2007 +0100 (2007-04-02)
parents 149943a5d2c8
children 598d55e3ff2f
files xen/arch/x86/mm/hap/hap.c xen/include/asm-x86/domain.h
line diff
     1.1 --- a/xen/arch/x86/mm/hap/hap.c	Mon Apr 02 11:50:06 2007 +0100
     1.2 +++ b/xen/arch/x86/mm/hap/hap.c	Mon Apr 02 13:05:59 2007 +0100
     1.3 @@ -52,7 +52,7 @@
     1.4  /************************************************/
     1.5  /*             HAP SUPPORT FUNCTIONS            */
     1.6  /************************************************/
     1.7 -mfn_t hap_alloc(struct domain *d, unsigned long backpointer)
     1.8 +mfn_t hap_alloc(struct domain *d)
     1.9  {
    1.10      struct page_info *sp = NULL;
    1.11      void *p;
    1.12 @@ -82,43 +82,43 @@ void hap_free(struct domain *d, mfn_t sm
    1.13      list_add_tail(&sp->list, &d->arch.paging.hap.freelists);
    1.14  }
    1.15  
    1.16 -static int hap_alloc_p2m_pages(struct domain *d)
    1.17 -{
    1.18 -    struct page_info *pg;
    1.19 -
    1.20 -    ASSERT(hap_locked_by_me(d));
    1.21 -
    1.22 -    pg = mfn_to_page(hap_alloc(d, 0));
    1.23 -    d->arch.paging.hap.p2m_pages += 1;
    1.24 -    d->arch.paging.hap.total_pages -= 1;
    1.25 -    
    1.26 -    page_set_owner(pg, d);
    1.27 -    pg->count_info = 1;
    1.28 -    list_add_tail(&pg->list, &d->arch.paging.hap.p2m_freelist);
    1.29 -
    1.30 -    return 1;
    1.31 -}
    1.32 -
    1.33  struct page_info * hap_alloc_p2m_page(struct domain *d)
    1.34  {
    1.35 -    struct list_head *entry;
    1.36      struct page_info *pg;
    1.37      mfn_t mfn;
    1.38      void *p;
    1.39  
    1.40      hap_lock(d);
    1.41 -    
    1.42 -    if ( list_empty(&d->arch.paging.hap.p2m_freelist) && 
    1.43 -         !hap_alloc_p2m_pages(d) ) {
    1.44 -        hap_unlock(d);
    1.45 -        return NULL;
    1.46 +
    1.47 +#if CONFIG_PAGING_LEVELS == 3
    1.48 +    /* Under PAE mode, top-level P2M table should be allocated below 4GB space
    1.49 +     * because the size of h_cr3 is only 32-bit. We use alloc_domheap_pages to 
    1.50 +     * force this requirement. This page will be de-allocated in 
    1.51 +     * hap_free_p2m_page(), like other P2M pages.
    1.52 +    */
    1.53 +    if ( d->arch.paging.hap.p2m_pages == 0 ) 
    1.54 +    {
    1.55 +	pg = alloc_domheap_pages(NULL, 0, MEMF_bits(32));
    1.56 +	d->arch.paging.hap.p2m_pages += 1;
    1.57      }
    1.58 -    entry = d->arch.paging.hap.p2m_freelist.next;
    1.59 -    list_del(entry);
    1.60 -    
    1.61 +    else
    1.62 +#endif
    1.63 +    {
    1.64 +	pg = mfn_to_page(hap_alloc(d));
    1.65 +	
    1.66 +	d->arch.paging.hap.p2m_pages += 1;
    1.67 +	d->arch.paging.hap.total_pages -= 1;
    1.68 +    }	
    1.69 +
    1.70 +    if ( pg == NULL ) {
    1.71 +	hap_unlock(d);
    1.72 +	return NULL;
    1.73 +    }   
    1.74 +
    1.75      hap_unlock(d);
    1.76  
    1.77 -    pg = list_entry(entry, struct page_info, list);
    1.78 +    page_set_owner(pg, d);
    1.79 +    pg->count_info = 1;
    1.80      mfn = page_to_mfn(pg);
    1.81      p = hap_map_domain_page(mfn);
    1.82      clear_page(p);
    1.83 @@ -141,6 +141,7 @@ void hap_free_p2m_page(struct domain *d,
    1.84      page_set_owner(pg, NULL); 
    1.85      free_domheap_pages(pg, 0);
    1.86      d->arch.paging.hap.p2m_pages--;
    1.87 +    ASSERT( d->arch.paging.hap.p2m_pages >= 0 );
    1.88  }
    1.89  
    1.90  /* Return the size of the pool, rounded up to the nearest MB */
    1.91 @@ -320,7 +321,7 @@ mfn_t hap_make_monitor_table(struct vcpu
    1.92  #if CONFIG_PAGING_LEVELS == 4
    1.93      {
    1.94          mfn_t m4mfn;
    1.95 -        m4mfn = hap_alloc(d, 0);
    1.96 +        m4mfn = hap_alloc(d);
    1.97          hap_install_xen_entries_in_l4(v, m4mfn, m4mfn);
    1.98          return m4mfn;
    1.99      }
   1.100 @@ -331,12 +332,12 @@ mfn_t hap_make_monitor_table(struct vcpu
   1.101          l2_pgentry_t *l2e;
   1.102          int i;
   1.103  
   1.104 -        m3mfn = hap_alloc(d, 0);
   1.105 +        m3mfn = hap_alloc(d);
   1.106  
   1.107          /* Install a monitor l2 table in slot 3 of the l3 table.
   1.108           * This is used for all Xen entries, including linear maps
   1.109           */
   1.110 -        m2mfn = hap_alloc(d, 0);
   1.111 +        m2mfn = hap_alloc(d);
   1.112          l3e = hap_map_domain_page(m3mfn);
   1.113          l3e[3] = l3e_from_pfn(mfn_x(m2mfn), _PAGE_PRESENT);
   1.114          hap_install_xen_entries_in_l2h(v, m2mfn);
   1.115 @@ -357,7 +358,7 @@ mfn_t hap_make_monitor_table(struct vcpu
   1.116      {
   1.117          mfn_t m2mfn;
   1.118          
   1.119 -        m2mfn = hap_alloc(d, 0);
   1.120 +        m2mfn = hap_alloc(d);
   1.121          hap_install_xen_entries_in_l2(v, m2mfn, m2mfn);
   1.122      
   1.123          return m2mfn;
   1.124 @@ -390,7 +391,6 @@ void hap_domain_init(struct domain *d)
   1.125  {
   1.126      hap_lock_init(d);
   1.127      INIT_LIST_HEAD(&d->arch.paging.hap.freelists);
   1.128 -    INIT_LIST_HEAD(&d->arch.paging.hap.p2m_freelist);
   1.129  }
   1.130  
   1.131  /* return 0 for success, -errno for failure */
     2.1 --- a/xen/include/asm-x86/domain.h	Mon Apr 02 11:50:06 2007 +0100
     2.2 +++ b/xen/include/asm-x86/domain.h	Mon Apr 02 13:05:59 2007 +0100
     2.3 @@ -115,7 +115,6 @@ struct hap_domain {
     2.4      const char       *locker_function;
     2.5      
     2.6      struct list_head  freelists;
     2.7 -    struct list_head  p2m_freelist;
     2.8      unsigned int      total_pages;  /* number of pages allocated */
     2.9      unsigned int      free_pages;   /* number of pages on freelists */
    2.10      unsigned int      p2m_pages;    /* number of pages allocates to p2m */