From: Andy P. <at...@us...> - 2001-06-26 19:01:16
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv19188/mm Modified Files: pgalloc.h Log Message: machine check implementation Index: pgalloc.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pgalloc.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- pgalloc.h 2001/06/17 12:39:19 1.7 +++ pgalloc.h 2001/06/26 19:01:11 1.8 @@ -166,162 +166,10 @@ #define pgd_free(pgd) free_pgd_slow(pgd) #define pgd_alloc() get_pgd_fast() +/* atp jun 01, moved these to arch/vax/mm/pgalloc.c */ /* Allocate a new page for a page table for the kernel */ -/* It is called from mm/vmalloc.c in alloc_area_pmd() - * - * It needs to be physically contiguous with the rest of the - * system page table. - * Things to consider: - * If you want to allocate a pagetable to hold a pte for a given - * new S0 address, (where this address is higher than SBR+SLR) then that - * new page table page must be allocated at the exact physical page - * That maps that S0 address. I.e. - * To map a virtual address X you need to allocate the physical - * page containing the address - * - * PFN = ( (X-PAGE_OFFSET) >> PAGE_SHIFT) - * PTE address (physical memory) = (PFN*4)+SBR - * Physical page address = (PTE address) & ~(PAGE_MASK) - * SLR = ((Physical page address + (1<<PAGE_SHIFT)) - SBR) / 4. - * - * - * If that physical page is already occupied, the contents must - * be ejected. This takes time, and can lead to deadlock, particularly - * if a dirty page needs to be written to disk/swap. - * Also, any physical pages that are in between the previous end of the - * system page table, and the new end (SBR+SLR) will need to be cleared, - * otherwise random rubbish will end up in the system page table. - * One way to do this by "locking up the machine", moving the contents - * of the physical pages needed to pages on the freelist, rewriting the PTE's - * to point at the new physical pages, and then allocating and expanding - * the system page table. No scheduling allowed. Also how you locate all - * of the references to a given physical page so that you can rewrite them - * without conducting a thorough search of all page tables (possibly - * incurring page faults for those P0 page tables that have been swapped out) - * is not clear. - * - * - * - At present I'm ducking this. We fix the S0 page table size at - * boot time, and disallow dynamic expansion. atp Feb 2001. - * - * - we still need to implement this ... linux still calls it .. - * - D.A. May 2001. - */ -extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) -{ - pgd_t *pgdptr = (pgd_t *)pmd; - - /* note the lr in the system pgd is in PAGELETS.... shift it down to - give page view */ - if ((address >> PAGE_SHIFT) < (pgdptr->lr>>3)) - return pte_offset(pmd, address); - else - return NULL; -} - -/* - * allocate a page, to hold page table entries. - * for a user process. - * We grab a random page. The only catch is that it must be virtually - * contiguous within the P0 or P1 page tables, which are held in S0 - * space. So, we remap the page table area in S0 space too. - */ -extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address) -{ - unsigned long pte_number, pte_page, pte_page_offset; - pgd_t *pgdptr = (pgd_t *)pmd; - pte_t *newpte= NULL; - - /* Deal with P0 vs P1 spaces */ - /* need to handle error cases */ - if (address < 0x40000000) - { - pte_number = (address >> PAGE_SHIFT); - pte_page = (pte_number >> SIZEOF_PTE_LOG2); - pte_page_offset = pte_number & (PTRS_PER_PTE - 1); - if ((pte_number) < (pgdptr->lr)) { - newpte = pte_offset(pmd, address); - } - } - else - { - address-=0x40000000; - pte_number = (address>>PAGE_SHIFT); - pte_page = (pte_number >> SIZEOF_PTE_LOG2); - pte_page_offset = pte_number & (PTRS_PER_PTE - 1); - if ((pte_number) > (pgdptr->lr)) { - newpte = pte_offset(pmd, address); - } - - } - - if (newpte) - { - remap_and_clear_pte_page((pgd_t *)pmd, newpte, pte_page); - /* make sure a page in S0 space is mapped */ - - } - return newpte; - - /* old 2.2 code commented out for now .. in case it is of any use - to anyone later - D.A. May 2001 */ -#if 0 - /* calculate the offset of the requested pte in this pagetable page */ - unsigned long pte_number, pte_page, pte_page_offset; - pgd_t *pgdptr = (pgd_t *)pmd; - unsigned long t2; - pte_t *page; - - pte_number = (address >> PAGE_SHIFT); - pte_page = (pte_number >> SIZEOF_PTE_LOG2); - pte_page_offset = pte_number & (PTRS_PER_PTE - 1); - - /* do we have a pgd base and length set ? */ - /* The p0br and p1br should be setup at process initialisation. */ - if (pmd_none(*pmd)) { - printk("Got pmd_none\n"); - return NULL; - } - - /* do we need to allocate another page(s) */ - - - /* this is already inside the page table region, and allocated */ - /* return the virtual address of the pte. (base registers for p0 and p1 */ - /* refer to virtual addresses in S0 space) so no _va() is needed */ - if (pte_number < (pgdptr->lr)) { - return (pte_t *) (pgdptr->br + pte_number*BYTES_PER_PTE_T); - } - - /* The address lies outside the current page table - by how much?*/ - /* FIXME: Maximum task size, defined by max p0 pagetable size */ - - /* number of pages to allocate */ - t2 = ((pte_number - pgdptr->lr) >> SIZEOF_PTE_LOG2) + 1 ; - - while (t2--) { - /* grab a page off the quicklist */ - page = get_pte_fast(); - /* or allocate a new one if none left */ - if (!page) page = get_pte_slow(pmd, address); - - /* run out of pages - out of memory */ - /* FIXME: is there anything else we need to do to signal failure?*/ - if (!page) { - printk("%s:%d: run out of free pages building page table at pte %08lx.\n", __FILE__, __LINE__, pgdptr->lr); - return NULL; - } - /* map this page into the S0 page table at the right point */ - remap_and_clear_pte_page((pgd_t *)pmd, page, pte_page); - - /* add this page of PTEs to the length register */ - /* FIXME: handle reverse P1 region... */ - pgdptr->lr += PTRS_PER_PTE; - } - return (pte_t *)( pgdptr->br + pte_number*BYTES_PER_PTE_T); -#endif /* if 0 */ -} - +extern pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address); +extern pte_t *pte_alloc(pmd_t *pmd, unsigned long address); /* * allocating and freeing a pmd is trivial: the 1-entry pmd is |