|
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.
*/
|