From: Andy P. <at...@us...> - 2001-08-20 21:29:11
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv23775 Modified Files: init.c fault.c pgalloc.c Log Message: fix vmalloc handling pte_alloc_kernel and kernel pmd Index: init.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/init.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- init.c 2001/07/31 17:28:26 1.15 +++ init.c 2001/08/20 21:29:07 1.16 @@ -36,6 +36,7 @@ context in task 0. */ pgd_t swapper_pg_dir[PTRS_PER_PGD]; +pmd_t swapper_pm_dir[2048]; /* two pages for the kernel pmd */ /* * In other architectures, paging_init sets up the kernel's page tables. @@ -50,7 +51,13 @@ /* sort out page table. */ pg0 = (pte_t *)SPT_BASE; - + + /* set up pmd */ + swapper_pg_dir[2].pmd = swapper_pm_dir; + swapper_pg_dir[2].pmd2 = &swapper_pm_dir[1024]; + /* FIXME: I _really_ dont like this flag. */ + pmd_val(swapper_pm_dir[PGD_SPECIAL]) = (unsigned long)swapper_pg_dir | 0x1; + /* FIXME: This is where the VMALLOC stuff from head.S should go */ printk("VAXMM: Initialising mm layer for %d tasks of size %dMB\n",TASK_MAXUPRC,(TASK_WSMAX>>20)); Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- fault.c 2001/08/17 20:20:41 1.8 +++ fault.c 2001/08/20 21:29:07 1.9 @@ -121,10 +121,6 @@ */ bad_area: up(&mm->mmap_sem); - printk("\nStack dump\n"); - hex_dump((void *)(regs->r1), 256); - show_regs(regs); - show_cpu_regs(); if (user_mode(regs)) { printk("do_page_fault: sending SIGSEGV\n"); Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pgalloc.c 2001/07/31 17:28:26 1.2 +++ pgalloc.c 2001/08/20 21:29:07 1.3 @@ -3,8 +3,9 @@ * pgalloc.c Routines from include/asm-vax/mm/pgalloc.h * Allocation of page table entries and so forth. * - * Copyright atp Jun 2001 - complete rewrite. - * + * Copyright atp Jun 2001 - complete rewrite. + * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) + * fix mistake in pte_alloc_kernel. * GNU GPL */ @@ -15,6 +16,8 @@ #include <asm/pgalloc.h> #include <asm/mmu_context.h> +extern void vaxpanic(char *reason); + #undef VAX_MM_PGALLOC_DEBUG /* @@ -69,8 +72,8 @@ ret[0].lr = 0x0; /* this comes in handy later */ ret[0].slot = taskslot; - /* p1br points at what would be page mapping 0x40000000 */ - ret[1].br = taskslot+ (P1PTE_OFFSET) - 0x800000 ; + /* p1br points at what would be page mapping 0x40000000 (i.e. the _end_ of the slot)*/ + ret[1].br = taskslot+ (P1PTE_OFFSET) /*+ (N_HWPTE_TASK_P1<<2)*/ - 0x800000 ; /* This is the unmapped number of PTEs */ ret[1].lr = 0x40000; ret[1].slot = taskslot; @@ -122,7 +125,10 @@ unsigned long adjaddr; is_p1 = pgd->segment; - adjaddr = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + adjaddr = pmd_index(address); +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: Calling pmd_alloc with (pgd=%8p,pmd=%8lx,address %8lx, adjaddr %8lx)\n",pgd,pgd->pmd,address,adjaddr); +#endif /* sanity check */ /* FIXME: is this pgd_none? */ @@ -190,6 +196,22 @@ return (pmd_t *) pgd->pmd+adjaddr; } +/* the kernel pmd is in mm/init.c */ +extern pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) +{ + /* we rely on init.c to set up the pmd pointers in the pgd for us. + * This leaves us just a pmd_offset sort of job */ +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: pmd_alloc_kernel: pgd %8p, pgd->pmd %8lx, address %8lx\n",pgd,pgd->pmd,address); +#endif + return pmd_offset(pgd, address); +} + +extern void pmd_free_kernel(pmd_t *pmd) +{ + return; +} + /* This inverts the remapping done in remap_and_clear */ unsigned long get_pageaddr_from_pte(pte_t *ptep) { @@ -232,11 +254,11 @@ /* sanity checks */ if (!s0addr) { - printk(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); + vaxpanic("VAXMM: null S0 address in remap_and_clear_pte_page!\n"); return; } if (!pte_page) { - printk(KERN_ERR "VAXMM: null pte_page in remap_and_clear_pte_page!\n"); + vaxpanic("VAXMM: null pte_page in remap_and_clear_pte_page!\n"); return; } @@ -332,18 +354,38 @@ * * - Indeed, however, the implementation is still not obvious to me. * atp July 2001. + * - let me qualify that. pte_alloc_kernel is called infrequently. + * Mostly by the VMALLOC stuff, which already has a VMALLOC_END check. + * so the only reason for calling this is if we are in the middle of + * some operation, outside of the vmalloc family, mapping system space. + * Hence the current implementation suffices, and I cant see a reason + * to implement an expandable s0 page table. */ 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 */ -//printk("pte_allock: pmd, %p, address %8lx\n",pmd,address); - if ((address >> PAGE_SHIFT) < (pgdptr->lr>>3)) - return pte_offset(pmd, address); + pgd_t *pgdptr = (pgd_t *)&swapper_pg_dir[2]; + unsigned long int adjusted_address; + unsigned long int spt_entry; + pte_t *spte; + + adjusted_address = ((pmd - (pmd_t *)(pgdptr->pmd))<<(PAGE_SHIFT+7)) + (address&~PMD_MASK); +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM:pte_alloc_kernel: pmd, %p, address %8lx, adjaddr %8lx\n",pmd,address,adjusted_address); +#endif + + /* note the lr in the system pgd is in PAGELETS */ + if (((adjusted_address) >> PAGELET_SHIFT) < (pgdptr->lr)) { + /* fill in any bits missing. Perhaps we should do this when we set up the + * SPT in init.c just to be consistent */ + if (pmd_val(*pmd)==NULL) { + spt_entry = (pmd - (pmd_t *)(pgdptr->pmd))<< (PAGE_SHIFT+7) | PAGE_OFFSET; + spte = GET_SPTE_VIRT(spt_entry); + pmd_val(*pmd) = spte; + } + return pte_offset(pmd, adjusted_address); + } else return NULL; } @@ -390,11 +432,11 @@ /* FIXME: should test pgdp. this is pointless otherwise */ if ((!pgdp)||(pgd_none(*pgdp))) { printk(KERN_ERR "VAXMM: Bad PGD (%8p, from pmd %8p) in pte_alloc\n",pgdp,pmd_basep); - return NULL; + goto give_segv; } if (pgdp->pmd != (unsigned long)pmd_basep) { printk(KERN_ERR "VAXMM: Mismatched PGD (%8p, has pmd %8lx from pmd %8p) in pte_alloc\n",pgdp,pgdp->pmd,pmd_basep); - return NULL; + goto give_segv; } is_p1=pgdp->segment; @@ -404,14 +446,18 @@ /* make an adjusted address + calculate linear page table entry */ adjusted_address = (((pmd-pmd_basep))<<(PAGE_SHIFT+7))+ (address&~PMD_MASK); + + + /* enforce wsmax memory limits */ if (is_p1){ adjusted_address |= 0x40000000; + if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) goto give_segv; pte_number = (adjusted_address - 0x40000000) >> PAGE_SHIFT; } else { + if (adjusted_address >= (TASK_WSMAX+TASK_MMAPMAX)) goto give_segv; pte_number = (adjusted_address>>PAGE_SHIFT); } - /* FIXME: check against WSMAX */ /* check that the pte we want isnt already allocated */ if (is_p1) { @@ -451,7 +497,7 @@ for (ii=0; ii<npages; ii++) { if (!(pte_page=pte_alloc_one(pmdi))) { printk(KERN_ERR "VAXMM: Unable to expand process page table (pgd=%8p)\n",pgdp); - return NULL; + goto give_segv; } /* remap and clear this page */ @@ -483,6 +529,11 @@ /* we flush tlb anways as we have touched S0 page tables */ flush_tlb_all(); return pte_offset(pmd, adjusted_address); + +give_segv: + printk(KERN_ERR "pte_alloc: sending SIGSEGV to process %p\n",current); + force_sig(SIGSEGV,current); + return NULL; } /* pte_alloc */ @@ -507,11 +558,20 @@ } /* Find an entry in the third-level page table.. */ +#ifdef VAX_MM_PGALLOC_DEBUG +pte_t * pte_offset(pmd_t * dir, unsigned long address) +{ + unsigned long int offset; + offset = (pmd_val(*dir)+(((address>>PAGE_SHIFT)&(PTRS_PER_PTE-1))<<SIZEOF_PTE_LOG2)); + printk(KERN_DEBUG "VAXMM:pte_offset: pmd %8p, address %8lx, pte_offset %8lx\n",dir, address, offset); + return offset; +} +#else pte_t * pte_offset(pmd_t * dir, unsigned long address) { return (pmd_val(*dir)+(((address>>PAGE_SHIFT)&(PTRS_PER_PTE-1))<<SIZEOF_PTE_LOG2)); } - +#endif /* get_pte_kernel_slow. allocate a page of PTEs for the S0 pagetable. * See comments in include/asm/mm/pgalloc.h for get_pte_kernel. */ |