WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix x86/64 Linux memory map initialisation.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix x86/64 Linux memory map initialisation.
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Sun, 22 May 2005 07:38:53 +0000
Delivery-date: Sun, 22 May 2005 17:04:00 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1507, 2005/05/22 08:38:53+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Fix x86/64 Linux memory map initialisation.
        Signed-off-by: Jun Nakajima <jun.nakajima@xxxxxxxxx>



 init.c |  201 +++++++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 116 insertions(+), 85 deletions(-)


diff -Nru a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c 
b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c
--- a/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c 2005-05-22 13:04:43 
-04:00
+++ b/linux-2.6.11-xen-sparse/arch/xen/x86_64/mm/init.c 2005-05-22 13:04:43 
-04:00
@@ -68,19 +68,19 @@
 {
         unsigned long addr;
         pte_t *pte;
-        unsigned long *page = (unsigned long *) init_level4_pgt;
+       unsigned long *page = (unsigned long *) init_level4_pgt;
 
-        addr = (unsigned long) page[pgd_index(va)];
-        addr_to_page(addr, page);
+       addr = (unsigned long) page[pgd_index(va)];
+       addr_to_page(addr, page);
 
-        addr = page[pud_index(va)];
-        addr_to_page(addr, page);
+       addr = page[pud_index(va)];
+       addr_to_page(addr, page);
 
-        addr = page[pmd_index(va)];
-        addr_to_page(addr, page);
+       addr = page[pmd_index(va)];
+       addr_to_page(addr, page);
 
-        pte = (pte_t *) &page[pte_index(va)];
-        xen_l1_entry_update(pte, (*(unsigned long*)pte) & ~_PAGE_RW);
+       pte = (pte_t *) &page[pte_index(va)];
+       xen_l1_entry_update(pte, (*(unsigned long*)pte) & ~_PAGE_RW);
        __flush_tlb_one(addr);
 }
 
@@ -106,7 +106,7 @@
 
 
 /*
- * Assume the tranlation is already established.
+ * Assume the translation is already established.
  */
 void make_page_readonly(void *va)
 {
@@ -385,72 +385,9 @@
        }
 
         set_pte_phys(address, phys, prot, SET_FIXMAP_USER); 
-
-#if 0
-        page = (unsigned long *) user_level3_pgt;
-        pud = page[pud_index(address)];
-
-        printk("pud = %p\n", pud);
-
-        pmd = (pmd_t *) spp_getpage(); 
-        printk("alloc pmd = %p\n", pmd);
-
-        make_page_readonly((unsigned long)pmd);
-
-        xen_pmd_pin(__pa(pmd));
-
-        set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
-
-        printk("after set_pud\n");
-
-        pte = (pte_t *) spp_getpage();
-        printk("pte = %p\n");
-
-        make_page_readonly((unsigned long)pte);
-
-        xen_pte_pin(__pa(pte));
-
-        page = (unsigned long *) pud;
-        pud = page[pud_index(address)];
-        
-
-        pmd = pmd_offset(pud, vaddr);
-
-        set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
-#endif
-
 }
 
-unsigned long __initdata table_start, table_end, tables_reserved; 
-
-#if 0
-/*
- * Get the machine PFN given va
- */
-static unsigned long get_machine_pfn(unsigned long va)
-{
-        unsigned long addr;
-        pte_t *pte;
-
-        unsigned long *page = (unsigned long *) init_level4_pgt;
-
-        addr = (unsigned long) page[pgd_index(va)];
-        addr &= PHYSICAL_PAGE_MASK;
-        page = (unsigned long *) ((unsigned long)(((mfn_to_pfn(addr >> 
PAGE_SHIFT)) << PAGE_SHIFT) + __START_KERNEL_map)); 
-
-        addr = page[pud_index(va)];
-        addr &= PHYSICAL_PAGE_MASK;
-        page = (unsigned long *) ((unsigned long)(((mfn_to_pfn(addr >> 
PAGE_SHIFT)) << PAGE_SHIFT) + __START_KERNEL_map));
-
-        addr = page[pmd_index(va)];
-        addr &= PHYSICAL_PAGE_MASK; 
-        page = (unsigned long *) ((unsigned long)(((mfn_to_pfn(addr >> 
PAGE_SHIFT)) << PAGE_SHIFT)+ __START_KERNEL_map));
-
-        pte = (pte_t *) &page[pte_index(va)];
-
-        return (unsigned long) (pte->pte >> PAGE_SHIFT);
-}
-#endif
+unsigned long __initdata table_start, table_end, tables_space; 
 
 unsigned long get_machine_pfn(unsigned long addr)
 {
@@ -461,17 +398,37 @@
         return (pte->pte >> PAGE_SHIFT);
 } 
 
