ChangeSet 1.2181.2.51, 2005/03/26 21:37:09-08:00, [EMAIL PROTECTED]

        [SPARC64]: Handle non-8K PAGE_SIZE better in TLB miss handlers.
        
        The existing code mostly worked, but only for 32-bit
        processes.
        
        This caught a serious bug too, pgd_index() was masking
        with plain PTRS_PER_PGD instead of (PTRS_PER_PGD - 1).
        That has been with us for several years.  It is a wonder
        that things work at all some times :-)
        
        Signed-off-by: David S. Miller <[EMAIL PROTECTED]>



 arch/sparc64/kernel/dtlb_backend.S |  158 ++++++++++++++++++++++++++-------
 arch/sparc64/kernel/dtlb_base.S    |    2 
 arch/sparc64/kernel/entry.S        |  173 ++++++++++++++++++++++++-------------
 arch/sparc64/mm/init.c             |   54 +----------
 arch/sparc64/mm/tlb.c              |    8 -
 include/asm-sparc64/cpudata.h      |    2 
 include/asm-sparc64/pgalloc.h      |   64 -------------
 include/asm-sparc64/pgtable.h      |   38 +-------
 8 files changed, 253 insertions(+), 246 deletions(-)


diff -Nru a/arch/sparc64/kernel/dtlb_backend.S 
b/arch/sparc64/kernel/dtlb_backend.S
--- a/arch/sparc64/kernel/dtlb_backend.S        2005-04-03 21:13:56 -07:00
+++ b/arch/sparc64/kernel/dtlb_backend.S        2005-04-03 21:13:56 -07:00
@@ -10,57 +10,140 @@
 #include <asm/mmu_context.h>
 
 #if PAGE_SHIFT == 13
-#define FILL_VALID_SZ_BITS1(r1) \
-        sllx           %g2, 62, r1
-#define FILL_VALID_SZ_BITS2(r1)
-#define FILL_VALID_SZ_BITS_NOP nop
+#define SZ_BITS                _PAGE_SZ8K
 #elif PAGE_SHIFT == 16
-#define FILL_VALID_SZ_BITS1(r1) \
-       or              %g0, 5, r1
-#define FILL_VALID_SZ_BITS2(r1) \
-       sllx            r1, 61, r1
-#define FILL_VALID_SZ_BITS_NOP
-#else
-#error unsupported PAGE_SIZE
-#endif /* PAGE_SHIFT */
+#define SZ_BITS                _PAGE_SZ64K
+#elif PAGE_SHIFT == 19
+#define SZ_BITS                _PAGE_SZ512K
+#elif PAGE_SHIFT == 22
+#define SZ_BITS                _PAGE_SZ4M
+#endif
+
+#define VALID_SZ_BITS  (_PAGE_VALID | SZ_BITS)
 
 #define VPTE_BITS              (_PAGE_CP | _PAGE_CV | _PAGE_P )
 #define VPTE_SHIFT             (PAGE_SHIFT - 3)
