- pgd_none() - Determines if the specified PGD entry is empty.
- pud_none() - Determines if the specified PUD entry is empty.
- pmd_none() - Determines if the specified PMD entry is empty.
- pte_none() - Determines if the specified PTE entry is empty.
- pgd_bad() - Determines if the specified PGD entry or its descendants are not in a safe state to be modified.
- pud_bad() - Determines if the specified PUD entry or its descendants are not in a safe state to be modified.
- pmd_bad() - Determines if the specified PMD entry or its descendants are not in a safe state to be modified.
- pgd_flags() - Retrieves bitfield containing the specified PGD entry's flags.
- pud_flags() - Retrieves bitfield containing the specified PUD entry's flags.
- pmd_flags() - Retrieves bitfield containing the specified PMD entry's flags.
- pte_flags() - Retrieves bitfield containing the specified PTE entry's flags.
- pud_pgprot() - Retrieves bitfield containing the specified PUD entry's flags wrapped in a pgprot_t.
- pmd_pgprot() - Retrieves bitfield containing the specified PMD entry's flags wrapped in a pgprot_t.
- pte_pgprot() - Retrieves bitfield containing the specified PTE entry's flags wrapped in a pgprot_t.
- __pgprot() - Converts the specified pgprotval_t into a pgprot_t.
- massage_pgprot() - Masks the specified pgprot_t fields against all possible flags, returns pgprotval_t.
- canon_pgprot() - Masks the specified pgprot_t fields against all possible flags, returns pgprot_t.
- pmd_set_flags() - Returns a new copy of a PMD with the specified bitfield appended to its flag bitfield.
- pte_set_flags() - Returns a new copy of a PTE with the specified bitfield appended to its flag bitfield.
- pmd_clear_flags() - Returns a new copy of a PMD with the specified bitfield cleared from its flag bitfield.
- pte_clear_flags() - Returns a new copy of a PTE with the specified bitfield cleared from its flag bitfield.
NOTE: Confusingly, the pXX_<flag>()
functions retrieve flags from the
specified pXX
entry, however they refer to the pointed at page,
e.g. pgd_present()
determines if the pointed at PUD page is present.
- pgd_present() - Determines if the pointed at PUD page is present, i.e. resident in memory.
- pud_present() - Determines if the pointed at PMD page is present, i.e. resident in memory.
- pmd_present() - Determines if the pointed at PTE page is present, i.e. resident in memory.
- pte_present() - Determines if the pointed at physical page is present, i.e. resident in memory.
- pmd_young() - Determines if the PTE page pointed at by the specified PMD entry has been accessed.
- pte_young() - Determines if the physical page pointed at by the specified PTE entry has been accessed.
- pmd_dirty() - Determines if the PTE page pointed at by the specified PMD entry has been modified.
- pte_dirty() - Determines if the physical page pointed at by the specified PTE entry has been modified.
- pmd_write() - Determines if the PTE page pointed at by the specified PMD entry is writable.
- pte_write() - Determines if the physical page pointed at by the specified PTE entry is writable.
- pte_exec() - Determines if the physical page pointed at by the specified PTE entry is executable.
- pte_global() - Determines whether ordinary TLB flushes do not clear the specified PTE entry mapping.
- pte_special() - Determines if the PTE entry is marked special.
- pmd_soft_dirty() - Determines if the PMD entry is marked soft-dirty.
- pte_soft_dirty() - Determines if the PTE entry is marked soft-dirty.
- pmd_devmap() - Determines if the PTE page pointed at by the specified PMD entry is part of a device mapping.
- pte_devmap() - Determines if the physical page pointed at by the specified PTE entry is part of a device mapping.
- pud_huge() - Determines if the PMD page pointed at by the specified PUD entry is huge in the context of hugetlb.
- pmd_huge() - Determines if the PTE page pointed at by the specified PMD entry is huge in the context of hugetlb.
- pte_huge() - Determines if the physical page pointed at by the specified PTE entry is huge (without context.)
- pmd_trans_huge() - Determines if the PTE page pointed at by the specified PMD entry is a transparent huge page.
- pgd_large() - Determines if the pointed at PUD page is huge (without context.)
- pud_large() - Determines if the pointed at PMD page is huge (without context.)
- pmd_large() - Determines if the pointed at PTE page is huge (without context.)
- pmd_mkyoung() - Returns a new copy of the specified PMD entry with the accessed flag set.
- pmd_mkold() - Returns a new copy of the specified PMD entry with the accessed flag cleared.
- pte_mkyoung() - Returns a new copy of the specified PTE entry with the accessed flag set.
- pte_mkold() - Returns a new copy of the specified PTE entry with the accessed flag cleared.
- pmd_mkdirty() - Returns a new copy of the specified PMD entry with the dirty (modified) flag set.
- pmd_mkclean() - Returns a new copy of the specified PMD entry with the dirty (modified) flag cleared.
- pte_mkdirty() - Returns a new copy of the specified PTE entry with the dirty (modified) flag set.
- pte_mkclean() - Returns a new copy of the specified PTE entry with the dirty (modified) flag cleared.
- pmd_mkwrite() - Returns a new copy of the specified PMD entry with the read/write flag set.
- pmd_wrprotect() - Returns a new copy of the specified PMD entry with the read/write flag cleared.
- pte_mkwrite() - Returns a new copy of the specified PTE entry with the read/write flag set.
- pte_wrprotect() - Returns a new copy of the specified PTE entry with the read/write flag cleared.
- pmd_mksoft_dirty() - Returns a new copy of the specified PMD entry with the soft-dirty flag set.
- pmd_clear_soft_dirty() - Returns a new copy of the specified PMD entry with the soft-dirty flag cleared.
- pte_mksoft_dirty() - Returns a new copy of the specified PTE entry with the soft-dirty flag set.
- pte_clear_soft_dirty() - Returns a new copy of the specified PTE entry with the soft-dirty flag cleared.
- pmd_mkdevmap() - Returns a new copy of the specified PMD entry with the devmap flag set.
- pte_mkdevmap() - Returns a new copy of the specified PTE entry with the devmap flag cleared.
- pmd_mknotpresent() - Returns a new copy of the specified PMD entry with the present flag cleared, i.e. indicating the underlying PTE page is not resident.
- pte_mkglobal() - Returns a new copy of the specified PTE entry with the global flag set, avoiding TLB flushes.
- pte_clrglobal() - Returns a new copy of the specified PTE entry with the global flag cleared.
- pte_mkexec() - Returns a new copy of the specified PTE entry with the NX flag cleared, marking the underlying physical page executable.
- pte_mkspecial() - Returns a new copy of the specified PTE entry with the special flag set.
- pmd_mkhuge() - Returns a new copy of the specified PMD entry with the huge page flag set.
- pte_mkhuge() - Returns a new copy of the specified PTE entry with the huge page flag set.
- pte_clrhuge() - Returns a new copy of the specified PTE entry with the huge page flag cleared.
int pgd_none(pgd_t pgd)
pgd_none() determines whether the specified PGD entry is empty.
pgd
- PGD entry which we want to determine is empty or not.
1 if the PGD entry is empty, 0 if not.
int pud_none(pud_t pud)
pud_none() determines whether the specified PUD entry is empty.
pud
- PUD entry which we want to determine is empty or not.
1 if the PUD entry is empty, 0 if not.
int pmd_none(pmd_t pmd)
pmd_none() determines whether the specified PMD entry is empty.
pmd
- PMD entry which we want to determine is empty or not.
1 if the PMD entry is empty, 0 if not.
int pte_none(pte_t pte)
pte_none() determines whether the specified PTE entry is empty.
pte
- PTE entry which we want to determine is empty or not.
1 if the PTE entry is empty, 0 if not.
int pgd_bad(pgd_t pgd)
pgd_bad() determines whether the specified PGD entry itself is not in a state where it, or descendent tables, can be safely modified.
NOTE: It seems to me that it also determines whether a page table entry is in a consistent state at all, since page tables that are empty/swapped out/read-only make no sense for the purposes of page table traversal (discussed below), but based on the definition from Understanding the Linux Virtual Memory Manager and what I've found online so far, 'modifiability' seems to be the canonical explanation so far, so I'm being conservative and sticking with that. On other architectures it seems the definition is more nebulous, I briefly looked into this recently where the definition was - does this entry actually refer to a lower level table.
In x86-64 the test consists of checking that the _PAGE_PRESENT
, _PAGE_RW
,
_PAGE_ACCESSED
and _PAGE_DIRTY
flags are set.
It's important to keep in mind that the PGD entry, if non-empty, contains the physical address/swap metadata for the page that contains a corresponding PUD.
If the page isn't present (e.g., but not only, swapped out) then modifying the entry itself will overwrite metadata, adjusting flags on the assumption the entry is a physical address may result in invalid state, and trying to traverse the entry in order to modify a lower level entry will not work since the entry is not a physical address.
If the page isn't set dirty/accessed this would imply that the PUD page contains no entries, which would make no sense - a PGD entry pointing to an empty PUD indicates inconsistent state.
Finally, if the page is read-only then clearly its descendant entries cannot be
modified and presumably the read-only provision indicates that the entry's flags
should also not be adjusted (other than code that is knowingly and intentionally
removing the read-only status, which will not be performing a pgd_bad()
check.)
pgd
- PGD entry we either (potentially) intend to modify or whose descendants we (potentially) intend to modify.
Truthy (non-zero) if the PGD entry or its descendants are unsafe to modify.
int pud_bad(pud_t pud)
pud_bad() determines whether the specified PUD entry itself is not in a state where it, or descendent tables, can be safely modified.
NOTE: It seems to me that it also determines whether a page table entry is in a consistent state at all, since page tables that are marked empty/swapped out/read-only make no sense for the purposes of page table traversal (discussed below), but based on the definition from Understanding the Linux Virtual Memory Manager and what I've found online so far, 'modifiability' seems to be the canonical explanation so far, so I'm being conservative and sticking with that. On other architectures it seems the definition is more nebulous, I briefly looked into this recently where the definition was - does this entry actually refer to a lower level table.
In x86-64 the test consists of checking that the _PAGE_PRESENT
, _PAGE_RW
,
_PAGE_ACCESSED
and _PAGE_DIRTY
flags are set.
It's important to keep in mind that the PUD entry, if non-empty, contains the physical address/swap metadata for the page that contains a corresponding PMD.
If the page isn't present (e.g., but not only, swapped out) then modifying the entry itself will overwrite metadata, adjusting flags on the assumption the entry is a physical address may result in invalid state, and trying to traverse the entry in order to modify a lower level entry will not work since the entry is not a physical address.
If the page isn't set dirty/accessed this would imply that the PMD page contains no entries, which would make no sense - a PUD entry pointing to an empty PMD indicates inconsistent state.
Finally, if the page is read-only then clearly its descendant entries cannot be
modified and presumably the read-only provision indicates that the entry's flags
should also not be adjusted (other than code that is knowingly and intentionally
removing the read-only status, which will not be performing a pud_bad()
check.)
pud
- PUD entry we either (potentially) intend to modify or whose descendants we (potentially) intend to modify.
Truthy (non-zero) if the PUD entry or its descendants are unsafe to modify.
int pmd_bad(pmd_t pmd)
pmd_bad() determines whether the specified PMD entry itself is not in a state where it, or descendent tables, can be safely modified.
NOTE: It seems to me that it also determines whether a page table entry is in a consistent state at all, since page tables that are marked empty/swapped out/read-only make no sense for the purposes of page table traversal (discussed below), but based on the definition from Understanding the Linux Virtual Memory Manager and what I've found online so far, 'modifiability' seems to be the canonical explanation so far, so I'm being conservative and sticking with that. On other architectures it seems the definition is more nebulous, I briefly looked into this recently where the definition was - does this entry actually refer to a lower level table.
In x86-64 the test consists of checking that the _PAGE_PRESENT
, _PAGE_RW
,
_PAGE_ACCESSED
and _PAGE_DIRTY
flags are set.
It's important to keep in mind that the PMD entry, if non-empty, contains the physical address/swap metadata for the page that contains a corresponding PTE.
If the page isn't present (e.g., but not only, swapped out) then modifying the entry itself will overwrite metadata, adjusting flags on the assumption the entry is a physical address may result in invalid state, and trying to traverse the entry in order to modify a lower level entry will not work since the entry is not a physical address.
If the page isn't set dirty/accessed this would imply that the PTE page contains no entries, which would make no sense - a PMD entry pointing to an empty PTE indicates inconsistent state.
Finally, if the page is read-only then clearly its descendant entries cannot be
modified and presumably the read-only provision indicates that the entry's flags
should also not be adjusted (other than code that is knowingly and intentionally
removing the read-only status, which will not be performing a pmd_bad()
check.)
pmd
- PMD entry we either (potentially) intend to modify or whose descendants we (potentially) intend to modify.
Truthy (non-zero) if the PMD entry or its descendants are unsafe to modify.
pgdval_t pgd_flags(pgd_t pgd)
pgd_flags() retrieves a bitfield containing the flags associated with the specified PGD entry which, if the entry is non-empty, relate to the PUD whose physical address (or swap metadata) is contained within the entry.
Typically this won't be accessed directly, rather a function wrapper for a specific flag will be used.
pgd
- PGD entry whose flags we desire.
A bitfield containing the PGD entry's flags.
pudval_t pud_flags(pud_t pud)
pud_flags() retrieves a bitfield containing the flags associated with the specified PUD entry which, if the entry is non-empty, relate to the PMD whose physical address (or swap metadata) is contained within the entry.
Typically this won't be accessed directly, rather a function wrapper for a specific flag will be used.
pud
- PUD entry whose flags we desire.
A bitfield containing the PUD entry's flags.
pmdval_t pmd_flags(pmd_t pmd)
pmd_flags() retrieves a bitfield containing the flags associated with the specified PMD entry which, if the entry is non-empty, relate to the PTE whose physical address (or swap metadata) is contained within the entry.
Typically this won't be accessed directly, rather a function wrapper for a specific flag will be used.
pmd
- PMD entry whose flags we desire.
A bitfield containing the PMD entry's flags.
pteval_t pte_flags(pte_t pte)
pte_flags() retrieves a bitfield containing the flags associated with the specified PTE entry which, if the entry is non-empty, relate to the physical page whose physical address (or swap metadata) is contained within the entry.
Typically this won't be accessed directly, rather a function wrapper for a specific flag will be used.
pte
- PTE entry whose flags we desire.
A bitfield containing the PTE entry's flags.
pgprot_t pud_pgprot(pud_t pud)
pud_pgprot() retrieves the flags for the specified PUD entry via pud_flags and converts them to a pgprot_t via __pgprot().
As with pXX_t
the reason this has to exist is that pgprot_t
is a typedef struct
used to enforce type safety - typedef struct { pgprotval_t pgprot; } pgprot_t;
.
A pgprot_t containing the specified PUD entry's flags.
pgprot_t pmd_pgprot(pmd_t pmd)
pmd_pgprot() retrieves the flags for the specified PMD entry via pmd_flags and converts them to a pgprot_t via __pgprot().
As with pXX_t
the reason this has to exist is that pgprot_t
is a typedef struct
used to enforce type safety - typedef struct { pgprotval_t pgprot; } pgprot_t;
.
A pgprot_t containing the specified PMD entry's flags.
pgprot_t pte_pgprot(pte_t pte)
pte_pgprot() retrieves the flags for the specified PTE entry via pte_flags and converts them to a pgprot_t via __pgprot().
As with pXX_t
the reason this has to exist is that pgprot_t
is a typedef struct
used to enforce type safety - typedef struct { pgprotval_t pgprot; } pgprot_t;
.
A pgprot_t containing the specified PTE entry's flags.
pgprot_t __pgprot(pgprotval_t val)
__pgprot() wraps the specified pgprotval_t (unsigned long
in x86-64) into a pgprot_t structure.
As with pXX_t
the reason this has to exist is that pgprot_t
is a typedef struct
used to enforce type safety - typedef struct { pgprotval_t pgprot; } pgprot_t;
.
NOTE: Macro, inferring function signature.
val
- The pgprotval_t value which we want to translate into a pgprot_t.
A pgprot_t containing the specified pgprotval_t value.
pgprotval_t massage_pgprot(pgprot_t pgprot)
massage_pgprot() determines the value of the specified
pgprot_t argument via pgprot_val() and checks whether
the page is present (i.e. has the _PAGE_PRESENT
flag set) - if so, it returns
the pgprotval_t of the flags masked against all possible flag
values.
If the page is not present, then no masking takes place. As the code comment says, those flags can be used for other purposes when the page is not present so it is not appropriate to modify them in that case.
pgprot
- The pgprot_t value which needs to be masked against possible flag values.
A pgprotval_t containing the specified flag bitfield masked against all valid flags.
pgprot_t canon_pgprot(pgprot_t pgprot)
canon_pgprot() does the same task as
massage_pgprot(), however it uses __pgprot() to
wrap the pgprotval_t returned by massage_pgprot()
into a new
pgprot_t.
See the massage_pgprot()
definition above for more details on what it
achieves.
NOTE: Macro, inferring function signature.
pgprot
- The pgprot_t value which needs to be masked against possible flag values.
A pgprot_t containing the specified flag bitfield masked against all valid flags.
pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
pmd_set_flags() returns a new pmd_t which is identical
to the specified PMD entry except for the specified set
field which is
'appended' (i.e. bitwise-or'd) to the input PMD entry's flag bitfield.
No checks are performed to ensure set
is valid and limited only to available
flag bits, so incorrect use of this function could result in an invalid return
value.
-
pmd
- The PMD entry which we want to copy/update. -
set
- The flag bitfield we want to append to the newly created PMD entry.
A copy of the input PMD entry with set
appended to its flag bitfield.
pte_t pte_set_flags(pte_t pte, pteval_t set)
pte_set_flags() returns a new pte_t which is identical
to the specified PTE entry except for the specified set
field which is
'appended' (i.e. bitwise-or'd) to the input PTE entry's flag bitfield.
No checks are performed to ensure set
is valid and limited only to available
flag bits, so incorrect use of this function could result in an invalid return
value.
-
pte
- The PTE entry which we want to copy/update. -
set
- The flag bitfield we want to append to the newly created PTE entry.
A copy of the input PTE entry with set
appended to its flag bitfield.
pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear)
pmd_clear_flags() returns a new pmd_t which is
identical to the specified PMD entry except for the specified clear
field
whose bitfield is cleared in the returned PMD entry's flag bitfield.
No checks are performed to ensure clear
is valid and limited only to available
flag bits, so incorrect use of this function could result in an invalid return
value.
-
pmd
- The PMD entry which we want to copy/update. -
clear
- The flag bitfield we want to clear from the newly created PMD entry.
A copy of the input PMD entry with clear
flags cleared in its flag bitfield.
pte_t pte_clear_flags(pte_t pte, pteval_t clear)
pte_clear_flags() returns a new pte_t which is
identical to the specified PTE entry except for the specified clear
field
whose bitfield is cleared in the returned PTE entry's flag bitfield.
No checks are performed to ensure clear
is valid and limited only to available
flag bits, so incorrect use of this function could result in an invalid return
value.
-
pte
- The PTE entry which we want to copy/update. -
clear
- The flag bitfield we want to clear from the newly created PTE entry.
A copy of the input PTE entry with clear
flags cleared in its flag bitfield.
int pgd_present(pgd_t pgd)
pgd_present() determines whether the PUD page that the specified PGD entry points at is 'present' - i.e. whether it is currently resident in memory and not swapped out or otherwise unavailable.
The function uses pgd_flags() to retrieve the PGD entry's flags
then tests whether _PAGE_PRESENT
is set.
pgd
- PGD entry pointing at the PUD page which we want to determine is present or not.
Truthy (non-zero) if the PUD page is present, 0 if not.
int pud_present(pud_t pud)
pud_present() determines whether the PMD page that the specified PUD entry points at is 'present' - i.e. whether it is currently resident in memory and not swapped out or otherwise unavailable.
The function uses pud_flags() to retrieve the PUD entry's flags
then tests whether _PAGE_PRESENT
is set.
pud
- PUD entry pointing at the PMD page which we want to determine is present or not.
Truthy (non-zero) if the PMD page is present, 0 if not.
int pmd_present(pmd_t pmd)
pmd_present() determines whether the PTE page that the specified PMD entry points at is 'present' - i.e. whether it is currently resident in memory and not swapped out or otherwise unavailable.
The function uses pmd_flags() to retrieve the PMD entry's flags
then tests whether _PAGE_PRESENT
, _PAGE_PROTNONE
or _PAGE_PSE
are set.
Looking at each flag:
-
_PAGE_PRESENT
indicates whether the pointed at PTE page is actually resident or not. -
_PAGE_PROTNONE
indicates that the PTE page is resident, but not accessible. This is used by NUMA balancing (irrelevant for our assumed architecture, UMA x86-64) or the mprotectPROT_NONE
flag having been set by the user. -
_PAGE_PSE
indicates that huge pages are in use, and needs to be checked here because (according to the comment for the pmd_present() function) the split_huge_page() function will temporarily clear the present bit, so we need a means of determining whether the page is still actually present when this happens.
The _PAGE_PROTNONE
and _PAGE_PSE
flags seem only to be meaningful at the PMD
level when the PTE is a huge page (i.e. 2MiB in x86-64), which seems only to be
the case when either transparent huge pages or the
device mapper are in use.
pmd
- PMD entry pointing at the PTE page which we want to determine is present or not.
Truthy (non-zero) if the PTE page is present, 0 if not.
int pte_present(pte_t pte)
pte_present() determines whether the physical page that the specified PTE entry points at is 'present' - i.e. whether it is currently resident in memory and not swapped out or otherwise unavailable.
The function uses pte_flags() to retrieve PTE flags then tests
whether _PAGE_PRESENT
or _PAGE_PROTNONE
are set.
Looking at each flag:
-
_PAGE_PRESENT
is the flag that indicates whether the physical page is actually resident or not. -
_PAGE_PROTNONE
indicates that the page is resident, but not accessible. This is used by NUMA balancing (irrelevant for our assumed architecture, UMA x86-64) or the mprotectPROT_NONE
flag having been set by the user.
pte
- PTE entry pointing at the physical page which we want to determine is present or not.
Truthy (non-zero) if the physical page is present, 0 if not.
int pmd_young(pmd_t pmd)
pmd_young() determines whether the specified PMD entry has the
_PAGE_ACCESSED
flag set, i.e. whether the PTE page it refers to has been
accessed since the flag was last cleared.
pmd
- The PMD entry whose accessed flag state we want to determine.
Truthy (non-zero) if the PMD entry is marked accessed.
int pte_young(pte_t pte)
pte_young() determines whether the specified PTE entry has the
_PAGE_ACCESSED
flag set, i.e. whether the physical page it refers to has been
accessed since the flag was last cleared.
pte
- The PTE entry whose accessed flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked accessed.
int pmd_dirty(pmd_t pmd)
pmd_dirty() determines whether the specified PMD entry has the
_PAGE_DIRTY
flag set, i.e. whether the PTE page it refers to has been modified
since the flag was last cleared.
This function can only be meaningfully used if pmd_present()
returns true.
pmd
- The PMD entry whose dirty flag state we want to determine.
Truthy (non-zero) if the PMD entry is marked dirty.
int pte_dirty(pte_t pte)
pte_dirty() determines whether the specified PTE entry has the
_PAGE_DIRTY
flag set, i.e. whether the physical page it refers to has been
modified since the flag was last cleared.
This function can only be meaningfully used if pte_present()
returns true.
pte
- The PTE entry whose dirty flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked dirty.
int pmd_write(pmd_t pmd)
pmd_write() determines whether the specified PMD entry has the
_PAGE_RW
flag set, i.e. whether the PTE page it refers to is not read-only.
pmd
- The PMD entry whose read/write flag state we want to determine.
Truthy (non-zero) if the PMD entry is marked read/write.
int pte_write(pte_t pte)
pte_write() determines whether the specified PTE entry has the
_PAGE_RW
flag set, i.e. whether the physical page it refers to is not
read-only.
pte
- The PTE entry whose read/write flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked read/write.
int pte_exec(pte_t pte)
pte_exec() determines whether the specified PTE entry has the
_PAGE_NX
flag set, i.e. whether the physical page it refers to contains bytes
that can be executed.
This uses the NX bit feature of x86-64 which determines whether bytes in a specific page are permitted to be executed or not.
pte
- The PTE entry whose executable flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked executable.
int pte_global(pte_t pte)
pte_global() determines whether the specified PTE entry has the
_PAGE_GLOBAL
flag set, i.e. whether the TLB cache entry mapping the
PTE's corresponding virtual address to the physical page it points at ought to
not to be cleared when the TLB is flushed, either manually or by a context
switch.
This flag is useful for pages which are shared across all processes and are regularly accessed.
Once set, TLB flushes caused by a task switch (i.e. assigning a new PGD to the
cr3
register) or a manual TLB flush other than
flush_tlb_all() will not invalidate the global entry.
If you want to finally invalidate such an entry, a call to __flush_tlb_global() and subsequently invpcid_flush_all() is required (this will most likely be via flush_tlb_all().)
pte
- The PTE entry whose global flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked global.
int pte_special(pte_t pte)
pte_special() determines whether the specified PTE entry has the
_PAGE_SPECIAL
flag set, i.e. whether the 'user-defined' special flag is set.
I put 'user-defined' in quotes to avoid confusion between user and kernel - here
user is in the sense of the software rather than the CPU. The
_PAGE_BIT_SPECIAL
constant (_PAGE_SPECIAL = 1UL << _PAGE_BIT_SPECIAL
) is an
alias for _PAGE_BIT_SOFTW1
- bit 9 (base-0), first of the 3 bits between 9 and
11 which the CPU simply ignores.
pte
- The PTE entry whose special flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked special.
int pmd_soft_dirty(pmd_t pmd)
pmd_soft_dirty() determines whether the specified PMD entry
has the _PAGE_SOFT_DIRTY
flag set, i.e. whether the 'user-defined' soft-dirty
flag is set.
I put 'user-defined' in quotes to avoid confusion between user and kernel - here
user is in the sense of the software rather than the CPU. The
_PAGE_BIT_SOFT_DIRTY
constant (_PAGE_SOFT_DIRTY = 1UL << _PAGE_BIT_SOFT_DIRTY
) is an alias for _PAGE_BIT_SOFTW3
- bit 11 (base-0),
third of the 3 bits between 9 and 11 which the CPU simply ignores.
The soft-dirty mechanism is a means by which userland processes
can determine which pages have been modified since these bits were last cleared
for a specified task via the /proc/<pid>/clear_refs
and /proc/<pid>/pagemap
files.
It differs from the actual dirty flag as that is used by the kernel for its own modified state tracking, rendering it unsuitable for use by userland.
Since the flags field describes the underlying PTE page, this function determines whether the PTE page has been modified since last use, despite the 'PMD' in its name.
pmd
- The PMD entry whose soft-dirty flag state we want to determine.
Truthy (non-zero) if the PMD entry is marked soft-dirty.
int pte_soft_dirty(pte_t pte)
pte_soft_dirty() determines whether the specified PTE entry
has the _PAGE_SOFT_DIRTY
flag set, i.e. whether the 'user-defined' soft-dirty
flag is set.
I put 'user-defined' in quotes to avoid confusion between user and kernel - here
user is in the sense of the software rather than the CPU. The
_PAGE_BIT_SOFT_DIRTY
constant (_PAGE_SOFT_DIRTY = 1UL << _PAGE_BIT_SOFT_DIRTY
) is an alias for _PAGE_BIT_SOFTW3
- bit 11 (base-0),
third of the 3 bits between 9 and 11 which the CPU simply ignores.
The soft-dirty mechanism is a means by which userland processes
can determine which pages have been modified since these bits were last cleared
for a specified task via the /proc/<pid>/clear_refs
and /proc/<pid>/pagemap
files.
It differs from the actual dirty flag as that is used by the kernel for its own modified state tracking, rendering it unsuitable for use by userland.
Since the flags field describes the underlying physical page page, this function determines whether the referred to physical page has been modified since last use, despite the 'PTE' in its name.
pte
- The PTE entry whose soft-dirty flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked soft-dirty.
int pmd_devmap(pmd_t pmd)
pmd_devmap() determines whether the specified PMD entry has the
_PAGE_DEVMAP
flag set, i.e. whether the 'user-defined' devmap flag is set.
I put 'user-defined' in quotes to avoid confusion between user and kernel - here
user is in the sense of the software rather than the CPU. The _PAGE_BIT_DEVMAP
constant (_PAGE_DEVMAP = 1UL << _PAGE_BIT_DEVMAP
) is an alias for
_PAGE_BIT_SOFTW4
- bit 58 (base-0), which the CPU simply ignores.
It seems like this flag forms part of the device mapper functionality but I haven't yet looked into this deeply.
pmd
- The PMD entry whose devmap flag state we want to determine.
Truthy (non-zero) if the PMD entry is marked as a devmap entry.
int pte_devmap(pte_t pte)
pte_devmap() determines whether the specified PTE entry has the
_PAGE_DEVMAP
flag set, i.e. whether the 'user-defined' devmap flag is set.
I put 'user-defined' in quotes to avoid confusion between user and kernel - here
user is in the sense of the software rather than the CPU. The _PAGE_BIT_DEVMAP
constant (_PAGE_DEVMAP = 1UL << _PAGE_BIT_DEVMAP
) is an alias for
_PAGE_BIT_SOFTW4
- bit 58 (base-0), which the CPU simply ignores.
It seems like this flag forms part of the device mapper functionality but I haven't yet looked into this deeply.
pte
- The PTE entry whose devmap flag state we want to determine.
Truthy (non-zero) if the PTE entry is marked as a devmap entry.
int pud_huge(pud_t pud)
pud_huge() determines whether the specified PUD entry is marked huge
in the context of hugetlb, i.e. whether the PMD page it refers to is
huge under the hugetlb
scheme.
This simply checks the _PAGE_PSE
(i.e. huge page) flag.
pud
- The PUD entry whose huge flag state we want to determine.
Truthy (non-zero) if the PUD entry is marked huge.
int pmd_huge(pmd_t pmd)
pmd_huge() determines whether the specified PMD entry is marked huge
in the context of hugetlb, i.e. whether the PTE page it refers to is
huge under the hugetlb
scheme.
This function determines whether the specified PMD entry is non-empty and either
not marked present or marked present and has the _PAGE_PSE
(i.e. huge page)
flag set.
pmd
- The PMD entry we want to determine is marked huge under thehugetlb
scheme.
Truthy (non-zero) if the PMD entry is marked huge under the hugetlb
scheme.
int pte_huge(pte_t pte)
pte_huge() determines whether the specified PTE entry is marked huge, i.e. whether the physical page it refers to is huge.
This simply checks the _PAGE_PSE
(i.e. huge page) flag.
pte
- The PTE entry we want to determine is marked huge or not.
Truthy (non-zero) if the PTE entry is marked huge.
int pmd_trans_huge(pmd_t pmd)
pmd_trans_huge() determines whether the specified PMD entry is marked huge in the context of transparent huge pages.
This checks that the _PAGE_PSE
flag is set and the _PAGE_DEVMAP
flag is
not set.
pmd
- The PMD entry we want to determine is marked huge or not under the Transparent Huge Pages scheme.
Truthy (non-zero) if the PMD entry is marked huge under the Transparent Huge Pages scheme.
int pgd_large(pgd_t pgd)
pgd_large() determines whether the specified PGD entry is marked huge, indicating the PUD page it points at is huge.
This function is defined as returning 0 on x86-64 - PUD pages are never huge.
pgd
- The PGD entry we want to determine is marked huge or not.
Truthy (non-zero) if the PGD entry is marked huge.
int pud_large(pud_t pud)
pud_large() determines whether the specified PUD entry is marked huge, indicating the PMD page it points at is huge.
The function tests the _PAGE_PSE
and _PAGE_PRESENT
flags to determine
whether the page is marked huge and not swapped out/otherwise unavailable,
respectively.
pud
- The PUD entry we want to determine is marked huge or not.
Truthy (non-zero) if the PUD entry is marked huge.
int pmd_large(pmd_t pmd)
pmd_large() determines whether the specified PMD entry is marked huge, indicating the PTE page it points at is huge.
The function simply tests the _PAGE_PSE
flag to determine whether the page is
marked huge. It differs from pud_large() in that it doesn't also
check for the present flag, an odd inconsistency.
pmd
- The PMD entry we want to determine is marked huge or not.
Truthy (non-zero) if the PMD entry is marked huge.
pmd_t pmd_mkyoung(pmd_t pmd)
pmd_mkyoung() returns a new pmd_t which is identical to
the specified PMD entry except that the _PAGE_ACCESSED
flag is set, indicating
that the underlying PTE page has been accessed.
pmd
- The PMD entry which we want a copy of with the accessed flag set.
A copy of the input PMD entry with the accessed flag set.
pmd_t pmd_mkold(pmd_t pmd)
pmd_mkold() returns a new pmd_t which is identical to the
specified PMD entry except that the _PAGE_ACCESSED
flag is cleared, indicating
that the underlying PTE page has not been accessed yet.
pmd
- The PMD entry which we want a copy of with the accessed flag cleared.
A copy of the input PMD entry with the accessed flag cleared.
pte_t pte_mkyoung(pte_t pte)
pte_mkyoung() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_ACCESSED
flag is set, indicating
that the underlying physical page has been accessed.
pte
- The PTE entry which we want a copy of with the accessed flag set.
A copy of the input PTE entry with the accessed flag set.
pte_t pte_mkold(pte_t pte)
pte_mkold() returns a new pte_t which is identical to the
specified PTE entry except that the _PAGE_ACCESSED
flag is cleared, indicating
that the underlying physical page has not been accessed yet.
pte
- The PTE entry which we want a copy of with the accessed flag cleared.
A copy of the input PTE entry with the accessed flag cleared.
pmd_t pmd_mkdirty(pmd_t pmd)
pmd_mkdirty() returns a new pmd_t which is identical to
the specified PMD entry except that the _PAGE_DIRTY
and _PAGE_SOFT_DIRTY
flags are set, indicating that the underlying PTE page has been modified.
The _PAGE_SOFT_DIRTY
flag being set synchronises the soft-dirty
state with the kernel page ageing logic.
pmd
- The PMD entry which we want a copy of with the dirty flags set.
A copy of the input PMD entry with the dirty flags set.
pmd_t pmd_mkclean(pmd_t pmd)
pmd_mkclean() returns a new pmd_t which is identical to
the specified PMD entry except that the _PAGE_DIRTY
flag is cleared,
indicating that the underlying PTE page has not been modified yet.
Curiously, the _PAGE_SOFT_DIRTY
flag is not cleared (it's curious because this
flag is set in pmd_mkdirty().)
pmd
- The PMD entry which we want a copy of with the dirty flag cleared.
A copy of the input PMD entry with the dirty flag cleared.
pte_t pte_mkdirty(pte_t pte)
pte_mkdirty() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_DIRTY
and _PAGE_SOFT_DIRTY
flags are set, indicating that the underlying physical page has been modified.
The _PAGE_SOFT_DIRTY
flag being set synchronises the soft-dirty
state with the kernel page ageing logic.
pte
- The PTE entry which we want a copy of with the dirty flags set.
A copy of the input PTE entry with the dirty flags set.
pte_t pte_mkclean(pte_t pte)
pte_mkclean() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_DIRTY
flag is cleared,
indicating that the underlying physical page has not been dirty yet.
Curiously, the _PAGE_SOFT_DIRTY
flag is not cleared (it's curious because this
flag is set in pte_mkdirty().)
pte
- The PTE entry which we want a copy of with the dirty flag cleared.
A copy of the input PTE entry with the dirty flag cleared.
pmd_t pmd_mkwrite(pmd_t pmd)
pmd_mkwrite() returns a new pmd_t which is identical to
the specified PMD entry except that the _PAGE_RW
flag is set, indicating that
the underlying PTE page can be read from and written to.
pmd
- The PMD entry which we want a copy of with the R/W flag set.
A copy of the input PMD entry with the R/W flag set.
pmd_t pmd_wrprotect(pmd_t pmd)
pmd_wrprotect() returns a new pmd_t which is identical
to the specified PMD entry except that the _PAGE_RW
flag is cleared,
indicating that the underlying PTE page is read-only.
pmd
- The PMD entry which we want a copy of with the R/W flag cleared.
A copy of the input PMD entry with the R/W flag cleared.
pte_t pte_mkwrite(pte_t pte)
pte_mkwrite() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_RW
flag is set, indicating that
the underlying physical page can be read from and written to.
pte
- The PTE entry which we want a copy of with the R/W flag set.
A copy of the input PTE entry with the R/W flag set.
pte_t pte_wrprotect(pte_t pte)
pte_wrprotect() returns a new pte_t which is identical to the
specified PTE entry except that the _PAGE_RW
flag is cleared, indicating that
the underlying physical page is read-only.
pte
- The PTE entry which we want a copy of with the R/W flag cleared.
A copy of the input PTE entry with the R/W flag cleared.
pmd_t pmd_mksoft_dirty(pmd_t pmd)
pmd_mksoft_dirty() returns a new pmd_t which is
identical to the specified PMD entry except that the _PAGE_SOFT_DIRTY
flag is
set, indicating that the underlying PTE page has been modified since the
soft-dirty flag was last set.
The soft-dirty mechanism is a means by which userland processes
can determine which pages have been modified since these bits were last cleared
for a specified task via the /proc/<pid>/clear_refs
and /proc/<pid>/pagemap
files.
It differs from the actual dirty flag as that is used by the kernel for its own modified state tracking, rendering it unsuitable for use by userland.
pmd
- The PMD entry which we want a copy of with the soft-dirty flag set.
A copy of the input PMD entry with the soft-dirty flag set.
pmd_t pmd_clear_soft_dirty(pmd_t pmd)
pmd_clear_soft_dirty() returns a new pmd_t
which is identical to the specified PMD entry except that the _PAGE_SOFT_DIRTY
flag is cleared, indicating that the underlying PTE page has not been modified
since the soft-dirty flag was last set.
The soft-dirty mechanism is a means by which userland processes
can determine which pages have been modified since these bits were last cleared
for a specified task via the /proc/<pid>/clear_refs
and /proc/<pid>/pagemap
files.
It differs from the actual dirty flag as that is used by the kernel for its own modified state tracking, rendering it unsuitable for use by userland.
pmd
- The PMD entry which we want a copy of with the soft-dirty flag cleared.
A copy of the input PMD entry with the soft-dirty flag cleared.
pte_t pte_mksoft_dirty(pte_t pte)
pte_mksoft_dirty() returns a new pte_t which is
identical to the specified PTE entry except that the _PAGE_SOFT_DIRTY
flag is
set, indicating that the underlying physical page has been modified since the
soft-dirty flag was last set.
The soft-dirty mechanism is a means by which userland processes
can determine which pages have been modified since these bits were last cleared
for a specified task via the /proc/<pid>/clear_refs
and /proc/<pid>/pagemap
files.
It differs from the actual dirty flag as that is used by the kernel for its own modified state tracking, rendering it unsuitable for use by userland.
pte
- The PTE entry which we want a copy of with the soft-dirty flag set.
A copy of the input PTE entry with the soft-dirty flag set.
pte_t pte_clear_soft_dirty(pte_t pte)
pte_clear_soft_dirty() returns a new pte_t
which is identical to the specified PTE entry except that the _PAGE_SOFT_DIRTY
flag is cleared, indicating that the underlying physical page has not been
modified since the soft-dirty flag was last set.
The soft-dirty mechanism is a means by which userland processes
can determine which pages have been modified since these bits were last cleared
for a specified task via the /proc/<pid>/clear_refs
and /proc/<pid>/pagemap
files.
It differs from the actual dirty flag as that is used by the kernel for its own modified state tracking, rendering it unsuitable for use by userland.
pte
- The PTE entry which we want a copy of with the soft-dirty flag cleared.
A copy of the input PTE entry with the soft-dirty flag cleared.
pmd_t pmd_mkdevmap(pmd_t pmd)
pmd_mkdevmap() returns a new pmd_t which is identical
to the specified PMD entry except that the _PAGE_DEVMAP
flag is set,
indicating that the underlying PTE page is used by the
device mapping functionality.
pmd
- The PMD entry which we want a copy of with the dev-map flag set.
A copy of the input PMD entry with the dev-map flag set.
pte_t pte_mkdevmap(pte_t pte)
pte_mkdevmap() returns a new pte_t which is identical
to the specified PTE entry except that the _PAGE_DEVMAP
flag is set,
indicating that the underlying physical page is used by the
device mapping functionality.
pte
- The PTE entry which we want a copy of with the dev-map flag set.
A copy of the input PTE entry with the dev-map flag set.
pmd_t pmd_mknotpresent(pmd_t pmd)
pmd_mknotpresent() returns a new pmd_t which is
identical to the specified PMD entry except that the _PAGE_PRESENT
and
_PAGE_PROTNONE
flags are cleared, indicating that the underlying PTE page is
not resident, not even as a non-readable page.
pmd
- The PMD entry which we want a copy of with the present flags cleared.
A copy of the input PMD entry with the present flags cleared.
pte_t pte_mkglobal(pte_t pte)
pte_mkglobal() returns a new pte_t which is identical
to the specified PTE entry except that the _PAGE_GLOBAL
flag is set,
indicating that the TLB cache entry mapping the PTE's corresponding
virtual address to the physical page it points at won't be cleared when the
TLB is flushed, either manually or by a context switch.
This flag is useful for pages which are shared across all processes and are regularly accessed.
Once set, TLB flushes caused by a task switch (i.e. assigning a new PGD to the
cr3
register) or a manual TLB flush other than
flush_tlb_all() will not invalidate the global entry.
pte
- The PTE entry which we want a copy of with the global flag set.
A copy of the input PTE entry with the global flag set.
pte_t pte_clrglobal(pte_t pte)
pte_clrglobal() returns a new pte_t which is identical
to the specified PTE entry except that the _PAGE_GLOBAL
flag is cleared,
indicating that the TLB cache entry mapping the PTE's corresponding
virtual address to the physical page it points at ought to be cleared when the
TLB is flushed, either manually or by a context switch (when the flag is set,
this does not happen.)
pte
- The PTE entry which we want a copy of with the global flag cleared.
A copy of the input PTE entry with the global flag cleared.
pte_t pte_mkexec(pte_t pte)
pte_mkexec() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_NX
flag is cleared, indicating
that the underlying physical page contains executable code.
pte
- The PTE entry which we want a copy of with the no-execute flag cleared.
A copy of the input PTE entry with the no-execute flag cleared.
pte_t pte_mkspecial(pte_t pte)
pte_mkspecial() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_SPECIAL
flag is set, indicating
that the underlying physical page is special.
pte
- The PTE entry which we want a copy of with the special flag set.
A copy of the input PTE entry with the special flag set.
pmd_t pmd_mkhuge(pmd_t pmd)
pmd_mkhuge() returns a new pmd_t which is identical to
the specified PMD entry except that the _PAGE_PSE
flag is set, indicating that
the underlying PTE page is huge.
pmd
- The PMD entry which we want a copy of with the huge flag set.
A copy of the input PMD entry with the huge flag set.
pte_t pte_mkhuge(pte_t pte)
pte_mkhuge() returns a new pte_t which is identical to
the specified PTE entry except that the _PAGE_PSE
flag is set, indicating that
the underlying physical page is huge (i.e. 2MiB in x86-64.)
pte
- The PTE entry which we want a copy of with the huge flag set.
A copy of the input PTE entry with the huge flag set.
pte_t pte_clrhuge(pte_t pte)
pte_clrhuge() returns a new pte_t which is identical to the
specified PTE entry except that the _PAGE_PSE
flag is cleared, indicating
that the underlying physical page is not huge.
pte
- The PTE entry which we want a copy of with the huge flag cleared.
A copy of the input PTE entry with the huge flag cleared.