Changeset c520034 in mainline for kernel/genarch/src/mm/page_pt.c


Ignore:
Timestamp:
2011-12-31T18:19:35Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
295f658, 77c2b02, 96cd5b4
Parents:
852052d (diff), 22f0561 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Support for kernel non-identity mappings, phase I.

  • identity/non-identity kernel memory split on all architectures
  • low/high physical memory split on all architectures
  • frame allocator understands low/high memory
  • high physical memory currently unused (Phase II)
  • more compact frame_t
  • zone conf frames, pte_t, kernel stacks allocated from low memory
  • lockless TLB-miss handlers everywhere (newly sparc64, ia64)
  • preallocate PTL1 page tables for non-identity and prevent their deallocation
  • hw_map() unification
  • new resource allocator used for allocating kernel virtual addresses

Breakage:

  • sparc64/sun4v creates too large kernel identity; not fixed because of lack of testing hw
  • ppc32's tlb_refill() seems wrong as it creates too large kernel identity, but appears unused and the architecture works normally

Not implemented yet (phase II):

  • allow high memory to be used for common kernel allocations
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/mm/page_pt.c

    r852052d rc520034  
    3939#include <mm/page.h>
    4040#include <mm/frame.h>
     41#include <mm/km.h>
    4142#include <mm/as.h>
    4243#include <arch/mm/page.h>
     
    4546#include <arch/asm.h>
    4647#include <memstr.h>
     48#include <align.h>
     49#include <macros.h>
    4750
    4851static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    4952static void pt_mapping_remove(as_t *, uintptr_t);
    5053static pte_t *pt_mapping_find(as_t *, uintptr_t, bool);
     54static void pt_mapping_make_global(uintptr_t, size_t);
    5155
    5256page_mapping_operations_t pt_mapping_operations = {
    5357        .mapping_insert = pt_mapping_insert,
    5458        .mapping_remove = pt_mapping_remove,
    55         .mapping_find = pt_mapping_find
     59        .mapping_find = pt_mapping_find,
     60        .mapping_make_global = pt_mapping_make_global
    5661};
    5762
     
    7580       
    7681        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) {
    77                 pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE, FRAME_KA);
     82                pte_t *newpt = (pte_t *) frame_alloc(PTL1_SIZE,
     83                    FRAME_LOWMEM | FRAME_KA);
    7884                memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0);
    7985                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
    80                 SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
     86                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page),
     87                    PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     88                    PAGE_WRITE);
    8189        }
    8290       
     
    8492       
    8593        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) {
    86                 pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE, FRAME_KA);
     94                pte_t *newpt = (pte_t *) frame_alloc(PTL2_SIZE,
     95                    FRAME_LOWMEM | FRAME_KA);
    8796                memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0);
    8897                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
    89                 SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
     98                SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page),
     99                    PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     100                    PAGE_WRITE);
    90101        }
    91102       
     
    93104       
    94105        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) {
    95                 pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE, FRAME_KA);
     106                pte_t *newpt = (pte_t *) frame_alloc(PTL3_SIZE,
     107                    FRAME_LOWMEM | FRAME_KA);
    96108                memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0);
    97109                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
    98                 SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE);
     110                SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page),
     111                    PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     112                    PAGE_WRITE);
    99113        }
    100114       
     
    123137        /*
    124138         * First, remove the mapping, if it exists.
    125          *
    126139         */
    127140       
     
    140153        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
    141154       
    142         /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
     155        /*
     156         * Destroy the mapping.
     157         * Setting to PAGE_NOT_PRESENT is not sufficient.
     158         */
    143159        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    144160       
    145161        /*
    146          * Second, free all empty tables along the way from PTL3 down to PTL0.
    147          *
     162         * Second, free all empty tables along the way from PTL3 down to PTL0
     163         * except those needed for sharing the kernel non-identity mappings.
    148164         */
    149165       
     
    162178                /*
    163179                 * PTL3 is empty.
    164                  * Release the frame and remove PTL3 pointer from preceding table.
    165                  *
    166                  */
    167                 frame_free(KA2PA((uintptr_t) ptl3));
     180                 * Release the frame and remove PTL3 pointer from the parent
     181                 * table.
     182                 */
    168183#if (PTL2_ENTRIES != 0)
    169184                memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
     
    171186                memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
    172187#else
     188                if (km_is_non_identity(page))
     189                        return;
     190
    173191                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    174192#endif
     193                frame_free(KA2PA((uintptr_t) ptl3));
    175194        } else {
    176195                /*
     
    195214                /*
    196215                 * PTL2 is empty.
    197                  * Release the frame and remove PTL2 pointer from preceding table.
    198                  *
    199                  */
    200                 frame_free(KA2PA((uintptr_t) ptl2));
     216                 * Release the frame and remove PTL2 pointer from the parent
     217                 * table.
     218                 */
    201219#if (PTL1_ENTRIES != 0)
    202220                memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
    203221#else
     222                if (km_is_non_identity(page))
     223                        return;
     224
    204225                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    205226#endif
     227                frame_free(KA2PA((uintptr_t) ptl2));
    206228        } else {
    207229                /*
     
    227249                /*
    228250                 * PTL1 is empty.
    229                  * Release the frame and remove PTL1 pointer from preceding table.
    230                  *
    231                  */
     251                 * Release the frame and remove PTL1 pointer from the parent
     252                 * table.
     253                 */
     254                if (km_is_non_identity(page))
     255                        return;
     256
     257                memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    232258                frame_free(KA2PA((uintptr_t) ptl1));
    233                 memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
    234259        }
    235260#endif /* PTL1_ENTRIES != 0 */
     
    267292}
    268293
     294/** Make the mappings in the given range global accross all address spaces.
     295 *
     296 * All PTL0 entries in the given range will be mapped to a next level page
     297 * table. The next level page table will be allocated and cleared.
     298 *
     299 * pt_mapping_remove() will never deallocate these page tables even when there
     300 * are no PTEs in them.
     301 *
     302 * @param as   Address space.
     303 * @param base Base address corresponding to the first PTL0 entry that will be
     304 *             altered by this function.
     305 * @param size Size in bytes defining the range of PTL0 entries that will be
     306 *             altered by this function.
     307 */
     308void pt_mapping_make_global(uintptr_t base, size_t size)
     309{
     310        uintptr_t ptl0 = PA2KA((uintptr_t) AS_KERNEL->genarch.page_table);
     311        uintptr_t ptl0step = (((uintptr_t) -1) / PTL0_ENTRIES) + 1;
     312        size_t order;
     313        uintptr_t addr;
     314
     315#if (PTL1_ENTRIES != 0)
     316        order = PTL1_SIZE;
     317#elif (PTL2_ENTRIES != 0)
     318        order = PTL2_SIZE;
     319#else
     320        order = PTL3_SIZE;
     321#endif
     322
     323        ASSERT(ispwr2(ptl0step));
     324
     325        for (addr = ALIGN_DOWN(base, ptl0step); addr < base + size;
     326            addr += ptl0step) {
     327                uintptr_t l1;
     328
     329                l1 = (uintptr_t) frame_alloc(order, FRAME_KA | FRAME_LOWMEM);
     330                memsetb((void *) l1, FRAME_SIZE << order, 0);
     331                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1));
     332                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr),
     333                    PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     334                    PAGE_WRITE);
     335        }
     336}
     337
    269338/** @}
    270339 */
Note: See TracChangeset for help on using the changeset viewer.