-#define TLB_PMD_SHIFT          (PAGE_SHIFT - 3 + 3)
-#define TLB_PGD_SHIFT          (PMD_BITS + PAGE_SHIFT - 3 + 3)
-#define TLB_PMD_MASK           (((1 << PMD_BITS) - 1) << 1)
-#define TLB_PGD_MASK           (((1 << (VA_BITS - PAGE_SHIFT - (PAGE_SHIFT - 
3) - PMD_BITS)) - 1) << 2)
 
 /* Ways we can get here:
  *
  * 1) Nucleus loads and stores to/from PA-->VA direct mappings at tl>1.
  * 2) Nucleus loads and stores to/from user/kernel window save areas.
  * 3) VPTE misses from dtlb_base and itlb_base.
+ *
+ * We need to extract out the PMD and PGDIR indexes from the
+ * linear virtual page table access address.  The PTE index
+ * is at the bottom, but we are not concerned with it.  Bits
+ * 0 to 2 are clear since each PTE is 8 bytes in size.  Each
+ * PMD and PGDIR entry are 4 bytes in size.   Thus, this
+ * address looks something like:
+ *
+ * |---------------------------------------------------------------|
+ * |  ...   |    PGDIR index    |    PMD index    | PTE index  |   |
+ * |---------------------------------------------------------------|
+ *   63   F   E               D   C             B   A         3 2 0  <- bit nr
+ *
+ *  The variable bits above are defined as:
+ *  A --> 3 + (PAGE_SHIFT - log2(8))
+ *    --> 3 + (PAGE_SHIFT - 3) - 1
+ *        (ie. this is "bit 3" + PAGE_SIZE - size of PTE entry in bits - 1)
+ *  B --> A + 1
+ *  C --> B + (PAGE_SHIFT - log2(4))
+ *    -->  B + (PAGE_SHIFT - 2) - 1
+ *        (ie. this is "bit B" + PAGE_SIZE - size of PMD entry in bits - 1)
+ *  D --> C + 1
+ *  E --> D + (PAGE_SHIFT - log2(4))
+ *    --> D + (PAGE_SHIFT - 2) - 1
+ *        (ie. this is "bit D" + PAGE_SIZE - size of PGDIR entry in bits - 1)
+ *  F --> E + 1
+ *
+ * (Note how "B" always evalutes to PAGE_SHIFT, all the other constants
+ *  cancel out.)
+ *
+ * For 8K PAGE_SIZE (thus, PAGE_SHIFT of 13) the bit numbers are:
+ * A --> 12
+ * B --> 13
+ * C --> 23
+ * D --> 24
+ * E --> 34
+ * F --> 35
+ *
+ * For 64K PAGE_SIZE (thus, PAGE_SHIFT of 16) the bit numbers are:
+ * A --> 15
+ * B --> 16
+ * C --> 29
+ * D --> 30
+ * E --> 43
+ * F --> 44
+ *
+ * Because bits both above and below each PGDIR and PMD index need to
+ * be masked out, and the index can be as long as 14 bits (when using a
+ * 64K PAGE_SIZE, and thus a PAGE_SHIFT of 16), we need 3 instructions
+ * to extract each index out.
+ *
+ * Shifts do not pair very well on UltraSPARC-I, II, IIi, and IIe, so
+ * we try to avoid using them for the entire operation.  We could setup
+ * a mask anywhere from bit 31 down to bit 10 using the sethi instruction.
+ *
+ * We need a mask covering bits B --> C and one covering D --> E.
+ * For 8K PAGE_SIZE these masks are 0x00ffe000 and 0x7ff000000.
+ * For 64K PAGE_SIZE these masks are 0x3fff0000 and 0xfffc0000000.
+ * The second in each set cannot be loaded with a single sethi
+ * instruction, because the upper bits are past bit 32.  We would
+ * need to use a sethi + a shift.
+ *
+ * For the time being, we use 2 shifts and a simple "and" mask.
+ * We shift left to clear the bits above the index, we shift down
+ * to clear the bits below the index (sans the log2(4 or 8) bits)
+ * and a mask to clear the log2(4 or 8) bits.  We need therefore
+ * define 4 shift counts, all of which are relative to PAGE_SHIFT.
+ *
+ * Although unsupportable for other reasons, this does mean that
+ * 512K and 4MB page sizes would be generaally supported by the
+ * kernel.  (ELF binaries would break with > 64K PAGE_SIZE since
+ * the sections are only aligned that strongly).
+ *
+ * The operations performed for extraction are thus:
+ *
+ *      ((X << FOO_SHIFT_LEFT) >> FOO_SHIFT_RIGHT) & ~0x3
+ *
  */
 
+#define A (3 + (PAGE_SHIFT - 3) - 1)
+#define B (A + 1)
+#define C (B + (PAGE_SHIFT - 2) - 1)
+#define D (C + 1)
+#define E (D + (PAGE_SHIFT - 2) - 1)
+#define F (E + 1)
+
+#define PMD_SHIFT_LEFT         (64 - D)
+#define PMD_SHIFT_RIGHT                (64 - (D - B) - 2)
+#define PGDIR_SHIFT_LEFT       (64 - F)
+#define PGDIR_SHIFT_RIGHT      (64 - (F - D) - 2)
+#define LOW_MASK_BITS          0x3
+
 /* TLB1 ** ICACHE line 1: tl1 DTLB and quick VPTE miss */
        ldxa            [%g1 + %g1] ASI_DMMU, %g4       ! Get TAG_ACCESS
        add             %g3, %g3, %g5                   ! Compute VPTE base
        cmp             %g4, %g5                        ! VPTE miss?
        bgeu,pt         %xcc, 1f                        ! Continue here
-        andcc          %g4, TAG_CONTEXT_BITS, %g5      ! From Nucleus? (for 
tl0 miss)
-       ba,pt           %xcc, from_tl1_trap             ! Fall to tl0 miss
-        rdpr           %tl, %g5                        ! For tl0 miss TL==3 
test
+        andcc          %g4, TAG_CONTEXT_BITS, %g5      ! tl0 miss Nucleus test
+       ba,a,pt         %xcc, from_tl1_trap             ! Fall to tl0 miss
 1:     sllx            %g6, VPTE_SHIFT, %g4            ! Position TAG_ACCESS
+       or              %g4, %g5, %g4                   ! Prepare TAG_ACCESS
 
 /* TLB1 ** ICACHE line 2: Quick VPTE miss              */
