Page Table Handling (Bunches of Func/Macro)

For a more detailed description please see the book.

 

Page Table Entry Macros

  • pte_t, pmd_t, pud_t, pgd_t: Describe each level of paging’s format. 64 bit with PAE 32 bit without PAE.
    • These are often just uint they are declared as structs for protection so they will not be used inappropiately
    • Addressing more than 4 Gb of RAM uses 4 extra bits (36 on address bus) entries for that will be stored as addition vars (?) on the struct
    • pgprot_t: Protecion flags are stored as part of the struct
  • pgprot_t: Represents protection flags associated with a single entry.  64 bit with PAE 32 without
  • __pte, __pmd, __pud, __pgd, __pgprot: These 5 macros convert an uint into a page ___ entry type
  • pte_val, pmd_val, pud_val, pgd_val, pgprot_val: Convert a page ___ entry into a uint type

Page Table Entry Macros and Functions for Read/Modify

  • pte_none, pmd_none, pud_none, and pgd_none: Yield 1 if entry is 0 otherwise yield 0
  • pte_clear, pmd_clear, pud_clear, and pgd_clear: Clear entry in corresponding page table stops any process from accessing the linear address used by that page table entry.
  • ptep_get_and_clear(): Returns previous entry at page table entry and clears it
  • set_pte, set_pmd, set_pud, and set_pgd: Write value to specific page table entry
    • Note when PAE is enabled set_pte_atomic will ensure that 64 bit architectures will be written automatically (?)
  • pte_same(a,b): returns 1 if if a, b refer to the same page and have same access priveleges.  0 otherwise.
  • pmd_large(e): Returns 1 if Page Middle Directory uses large pages (2Mb, 4Mb) else 0
Capture.PNG
pmd is used by 32 bit PAE, pmd is ignored by 32 bit no PAE, pmd and pud are ignored when using 32 bit no pae.  Therefore only pmd_bad varies in 0 or 1 because it is the only end point in contact with page frames depending on the setup.
  • pmd_bad: Value is 1 if entry points to bad page table. 0 otherwise
    • What defines bad?
      1. Page not in main memory (present flag cleared)
      2. Page only allows read access (Read/write flag cleared)
      3. Accessed or Dirty cleared.  (Note: Linux forces these flags to always be set for every existing Page Table should never happen)
  • pud_bad, pgd_bad : Always yields 0.
  • pte_bad: Is not defined.  Legal for a Page Table entry to refer to a page that is not present in main memory, not writable, or not accessible at all.
  • pte_present: Yields 1 if either present Flag or Page Size is 1 in a Page Table entry
    • Page Size flag in Page Table entries has no meaning for the paging unit.  The kernel, however, marks Present equal to 0 and Page Size equal to 1 for
      the pages present in main memory but without read, write, or execute privileges.

      • Access to such pages triggers a Page Fault exception because Present is
        cleared, and the kernel can detect that the fault is not due to a missing page by checking the value of Page Size.
  • pmd_present:  Yields the value 1 if the Present flag of the corresponding
    entry is equal to 1 aka in main memory

Creating and Deleting Page Directories

  • 2/3 Level paging Page Upper Directory is always mapped as a single entry in the Page Global Directory
  • 2 Level Paging (No PAE 32 bit)
    • Using the picture above the only 2 relevant levels of paging are the Page Global Directory (Page Directory) and Page Table (Page Table)
    • Recall in the discussion of paging in Linux this means Upper/Middle directories are just one entry in the PGD. and thus can be easily allocated
    • Page Tables allocation is more complex.
      • It may not exist yet.  Allocate a new page frame fill with zeros and then add entry
  • 3 Level Paging (PAE enabled 32 bit)
    • When enabled the Page Global Directory becomes the PDPT and thus 4 Page Middle Directories must be allocated

 

The following are some functions with definitions which will be important later for now just know they exist.

Page Flag Reading Functions


pte_user(); //Reads User/Supervisor Flag

