ia64/xen-unstable

changeset 19288:f1080b20cd15

x86/mm: Do not set page's count_info directly

Page offline patch add several flag to page_info->count_info. However,
currently some code will try to set count_info after alloc_domheap_pages
without using "&" or "|" operation, this may cause the new flags lost, since
there are no protection. This patch try to make sure all write to
count_info will only impact specific field.

Also currently shadow code assume count_info is 0 for shadow page,
however, this is invalid after the new flags. Change some assert in
shadow code.

Signed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Mar 06 19:14:50 2009 +0000 (2009-03-06)
parents 0942baa2a088
children dd489125a2e7
files xen/arch/x86/mm/hap/hap.c xen/arch/x86/mm/p2m.c xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/mm/shadow/private.h
line diff
     1.1 --- a/xen/arch/x86/mm/hap/hap.c	Fri Mar 06 19:13:23 2009 +0000
     1.2 +++ b/xen/arch/x86/mm/hap/hap.c	Fri Mar 06 19:14:50 2009 +0000
     1.3 @@ -152,7 +152,7 @@ static struct page_info *hap_alloc_p2m_p
     1.4          d->arch.paging.hap.total_pages--;
     1.5          d->arch.paging.hap.p2m_pages++;
     1.6          page_set_owner(pg, d);
     1.7 -        pg->count_info = 1;
     1.8 +        pg->count_info |= 1;
     1.9      }
    1.10  
    1.11      hap_unlock(d);
    1.12 @@ -167,7 +167,7 @@ void hap_free_p2m_page(struct domain *d,
    1.13      if ( (pg->count_info & PGC_count_mask) != 1 )
    1.14          HAP_ERROR("Odd p2m page count c=%#lx t=%"PRtype_info"\n",
    1.15                    pg->count_info, pg->u.inuse.type_info);
    1.16 -    pg->count_info = 0;
    1.17 +    pg->count_info &= ~PGC_count_mask;
    1.18      /* Free should not decrement domain's total allocation, since
    1.19       * these pages were allocated without an owner. */
    1.20      page_set_owner(pg, NULL);
    1.21 @@ -218,7 +218,6 @@ hap_set_allocation(struct domain *d, uns
    1.22              ASSERT(pg);
    1.23              d->arch.paging.hap.free_pages--;
    1.24              d->arch.paging.hap.total_pages--;
    1.25 -            pg->count_info = 0;
    1.26              free_domheap_page(pg);
    1.27          }
    1.28  
     2.1 --- a/xen/arch/x86/mm/p2m.c	Fri Mar 06 19:13:23 2009 +0000
     2.2 +++ b/xen/arch/x86/mm/p2m.c	Fri Mar 06 19:14:50 2009 +0000
     2.3 @@ -177,7 +177,7 @@ p2m_next_level(struct domain *d, mfn_t *
     2.4              return 0;
     2.5          page_list_add_tail(pg, &d->arch.p2m->pages);
     2.6          pg->u.inuse.type_info = type | 1 | PGT_validated;
     2.7 -        pg->count_info = 1;
     2.8 +        pg->count_info |= 1;
     2.9  
    2.10          new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)),
    2.11                                   __PAGE_HYPERVISOR|_PAGE_USER);
    2.12 @@ -216,7 +216,7 @@ p2m_next_level(struct domain *d, mfn_t *
    2.13              return 0;
    2.14          page_list_add_tail(pg, &d->arch.p2m->pages);
    2.15          pg->u.inuse.type_info = PGT_l1_page_table | 1 | PGT_validated;
    2.16 -        pg->count_info = 1;
    2.17 +        pg->count_info |= 1;
    2.18          
    2.19          /* New splintered mappings inherit the flags of the old superpage, 
    2.20           * with a little reorganisation for the _PAGE_PSE_PAT bit. */
     3.1 --- a/xen/arch/x86/mm/shadow/common.c	Fri Mar 06 19:13:23 2009 +0000
     3.2 +++ b/xen/arch/x86/mm/shadow/common.c	Fri Mar 06 19:14:50 2009 +0000
     3.3 @@ -1677,7 +1677,7 @@ sh_alloc_p2m_pages(struct domain *d)
     3.4           * believed to be a concern.
     3.5           */
     3.6          page_set_owner(&pg[i], d);
     3.7 -        pg[i].count_info = 1;
     3.8 +        pg[i].count_info |= 1;
     3.9          page_list_add_tail(&pg[i], &d->arch.paging.shadow.p2m_freelist);
    3.10      }
    3.11      return 1;
    3.12 @@ -1721,7 +1721,7 @@ shadow_free_p2m_page(struct domain *d, s
    3.13          SHADOW_ERROR("Odd p2m page count c=%#lx t=%"PRtype_info"\n",
    3.14                       pg->count_info, pg->u.inuse.type_info);
    3.15      }
    3.16 -    pg->count_info = 0;
    3.17 +    pg->count_info &= ~PGC_count_mask;
    3.18      /* Free should not decrement domain's total allocation, since 
    3.19       * these pages were allocated without an owner. */
    3.20      page_set_owner(pg, NULL); 
    3.21 @@ -1895,7 +1895,7 @@ static void sh_hash_audit_bucket(struct 
    3.22      while ( sp )
    3.23      {
    3.24          /* Not a shadow? */
    3.25 -        BUG_ON( sp->count_info != 0 );
    3.26 +        BUG_ON( (sp->count_info & PGC_count_mask )!= 0 ) ;
    3.27          /* Bogus type? */
    3.28          BUG_ON( sp->u.sh.type == 0 );
    3.29          BUG_ON( sp->u.sh.type > SH_type_max_shadow );
     4.1 --- a/xen/arch/x86/mm/shadow/multi.c	Fri Mar 06 19:13:23 2009 +0000
     4.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Fri Mar 06 19:14:50 2009 +0000
     4.3 @@ -4281,7 +4281,7 @@ int sh_rm_write_access_from_sl1p(struct 
     4.4  
     4.5      sp = mfn_to_page(smfn);
     4.6  
     4.7 -    if ( sp->count_info != 0
     4.8 +    if ( ((sp->count_info & PGC_count_mask) != 0)
     4.9           || (sp->u.sh.type != SH_type_l1_shadow
    4.10               && sp->u.sh.type != SH_type_fl1_shadow) )
    4.11          goto fail;
     5.1 --- a/xen/arch/x86/mm/shadow/private.h	Fri Mar 06 19:13:23 2009 +0000
     5.2 +++ b/xen/arch/x86/mm/shadow/private.h	Fri Mar 06 19:14:50 2009 +0000
     5.3 @@ -647,7 +647,7 @@ static inline void sh_put_ref(struct vcp
     5.4      struct page_info *sp = mfn_to_page(smfn);
     5.5  
     5.6      ASSERT(mfn_valid(smfn));
     5.7 -    ASSERT(sp->count_info == 0);
     5.8 +    ASSERT(!(sp->count_info & PGC_count_mask));
     5.9  
    5.10      /* If this is the entry in the up-pointer, remove it */
    5.11      if ( entry_pa != 0