-       or              %g4, %g5, %g4                   ! Prepare TAG_ACCESS
        mov             TSB_REG, %g1                    ! Grab TSB reg
        ldxa            [%g1] ASI_DMMU, %g5             ! Doing PGD caching?
-       srlx            %g6, (TLB_PMD_SHIFT - 1), %g1   ! Position PMD offset
+       sllx            %g6, PMD_SHIFT_LEFT, %g1        ! Position PMD offset
        be,pn           %xcc, sparc64_vpte_nucleus      ! Is it from Nucleus?
-        and            %g1, TLB_PMD_MASK, %g1          ! Mask PMD offset bits
+        srlx           %g1, PMD_SHIFT_RIGHT, %g1       ! Mask PMD offset bits
        brnz,pt         %g5, sparc64_vpte_continue      ! Yep, go like smoke
-        add            %g1, %g1, %g1                   ! Position PMD offset 
some more
+        andn           %g1, LOW_MASK_BITS, %g1         ! Final PMD mask
+       sllx            %g6, PGDIR_SHIFT_LEFT, %g5      ! Position PGD offset
 
 /* TLB1 ** ICACHE line 3: Quick VPTE miss              */
-       srlx            %g6, (TLB_PGD_SHIFT - 2), %g5   ! Position PGD offset
-       and             %g5, TLB_PGD_MASK, %g5          ! Mask PGD offset
+       srlx            %g5, PGDIR_SHIFT_RIGHT, %g5     ! Mask PGD offset bits
+       andn            %g5, LOW_MASK_BITS, %g5         ! Final PGD mask
        lduwa           [%g7 + %g5] ASI_PHYS_USE_EC, %g5! Load PGD
        brz,pn          %g5, vpte_noent                 ! Valid?
 sparc64_kpte_continue:
@@ -71,23 +154,28 @@
        brz,pn          %g5, vpte_noent                 ! Valid?
 
 /* TLB1 ** ICACHE line 4: Quick VPTE miss              */
-        FILL_VALID_SZ_BITS1(%g1)                       ! Put _PAGE_VALID into 
%g1
-       FILL_VALID_SZ_BITS2(%g1)                        ! Put _PAGE_VALID into 
%g1
+        mov            (VALID_SZ_BITS >> 61), %g1      ! upper vpte into %g1
+       sllx            %g1, 61, %g1                    ! finish calc
        or              %g5, VPTE_BITS, %g5             ! Prepare VPTE data
        or              %g5, %g1, %g5                   ! ...
        mov             TLB_SFSR, %g1                   ! Restore %g1 value
        stxa            %g5, [%g0] ASI_DTLB_DATA_IN     ! Load VPTE into TLB
        stxa            %g4, [%g1 + %g1] ASI_DMMU       ! Restore previous 
TAG_ACCESS
        retry                                           ! Load PTE once again
-       FILL_VALID_SZ_BITS_NOP
 
+#undef SZ_BITS
+#undef VALID_SZ_BITS
 #undef VPTE_SHIFT
-#undef TLB_PMD_SHIFT
-#undef TLB_PGD_SHIFT
 #undef VPTE_BITS
-#undef TLB_PMD_MASK
-#undef TLB_PGD_MASK
-#undef FILL_VALID_SZ_BITS1
-#undef FILL_VALID_SZ_BITS2
-#undef FILL_VALID_SZ_BITS_NOP
+#undef A
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef PMD_SHIFT_LEFT
+#undef PMD_SHIFT_RIGHT
+#undef PGDIR_SHIFT_LEFT
+#undef PGDIR_SHIFT_RIGHT
+#undef LOW_MASK_BITS
 
diff -Nru a/arch/sparc64/kernel/dtlb_base.S b/arch/sparc64/kernel/dtlb_base.S
--- a/arch/sparc64/kernel/dtlb_base.S   2005-04-03 21:13:56 -07:00
+++ b/arch/sparc64/kernel/dtlb_base.S   2005-04-03 21:13:56 -07:00
@@ -68,8 +68,8 @@
 /* DTLB ** ICACHE line 1: Quick user TLB misses                */
        ldxa            [%g1 + %g1] ASI_DMMU, %g4       ! Get TAG_ACCESS
        andcc           %g4, TAG_CONTEXT_BITS, %g0      ! From Nucleus?
-       mov             1, %g5                          ! For TL==3 test
 from_tl1_trap:
+       rdpr            %tl, %g5                        ! For TL==3 test
        CREATE_VPTE_OFFSET1(%g4, %g6)                   ! Create VPTE offset
        be,pn           %xcc, 3f                        ! Yep, special 
processing
         CREATE_VPTE_OFFSET2(%g4, %g6)                  ! Create VPTE offset