pte_read(); //Reads the User/Supervisor flag (pages on the 80 × 86 processor can-
not be protected against reading)

pte_write(); //Reads the Read/Write flag

pte_exec(); //Reads the User/Supervisor flag (pages on the 80x 86 processor cannot be
protected against code execution)

pte_dirty(); //Reads the Dirty flag

pte_young(); //Reads the Accessed flag

pte_file(); //Reads the Dirty flag (when the Present flag is cleared and the Dirty flag
is set, the page belongs to a non-linear disk file mapping; see Chapter 16)

Page Flag Setting Functions


mk_pte_huge( ); // Sets the Page Size and Present flags of a Page Table entry

pte_wrprotect( ); //Clears the Read/Write flag

pte_rdprotect( ); //Clears the User/Supervisor flag

pte_exprotect( ); //Clears the User/Supervisor flag

pte_mkwrite( ); //Sets the Read/Write flag

pte_mkread( ); //Sets the User/Supervisor flag

pte_mkexec( ); //Sets the User/Supervisor flagpte_mkclean( ); //Clears the Dirty flag

pte_mkdirty( ); //Sets the Dirty flag

pte_mkold( ); //Clears the Accessed flag (makes the page old)

pte_mkyoung( ); //Sets the Accessed flag (makes the page young)

pte_modify(p,v); //Sets all access rights in a Page Table entry p to a specified value v

ptep_set_wrprotect(); //Like pte_wrprotect(), but acts on a pointer to a Page Table entry

ptep_set_access_flags(); //If the Dirty flag is set, sets the page’s access rights to a specified value and invokes flush_tlb_page() (see the section “ Translation Lookaside Buffers (TLB)” later in this chapter)
ptep_mkdirty(); //Like pte_mkdirty() but acts on a pointer to a Page Table entry

ptep_test_and_clear_dirty(); //Like pte_mkclean() but acts on a pointer to a Page Table entry and returns the old value of the flag

ptep_test_and_clear_young() Like pte_mkold() but acts on a pointer to a Page Table entry and returns the old value of the flag

Macros Acting on Page Table Entries

  • Combines page address and flags to make page table entry
  • Or the reverse and extract page address from page table entry
pgd_index(addr); //Yields the index (relative position) of the entry in the Page Global Directory that maps the linear address addr.

pgd_offset(mm, addr); //Receives as parameters the address of a memory descriptor cw (see Chapter 9) and a linear address addr. The macro yields the linear address of the entry in a Page Global Directory that corresponds to the address addr; the Page Global Directory is found through a pointer within the memory descriptor.

pgd_offset_k(addr); //Yields the linear address of the entry in the master kernel Page Global Directory that corresponds to the address addr (see the later section “ Kernel Page Tables”).

pgd_page(pgd); //Yields the page descriptor address of the page frame containing the Page
Upper Directory referred to by the Page Global Directory entry pgd. In a two-or three-level paging system, this macro is equivalent to pud_page() applied to the folded Page Upper Directory entry.

pud_offset(pgd, addr); //Receives as parameters a pointer pgd to a Page Global Directory entry and a linear address addr. The macro yields the linear address of the entry in a
Page Upper Directory that corresponds to addr. In a two- or three-level paging system, this macro yields pgd, the address of a Page Global Directory entry.

pud_page(pud); //Yields the linear address of the Page Middle Directory referred to by the Page Upper Directory entry pud. In a two-level paging system, this macro is equivalent to pmd_page() applied to the folded Page Middle Directory entry.

pmd_index(addr); //Yields the index (relative position) of the entry in the Page Middle Directorythat maps the linear address addr.

pmd_offset(pud, addr); //Receives as parameters a pointer pud to a Page Upper Directory entry and a linear address addr. The macro yields the address of the entry in a Page Middle Directory that corresponds to addr. In a two-level paging system, it yields pud, the address of a Page Global Directory entry.