+#define ALIGN_TO_4K __attribute__((section(".data.page_aligned")))
+#define MAX_LOW_PAGES  0x20
+static unsigned long __init_pgt[MAX_LOW_PAGES][512]  ALIGN_TO_4K;
+static int __init_pgt_index;
 
 /*
  * We start using from start_pfn
  */
-static __init void *alloc_low_page(unsigned long *phys)
+static __init void *alloc_static_page(unsigned long *phys)
+{
+       int i = __init_pgt_index++;
+
+       if (__init_pgt_index >= MAX_LOW_PAGES) {
+               printk("Need to increase MAX_LOW_PAGES");
+               BUG();
+       }
+               
+       *phys = __pa(__init_pgt[i]);
+
+       return (void *) __init_pgt[i];
+} 
+
+/*
+ * Get RO page
+ */
+static void __init *alloc_low_page(unsigned long *phys)
 { 
         unsigned long pfn = table_end++;
     
         *phys = (pfn << PAGE_SHIFT);
         memset((void *) ((pfn << PAGE_SHIFT) + __START_KERNEL_map), 0, 
PAGE_SIZE);
-
         return (void *)((pfn << PAGE_SHIFT) + __START_KERNEL_map);
 } 
 
@@ -519,7 +476,7 @@
                         pte_save = pte;
                         for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += 
PTE_SIZE) {
                                 if (paddr < (table_start << PAGE_SHIFT) 
-                                    + tables_reserved)
+                                    + tables_space)
                                 {
                                         __set_pte(pte, 
                                                 __pte(paddr | (_KERNPG_TABLE & 
~_PAGE_RW)));
@@ -549,12 +506,83 @@
        pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
         ptes = (end + PTE_SIZE - 1) >> PAGE_SHIFT;
 
-        tables_reserved = round_up(puds*8, PAGE_SIZE) + round_up(pmds * 8, 
PAGE_SIZE) 
-                + round_up(ptes * 8, PAGE_SIZE); 
-       table_start = start_pfn;
-       table_end = table_start;
+        tables_space = round_up(puds * 8, PAGE_SIZE) + 
+                         round_up(pmds * 8, PAGE_SIZE) + 
+                         round_up(ptes * 8, PAGE_SIZE); 
 }
 
+
+/*
+ * Extend kernel mapping to access pages for page tables.  The initial
+ * mapping done by Xen is minimal (e.g. 8MB) and we need to extend the
+ * mapping for early initialization.
+ */
+
+#define MIN_INIT_SIZE  0x800000
+static unsigned long current_size, extended_size;
+
+void __init extend_init_mapping(void) 
+{
+       unsigned long va = __START_KERNEL_map;
+       unsigned long addr, *pte_page;
+
+       unsigned long phys;
+        pmd_t *pmd;
+       pte_t *pte, new_pte;
+       unsigned long *page = (unsigned long *) init_level4_pgt;
+       int i;
+
+       addr = (unsigned long) page[pgd_index(va)];
+       addr_to_page(addr, page);
+
+       addr = page[pud_index(va)];
+       addr_to_page(addr, page);
+
+       for (;;) {
+               pmd = (pmd_t *) &page[pmd_index(va)];
+               if (pmd_present(*pmd)) {
+                       /*
+                        * if pmd is valid, check pte.
+                        */
+                       addr = page[pmd_index(va)];
+                       addr_to_page(addr, pte_page);
+                       
+                       for (i = 0; i < PTRS_PER_PTE; i++) {
+                               pte = (pte_t *) &pte_page[pte_index(va)];
+                               
+                               if (pte_present(*pte)) {
+                                       va += PAGE_SIZE;
+                                       current_size += PAGE_SIZE;
+                               } else
+                                   break;
+                       }
+
+               } else
+                   break;
+       }
+
+       for (; va < __START_KERNEL_map + current_size + tables_space; ) {
+               pmd = (pmd_t *) &page[pmd_index(va)];
+
+               if (pmd_none(*pmd)) {
+                       pte_page = (unsigned long *) alloc_static_page(&phys);
+                       make_page_readonly(pte_page);
+                       xen_pte_pin(phys);
+                       set_pmd(pmd, __pmd(phys | _KERNPG_TABLE | _PAGE_USER));
+
+                       for (i = 0; i < PTRS_PER_PTE; i++, va += PAGE_SIZE) {
+                               new_pte = pfn_pte((va -  __START_KERNEL_map) >> 
PAGE_SHIFT, 
+                                                 __pgprot(_KERNPG_TABLE | 
_PAGE_USER));
+
+                               pte = (pte_t *) &pte_page[pte_index(va)];
+                               xen_l1_entry_update(pte, new_pte.pte);
+                               extended_size += PAGE_SIZE;
+                       }
+               } 
+       }
+}
+
+
 /* Setup the direct mapping of the physical memory at PAGE_OFFSET.

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix x86/64 Linux memory map initialisation., BitKeeper Bot <=