diff -Nru a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
--- a/arch/sparc64/kernel/entry.S       2005-04-03 21:13:56 -07:00
+++ b/arch/sparc64/kernel/entry.S       2005-04-03 21:13:56 -07:00
@@ -38,97 +38,150 @@
  * range (note that this is only possible for instruction miss, data misses to
  * obp range do not use vpte). If so, go back directly to the faulting address.
  * This is because we want to read the tpc, otherwise we have no way of knowing
- * the 8k aligned faulting address if we are using >8k kernel pagesize. This 
also
- * ensures no vpte range addresses are dropped into tlb while obp is executing
- * (see inherit_locked_prom_mappings() rant).
+ * the 8k aligned faulting address if we are using >8k kernel pagesize. This
+ * also ensures no vpte range addresses are dropped into tlb while obp is
+ * executing (see inherit_locked_prom_mappings() rant).
  */
 sparc64_vpte_nucleus:
+       /* Load 0xf0000000, which is LOW_OBP_ADDRESS.  */
        mov             0xf, %g5
-       sllx            %g5, 28, %g5                    ! Load 0xf0000000
-       cmp             %g4, %g5                        ! Is addr >= 
LOW_OBP_ADDRESS?
+       sllx            %g5, 28, %g5
+
+       /* Is addr >= LOW_OBP_ADDRESS?  */
+       cmp             %g4, %g5
        blu,pn          %xcc, sparc64_vpte_patchme1
         mov            0x1, %g5
-       sllx            %g5, 32, %g5                    ! Load 0x100000000
-       cmp             %g4, %g5                        ! Is addr < 
HI_OBP_ADDRESS?
+
+       /* Load 0x100000000, which is HI_OBP_ADDRESS.  */
+       sllx            %g5, 32, %g5
+
+       /* Is addr < HI_OBP_ADDRESS?  */
+       cmp             %g4, %g5
        blu,pn          %xcc, obp_iaddr_patch
         nop
+
+       /* These two instructions are patched by paginig_init().  */
 sparc64_vpte_patchme1:
-       sethi           %hi(0), %g5                     ! This has to be patched
+       sethi           %hi(0), %g5
 sparc64_vpte_patchme2:
-       or              %g5, %lo(0), %g5                ! This is patched too
-       ba,pt           %xcc, sparc64_kpte_continue     ! Part of dtlb_backend
-        add            %g1, %g1, %g1                   ! Finish PMD offset 
adjustment
+       or              %g5, %lo(0), %g5
+
+       /* With kernel PGD in %g5, branch back into dtlb_backend.  */
+       ba,pt           %xcc, sparc64_kpte_continue
+        andn           %g1, 0x3, %g1   /* Finish PMD offset adjustment.  */
 
 vpte_noent:
-       mov             TLB_SFSR, %g1                   ! Restore %g1 value
-       stxa            %g4, [%g1 + %g1] ASI_DMMU       ! Restore previous 
TAG_ACCESS
-       done                                            ! Slick trick
+       /* Restore previous TAG_ACCESS, %g5 is zero, and we will
+        * skip over the trap instruction so that the top level
+        * TLB miss handler will thing this %g5 value is just an
+        * invalid PTE, thus branching to full fault processing.
+        */
+       mov             TLB_SFSR, %g1
+       stxa            %g4, [%g1 + %g1] ASI_DMMU
+       done
 
        .globl          obp_iaddr_patch
-       .globl          obp_daddr_patch
-
 obp_iaddr_patch:
