ia64/xen-unstable

changeset 15166:9c96ff147be6

[IA64] Fix p2m exposure.

p2m table page doesn't belong to any domain so that special handling required.
Instead, dom_p2m is introduced and make all p2m page belong to dom_p2m.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Mon Jun 11 11:02:05 2007 -0600 (2007-06-11)
parents 96331db61e47
children a8f780b5ff97
files xen/arch/ia64/xen/mm.c
line diff
     1.1 --- a/xen/arch/ia64/xen/mm.c	Wed Jun 06 09:30:01 2007 -0600
     1.2 +++ b/xen/arch/ia64/xen/mm.c	Mon Jun 11 11:02:05 2007 -0600
     1.3 @@ -187,6 +187,13 @@ extern unsigned long ia64_iobase;
     1.4  
     1.5  static struct domain *dom_xen, *dom_io;
     1.6  
     1.7 +/*
     1.8 + * This number is bigger than DOMID_SELF, DOMID_XEN and DOMID_IO.
     1.9 + * If more reserved domain ids are introduced, this might be increased.
    1.10 + */
    1.11 +#define DOMID_P2M       (0x7FF8U)
    1.12 +static struct domain *dom_p2m;
    1.13 +
    1.14  // followings are stolen from arch_init_memory() @ xen/arch/x86/mm.c
    1.15  void
    1.16  alloc_dom_xen_and_dom_io(void)
    1.17 @@ -227,11 +234,8 @@ mm_teardown_pte(struct domain* d, volati
    1.18      if (!mfn_valid(mfn))
    1.19          return;
    1.20      page = mfn_to_page(mfn);
    1.21 -    // page might be pte page for p2m exposing. check it.
    1.22 -    if (page_get_owner(page) == NULL) {
    1.23 -        BUG_ON(page->count_info != 0);
    1.24 -        return;
    1.25 -    }
    1.26 +    BUG_ON(page_get_owner(page) == NULL);
    1.27 +
    1.28      // struct page_info corresponding to mfn may exist or not depending
    1.29      // on CONFIG_VIRTUAL_FRAME_TABLE.
    1.30      // The above check is too easy.
    1.31 @@ -1379,11 +1383,20 @@ dom0vp_add_physmap_with_gmfn(struct doma
    1.32  #ifdef CONFIG_XEN_IA64_EXPOSE_P2M
    1.33  static struct page_info* p2m_pte_zero_page = NULL;
    1.34  
    1.35 +/* This must called before dom0 p2m table allocation */
    1.36  void __init
    1.37  expose_p2m_init(void)
    1.38  {
    1.39      pte_t* pte;
    1.40  
    1.41 +    /*
    1.42 +     * Initialise our DOMID_P2M domain.
    1.43 +     * This domain owns m2p table pages.
    1.44 +     */
    1.45 +    dom_p2m = alloc_domain(DOMID_P2M);
    1.46 +    BUG_ON(dom_p2m == NULL);
    1.47 +    dom_p2m->max_pages = ~0U;
    1.48 +
    1.49      pte = pte_alloc_one_kernel(NULL, 0);
    1.50      BUG_ON(pte == NULL);
    1.51      smp_mb();// make contents of the page visible.
    1.52 @@ -1393,13 +1406,8 @@ expose_p2m_init(void)
    1.53  static int
    1.54  expose_p2m_page(struct domain* d, unsigned long mpaddr, struct page_info* page)
    1.55  {
    1.56 -    // we can't get_page(page) here.
    1.57 -    // pte page is allocated form xen heap.(see pte_alloc_one_kernel().)
    1.58 -    // so that the page has NULL page owner and it's reference count
    1.59 -    // is useless.
    1.60 -    // see also mm_teardown_pte()'s page_get_owner() == NULL check.
    1.61 -    BUG_ON(page_get_owner(page) != NULL);
    1.62 -
    1.63 +    int ret = get_page(page, dom_p2m);
    1.64 +    BUG_ON(ret != 1);
    1.65      return __assign_domain_page(d, mpaddr, page_to_maddr(page),
    1.66                                  ASSIGN_readonly);
    1.67  }
    1.68 @@ -1918,8 +1926,10 @@ boolean_param("p2m_xenheap", opt_p2m_xen
    1.69  void *pgtable_quicklist_alloc(void)
    1.70  {
    1.71      void *p;
    1.72 +
    1.73 +    BUG_ON(dom_p2m == NULL);
    1.74      if (!opt_p2m_xenheap) {
    1.75 -        struct page_info *page = alloc_domheap_page(NULL);
    1.76 +        struct page_info *page = alloc_domheap_page(dom_p2m);
    1.77          if (page == NULL)
    1.78              return NULL;
    1.79          p = page_to_virt(page);
    1.80 @@ -1927,16 +1937,26 @@ void *pgtable_quicklist_alloc(void)
    1.81          return p;
    1.82      }
    1.83      p = alloc_xenheap_pages(0);
    1.84 -    if (p)
    1.85 +    if (p) {
    1.86          clear_page(p);
    1.87 +        /*
    1.88 +         * This page should be read only.  At this moment, the third
    1.89 +         * argument doesn't make sense.  It should be 1 when supported.
    1.90 +         */
    1.91 +        share_xen_page_with_guest(virt_to_page(p), dom_p2m, 0);
    1.92 +    }
    1.93      return p;
    1.94  }
    1.95  
    1.96  void pgtable_quicklist_free(void *pgtable_entry)
    1.97  {
    1.98 -    if (!opt_p2m_xenheap)
    1.99 -        free_domheap_page(virt_to_page(pgtable_entry));
   1.100 -    else
   1.101 +    struct page_info* page = virt_to_page(pgtable_entry);
   1.102 +
   1.103 +    BUG_ON(page_get_owner(page) != dom_p2m);
   1.104 +    BUG_ON(page->count_info != (1 | PGC_allocated));
   1.105 +
   1.106 +    put_page(page);
   1.107 +    if (opt_p2m_xenheap)
   1.108          free_xenheap_page(pgtable_entry);
   1.109  }
   1.110