pmd_page(pmd); //Yields the page descriptor address of the Page Table referred to by the Page Middle Directory entry pmd. In a two-level paging system, pmd is actually an entry of a Page Global Directory.

mk_pte(p,prot); //Receives as parameters the address of a page descriptor p and a group of
access rights prot, and builds the corresponding Page Table entry.

pte_index(addr); //Yields the index (relative position) of the entry in the Page Table that maps the linear address addr.

pte_offset_kernel(dir, addr); //Yields the linear address of the Page Table that corresponds to the linear address addr mapped by the Page Middle Directory dir. Used only on the
master kernel page tables (see the later section “Kernel Page Tables”).

pte_offset_map(dir, addr); //Receives as parameters a pointer dir to a Page Middle Directory entry and a linear address addr; it yields the linear address of the entry in the Page Table that corresponds to the linear address addr. If the Page Table is kept in high memory, the kernel establishes a temporary kernel mapping (see the section “Kernel Mappings of High-Memory Page Frames”in Chapter 8), to be released by means of pte_unmap. The macros pte_offset_map_nested and pte_unmap_nested are identical, but they use a different temporary kernel mapping.

pte_page(x); //Returns the page descriptor address of the page referenced by the Page Table
entry x .

pte_to_pgoff(pte); //Extracts from the content pte of a Page Table entry the file offset corresponding to a page belonging to a non-linear file memory mapping (see the section “Non-Linear Memory Mappings” in Chapter 16).

pgoff_to_pte(offset); //Sets up the content of a Page Table entry for a page belonging to a non-linear file memory mapping.

Page Allocation Functions


pgd_alloc(mm); //Allocates a new Page Global Directory; if PAE is enabled, it also allocates the three children Page Middle Directories that map the User Mode linear addresses. The argument mm (the address of a memory descriptor) is ignored on the 80x 86 architecture.

pgd_free( pgd); //Releases the Page Global Directory at address pgd; if PAE is enabled, it also releases the three Page Middle Directories that map the User Mode linear addresses.

pud_alloc(mm, pgd, addr); //In a two- or three-level paging system, this function does nothing: it simply returns the linear address of the Page Global Directory entry pgd.

pud_free(x); //In a two- or three-level paging system, this macro does nothing.

pmd_alloc(mm, pud, addr); //Defined so generic three-level paging systems can allocate a new Page Middle Directory for the linear address addr. If PAE is not enabled, the function simply returns the input parameter pud— that is, the address of the entry in the Page Global Directory. If PAE is enabled, the function returns the linear address of the Page Middle Directory entry that maps the linear address addr. The argument cw is ignored.

pmd_free(x); //Does nothing, because Page Middle Directories are allocated and deallocated
together with their parent Page Global Directory.

pte_alloc_map(mm, pmd, addr); //Receives as parameters the address of a Page Middle Directory entry pmd and a linear address addr, and returns the address of the Page Table entry corresponding to addr. If the Page Middle Directory entry is null, the function allocates a new Page Table by invoking pte_alloc_one( ). If a new Page Table is allocated, the entry corresponding to addr is initialized and the User/Supervisor flag is set. If the Page Table is kept in high memory, the kernel establishes a temporary kernel mapping (see the section “Kernel Mappings of High-Memory Page Frames” in Chapter 8), to be released by pte_unmap.

pte_alloc_kernel(mm, pmd, addr); //If the Page Middle Directory entry pmd associated with the address addr is null, the function allocates a new Page Table. It then returns the linear address of the Page Table entry associated with addr. Used only for master kernel page tables (see the later section “Kernel Page Tables”).

pte_free( pte); //Releases the Page Table associated with the pte page descriptor pointer.

pte_free_kernel(pte); //Equivalent to pte_free(), but used for master kernel page tables.

clear_page_range(mmu,start,end); //Clears the contents of the page tables of a process from linear address start to end by iteratively releasing its Page Tables and clearing the Page Middle Directory entries.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s