-       sethi           %hi(0), %g5                     ! This and following is 
patched
-       or              %g5, %lo(0), %g5                ! g5 now holds obp pmd 
base physaddr
-       wrpr            %g0, 1, %tl                     ! Behave as if we are 
at TL0
-       rdpr            %tpc, %g4                       ! Find original 
faulting iaddr
-       srlx            %g4, 13, %g4                    ! Throw out context bits
-       sllx            %g4, 13, %g4                    ! g4 has vpn + ctx0 now
-       mov             TLB_SFSR, %g1                   ! Restore %g1 value
-       stxa            %g4, [%g1 + %g1] ASI_IMMU       ! Restore previous 
TAG_ACCESS
-       srlx            %g4, 23, %g6                    ! Find pmd number
-       and             %g6, 0x7ff, %g6                 ! Find pmd number
-       sllx            %g6, 2, %g6                     ! Find pmd offset
-       lduwa           [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pmd, ie 
pagetable physaddr
-       brz,pn          %g5, longpath                   ! Kill the PROM ? :-)
-        sllx           %g5, 11, %g5                    ! Shift into place
-       srlx            %g4, 13, %g6                    ! find pte number in 
pagetable
-       and             %g6, 0x3ff, %g6                 ! find pte number in 
pagetable
-       sllx            %g6, 3, %g6                     ! find pte offset in 
pagetable
-       ldxa            [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pte
-       brgez,pn        %g5, longpath                   ! Kill the PROM ? :-)
+       /* These two instructions patched by inherit_prom_mappings().  */
+       sethi           %hi(0), %g5
+       or              %g5, %lo(0), %g5
+
+       /* Behave as if we are at TL0.  */
+       wrpr            %g0, 1, %tl
+       rdpr            %tpc, %g4       /* Find original faulting iaddr */
+       srlx            %g4, 13, %g4    /* Throw out context bits */
+       sllx            %g4, 13, %g4    /* g4 has vpn + ctx0 now */
+
+       /* Restore previous TAG_ACCESS.  */
+       mov             TLB_SFSR, %g1
+       stxa            %g4, [%g1 + %g1] ASI_IMMU
+
+       /* Get PMD offset.  */
+       srlx            %g4, 23, %g6
+       and             %g6, 0x7ff, %g6
+       sllx            %g6, 2, %g6
+
+       /* Load PMD, is it valid?  */
+       lduwa           [%g5 + %g6] ASI_PHYS_USE_EC, %g5
+       brz,pn          %g5, longpath
+        sllx           %g5, 11, %g5
+
+       /* Get PTE offset.  */
+       srlx            %g4, 13, %g6
+       and             %g6, 0x3ff, %g6
+       sllx            %g6, 3, %g6
+
+       /* Load PTE.  */
+       ldxa            [%g5 + %g6] ASI_PHYS_USE_EC, %g5
+       brgez,pn        %g5, longpath
         nop
-       stxa            %g5, [%g0] ASI_ITLB_DATA_IN     ! put into tlb
-       retry                                           ! go back to original 
fault
 
+       /* TLB load and return from trap.  */
+       stxa            %g5, [%g0] ASI_ITLB_DATA_IN
+       retry
+
+       .globl          obp_daddr_patch
 obp_daddr_patch:
-       sethi           %hi(0), %g5                     ! This and following is 
patched
-       or              %g5, %lo(0), %g5                ! g5 now holds obp pmd 
base physaddr
-       srlx            %g4, 23, %g6                    ! Find pmd number
-       and             %g6, 0x7ff, %g6                 ! Find pmd number
-       sllx            %g6, 2, %g6                     ! Find pmd offset
-       lduwa           [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pmd, ie 
pagetable physaddr
+       /* These two instructions patched by inherit_prom_mappings().  */
+       sethi           %hi(0), %g5
+       or              %g5, %lo(0), %g5
+
+       /* Get PMD offset.  */
+       srlx            %g4, 23, %g6
+       and             %g6, 0x7ff, %g6
+       sllx            %g6, 2, %g6
+
+       /* Load PMD, is it valid?  */
+       lduwa           [%g5 + %g6] ASI_PHYS_USE_EC, %g5
        brz,pn          %g5, longpath
-        sllx           %g5, 11, %g5                    ! Shift into place
-       srlx            %g4, 13, %g6                    ! find pte number in 
pagetable
-       and             %g6, 0x3ff, %g6                 ! find pte number in 
pagetable
-       sllx            %g6, 3, %g6                     ! find pte offset in 
pagetable
-       ldxa            [%g5 + %g6] ASI_PHYS_USE_EC, %g5! Load pte
+        sllx           %g5, 11, %g5
+
+       /* Get PTE offset.  */
+       srlx            %g4, 13, %g6
+       and             %g6, 0x3ff, %g6
+       sllx            %g6, 3, %g6
+
+       /* Load PTE.  */
+       ldxa            [%g5 + %g6] ASI_PHYS_USE_EC, %g5
        brgez,pn        %g5, longpath
         nop
-       stxa            %g5, [%g0] ASI_DTLB_DATA_IN     ! put into tlb
+
+       /* TLB load and return from trap.  */
+       stxa            %g5, [%g0] ASI_DTLB_DATA_IN
        retry
 
 /*
- * On a first level data miss, check whether this is to the OBP range (note 
that
- * such accesses can be made by prom, as well as by kernel using 
prom_getproperty
- * on "address"), and if so, do not use vpte access ... rather, use information
- * saved during inherit_prom_mappings() using 8k pagesize.
+ * On a first level data miss, check whether this is to the OBP range (note
+ * that such accesses can be made by prom, as well as by kernel using
+ * prom_getproperty on "address"), and if so, do not use vpte access ...
+ * rather, use information saved during inherit_prom_mappings() using 8k
+ * pagesize.
  */
 kvmap:
+       /* Load 0xf0000000, which is LOW_OBP_ADDRESS.  */
        mov             0xf, %g5
-       sllx            %g5, 28, %g5                    ! Load 0xf0000000
-       cmp             %g4, %g5                        ! Is addr >= 
LOW_OBP_ADDRESS?
+       sllx            %g5, 28, %g5
+
+       /* Is addr >= LOW_OBP_ADDRESS?  */
+       cmp             %g4, %g5
        blu,pn          %xcc, vmalloc_addr
         mov            0x1, %g5
-       sllx            %g5, 32, %g5                    ! Load 0x100000000
-       cmp             %g4, %g5                        ! Is addr < 
HI_OBP_ADDRESS?
+
+       /* Load 0x100000000, which is HI_OBP_ADDRESS.  */
+       sllx            %g5, 32, %g5
+
+       /* Is addr < HI_OBP_ADDRESS?  */
+       cmp             %g4, %g5
        blu,pn          %xcc, obp_daddr_patch
         nop
-vmalloc_addr:                                          ! vmalloc addr accessed
-       ldxa            [%g3 + %g6] ASI_N, %g5          ! Yep, load k-vpte
-       brgez,pn        %g5, longpath                   ! Valid, load into TLB
+
+vmalloc_addr:
+       /* If we get here, a vmalloc addr accessed, load kernel VPTE.  */
+       ldxa            [%g3 + %g6] ASI_N, %g5
+       brgez,pn        %g5, longpath
         nop
+
+       /* PTE is valid, load into TLB and return from trap.  */
        stxa            %g5, [%g0] ASI_DTLB_DATA_IN     ! Reload TLB
        retry
 
diff -Nru a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c    2005-04-03 21:13:56 -07:00
+++ b/arch/sparc64/mm/init.c    2005-04-03 21:13:56 -07:00
@@ -85,40 +85,14 @@
        preempt_disable();
        if (pgtable_cache_size > PGT_CACHE_HIGH) {
                do {
-#ifdef CONFIG_SMP
                        if (pgd_quicklist)
                                free_pgd_slow(get_pgd_fast());
-#endif
                        if (pte_quicklist[0])
                                free_pte_slow(pte_alloc_one_fast(NULL, 0));
                        if (pte_quicklist[1])
                                free_pte_slow(pte_alloc_one_fast(NULL, 1 << 
(PAGE_SHIFT + 10)));
                } while (pgtable_cache_size > PGT_CACHE_LOW);
        }
-#ifndef CONFIG_SMP
-        if (pgd_cache_size > PGT_CACHE_HIGH / 4) {
-               struct page *page, *page2;
-                for (page2 = NULL, page = (struct page *)pgd_quicklist; page;) 
{
-                        if ((unsigned long)page->lru.prev == 3) {
-                                if (page2)
-                                        page2->lru.next = page->lru.next;
-                                else
-                                        pgd_quicklist = (void *) 
page->lru.next;
-                                pgd_cache_size -= 2;
-                                __free_page(page);
-                                if (page2)
-                                        page = (struct page *)page2->lru.next;
-                                else
-                                        page = (struct page *)pgd_quicklist;
-                                if (pgd_cache_size <= PGT_CACHE_LOW / 4)
-                                        break;
-                                continue;
-                        }
-                        page2 = page;
-                        page = (struct page *)page->lru.next;
-                }
-        }
-#endif
        preempt_enable();
 }
 
@@ -219,6 +193,7 @@
 
                put_cpu();
        }
+
        if (get_thread_fault_code())
                __update_mmu_cache(vma->vm_mm->context & TAG_CONTEXT_BITS,
                                   address, pte, get_thread_fault_code());
@@ -281,9 +256,6 @@
        printk("%ld pages of RAM\n", num_physpages);
        printk("%d free pages\n", nr_free_pages());
        printk("%d pages in page table cache\n",pgtable_cache_size);
-#ifndef CONFIG_SMP
-       printk("%d entries in page dir cache\n",pgd_cache_size);
-#endif 
 }
 
 void mmu_info(struct seq_file *m)
@@ -392,10 +364,10 @@
        n = n / sizeof(*trans);
 
        /*
-        * The obp translations are saved based on 8k pagesize, since obp can 
use
-        * a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000, ie 
obp 
-        * range, are handled in entry.S and do not use the vpte scheme (see 
rant
-        * in inherit_locked_prom_mappings()).
+        * The obp translations are saved based on 8k pagesize, since obp can
+        * use a mixture of pagesizes. Misses to the 0xf0000000 - 0x100000000,
+        * ie obp range, are handled in entry.S and do not use the vpte scheme
+        * (see rant in inherit_locked_prom_mappings()).
         */
 #define OBP_PMD_SIZE 2048
        prompmd = __alloc_bootmem(OBP_PMD_SIZE, OBP_PMD_SIZE, bootmap_base);
@@ -1703,22 +1675,6 @@
        datapages = PAGE_ALIGN(datapages) >> PAGE_SHIFT;
        initpages = (((unsigned long) __init_end) - ((unsigned long) 
__init_begin));
        initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
-
-#ifndef CONFIG_SMP
-       {
-               /* Put empty_pg_dir on pgd_quicklist */
-               extern pgd_t empty_pg_dir[1024];
-               unsigned long addr = (unsigned long)empty_pg_dir;
-               unsigned long alias_base = kern_base + PAGE_OFFSET -
-                       (long)(KERNBASE);
-               
-               memset(empty_pg_dir, 0, sizeof(empty_pg_dir));
-               addr += alias_base;
-               free_pgd_fast((pgd_t *)addr);
-               num_physpages++;
-               totalram_pages++;
-       }
-#endif
 
        printk("Memory: %uk available (%ldk kernel code, %ldk data, %ldk init) 
[%016lx,%016lx]\n",
               nr_free_pages() << (PAGE_SHIFT-10),
diff -Nru a/arch/sparc64/mm/tlb.c b/arch/sparc64/mm/tlb.c
--- a/arch/sparc64/mm/tlb.c     2005-04-03 21:13:56 -07:00
+++ b/arch/sparc64/mm/tlb.c     2005-04-03 21:13:56 -07:00
@@ -73,6 +73,7 @@
        }
 
 no_cache_flush:
+
        if (mp->tlb_frozen)
                return;
 
@@ -149,11 +150,4 @@
        }
        if (nr)
                flush_tlb_pending();
-}
-
-unsigned long __ptrs_per_pmd(void)
-{
-       if (test_thread_flag(TIF_32BIT))
-               return (1UL << (32 - (PAGE_SHIFT-3) - PAGE_SHIFT));
-       return REAL_PTRS_PER_PMD;
 }
diff -Nru a/include/asm-sparc64/cpudata.h b/include/asm-sparc64/cpudata.h
--- a/include/asm-sparc64/cpudata.h     2005-04-03 21:13:56 -07:00
+++ b/include/asm-sparc64/cpudata.h     2005-04-03 21:13:56 -07:00
@@ -19,7 +19,7 @@
 
        /* Dcache line 2 */
        unsigned int    pgcache_size;
-       unsigned int    pgdcache_size;
+       unsigned int    __pad1;
        unsigned long   *pte_cache[2];
        unsigned long   *pgd_cache;
 } cpuinfo_sparc;
diff -Nru a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h
--- a/include/asm-sparc64/pgalloc.h     2005-04-03 21:13:56 -07:00
+++ b/include/asm-sparc64/pgalloc.h     2005-04-03 21:13:56 -07:00
@@ -22,74 +22,12 @@
        unsigned long *pgd_cache;
        unsigned long *pte_cache[2];
        unsigned int pgcache_size;
-       unsigned int pgdcache_size;
 } pgt_quicklists;
 #endif
 #define pgd_quicklist          (pgt_quicklists.pgd_cache)
 #define pmd_quicklist          ((unsigned long *)0)
 #define pte_quicklist          (pgt_quicklists.pte_cache)
 #define pgtable_cache_size     (pgt_quicklists.pgcache_size)
-#define pgd_cache_size         (pgt_quicklists.pgdcache_size)
-
-#ifndef CONFIG_SMP
-
-static __inline__ void free_pgd_fast(pgd_t *pgd)
-{
-       struct page *page = virt_to_page(pgd);
-
-       preempt_disable();
-       if (!page->lru.prev) {
-               page->lru.next = (void *) pgd_quicklist;
-               pgd_quicklist = (unsigned long *)page;
-       }
-       page->lru.prev = (void *)
-         (((unsigned long)page->lru.prev) |
-          (((unsigned long)pgd & (PAGE_SIZE / 2)) ? 2 : 1));
-       pgd_cache_size++;
-       preempt_enable();
-}
-
-static __inline__ pgd_t *get_pgd_fast(void)
-{
-        struct page *ret;
-
-       preempt_disable();
-        if ((ret = (struct page *)pgd_quicklist) != NULL) {
-                unsigned long mask = (unsigned long)ret->lru.prev;
-               unsigned long off = 0;
-
-               if (mask & 1)
-                       mask &= ~1;
-               else {
-                       off = PAGE_SIZE / 2;
-                       mask &= ~2;
-               }
-               ret->lru.prev = (void *) mask;
-               if (!mask)
-                       pgd_quicklist = (unsigned long *)ret->lru.next;
-                ret = (struct page *)(__page_address(ret) + off);
-                pgd_cache_size--;
-               preempt_enable();
-        } else {
-               struct page *page;
-
-               preempt_enable();
-               page = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
-               if (page) {
-                       ret = (struct page *)page_address(page);
-                       page->lru.prev = (void *) 2UL;
-
-                       preempt_disable();
-                       page->lru.next = (void *) pgd_quicklist;
-                       pgd_quicklist = (unsigned long *)page;
-                       pgd_cache_size++;
-                       preempt_enable();
-               }
-        }
-        return (pgd_t *)ret;
-}
-
-#else /* CONFIG_SMP */
 
 static __inline__ void free_pgd_fast(pgd_t *pgd)
 {
@@ -123,8 +61,6 @@
 {
        free_page((unsigned long)pgd);
 }
-
-#endif /* CONFIG_SMP */
 
 #ifdef DCACHE_ALIASING_POSSIBLE
 #define VPTE_COLOR(address)            (((address) >> (PAGE_SHIFT + 10)) & 1UL)
diff -Nru a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
--- a/include/asm-sparc64/pgtable.h     2005-04-03 21:13:56 -07:00
+++ b/include/asm-sparc64/pgtable.h     2005-04-03 21:13:56 -07:00
@@ -59,44 +59,24 @@
 #define PMD_SHIFT      (PAGE_SHIFT + (PAGE_SHIFT-3))
 #define PMD_SIZE       (1UL << PMD_SHIFT)
 #define PMD_MASK       (~(PMD_SIZE-1))
-#define PMD_BITS       11
+#define PMD_BITS       (PAGE_SHIFT - 2)
 
 /* PGDIR_SHIFT determines what a third-level page table entry can map */
 #define PGDIR_SHIFT    (PAGE_SHIFT + (PAGE_SHIFT-3) + PMD_BITS)
 #define PGDIR_SIZE     (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK     (~(PGDIR_SIZE-1))
+#define PGDIR_BITS     (PAGE_SHIFT - 2)
 
 #ifndef __ASSEMBLY__
 
 #include <linux/sched.h>
 
 /* Entries per page directory level. */
-#define PTRS_PER_PTE           (1UL << (PAGE_SHIFT-3))
-
-/* We the first one in this file, what we export to the kernel
- * is different so we can optimize correctly for 32-bit tasks.
- */
-#define REAL_PTRS_PER_PMD      (1UL << PMD_BITS)
-
-/* This is gross, but unless we do this gcc retests the
- * thread flag every interation in pmd traversal loops.
- */
-extern unsigned long __ptrs_per_pmd(void) __attribute_const__;
-#define PTRS_PER_PMD           __ptrs_per_pmd()
-
-/*
- * We cannot use the top address range because VPTE table lives there. This
- * formula finds the total legal virtual space in the processor, subtracts the
- * vpte size, then aligns it to the number of bytes mapped by one pgde, and
- * thus calculates the number of pgdes needed.
- */
-#define PTRS_PER_PGD (((1UL << VA_BITS) - VPTE_SIZE + (1UL << (PAGE_SHIFT + \
-                     (PAGE_SHIFT-3) + PMD_BITS)) - 1) / (1UL << (PAGE_SHIFT + \
-                     (PAGE_SHIFT-3) + PMD_BITS)))
+#define PTRS_PER_PTE   (1UL << (PAGE_SHIFT-3))
+#define PTRS_PER_PMD   (1UL << PMD_BITS)
+#define PTRS_PER_PGD   (1UL << PGDIR_BITS)
 
 /* Kernel has a separate 44bit address space. */
-#define USER_PTRS_PER_PGD      ((const int)(test_thread_flag(TIF_32BIT)) ? \
-                                (1) : (PTRS_PER_PGD))
 #define FIRST_USER_PGD_NR      0
 
 #define pte_ERROR(e)   __builtin_trap()
@@ -235,8 +215,8 @@
 
 /* PFNs are real physical page numbers.  However, mem_map only begins to record
  * per-page information starting at pfn_base.  This is to handle systems where
- * the first physical page in the machine is at some huge physical address, 
such
- * as 4GB.   This is common on a partitioned E10000, for example.
+ * the first physical page in the machine is at some huge physical address,
+ * such as 4GB.   This is common on a partitioned E10000, for example.
  */
 
 #define pfn_pte(pfn, prot)     \
@@ -307,7 +287,7 @@
 #define pte_mkdirty(pte)       (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W))
 
 /* to find an entry in a page-table-directory. */
-#define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD))
+#define pgd_index(address)     (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 
1))
 #define pgd_offset(mm, address)        ((mm)->pgd + pgd_index(address))
 
 /* to find an entry in a kernel page-table-directory */
@@ -321,7 +301,7 @@
 /* Find an entry in the second-level page table.. */
 #define pmd_offset(pudp, address)      \
        ((pmd_t *) pud_page(*(pudp)) + \
-        (((address) >> PMD_SHIFT) & (REAL_PTRS_PER_PMD-1)))
+        (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)))
 
 /* Find an entry in the third-level page table.. */
 #define pte_index(dir, address)        \
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to