Skip to content

Page Table

include/mem/page_table.h View source View on GitHub
struct pte_tagged (2 fields) source

This is a bit like a tagged pointer, just that the payload moseys around LOCK_BIT and AVAIL2, and the type sits right above PRESENT

The layout is effectively

[ payload higher ] [ LOCK + AVAIL2 ] [ payload lower ] [ type ] [ P = 0 ]

§ enum pte_tag_type type
§ uint64_t payload
NOTE

higher 5 bits MUST be zero

enum pte_tag_type : uint8_t (2 variants) source

Packed into the low X bits

§ PTE_TAG_TYPE_NONE = 0
§ PTE_TAG_TYPE_DEMAND_PAGED = 1
typedef atomic_uint64_t pte_atomic_t
source
bool pte_is_shared(uint64_t pte)
source
void pte_tagged_check(struct pte_tagged *pt)
source
uint64_t pte_tagged_pack(struct pte_tagged *pt)
source
struct pte_tagged pte_tagged_unpack(pte_t pte)
source
bool pte_locked(pte_atomic_t *pte)
source
uint64_t pte_read(pte_atomic_t *pte)
source
uint64_t pte_or(pte_atomic_t *pte, uint64_t val)
source
void pte_unlock_internal(pte_atomic_t *pte)
source
void pte_lock_internal(pte_atomic_t *pte)
source
TODO

use bit_spinlock.h

enum irql pte_lock_irql(pte_atomic_t *pte)
source
void pte_unlock_irql(pte_atomic_t *pte, enum irql old_irql)
source
bool pte_has_tag(pte_atomic_t *pte)
source
uint64_t pte_tag_pte(pte_atomic_t *pte, struct pte_tagged *ptag)
source
struct pte_tagged pte_read_tag(pte_atomic_t *pte)
source
bool pte_in_use(pte_atomic_t *pte)
source
#define PT_LEVELS 4
source
#define PT_SHIFT_L1 12
source
#define PT_SHIFT_L2 21
source
#define PT_SHIFT_L3 30
source
#define PT_SHIFT_L4 39
source
#define PT_STRIDE 9
source
#define PTE_LOCK_SHIFT 9
source
#define PTE_AVAIL2_SHIFT 10
source
#define PTE_LOCK_BIT BIT(PTE_LOCK_SHIFT)
source
#define PTE_AVAIL2_BIT BIT(PTE_AVAIL2_SHIFT)
source
#define PTE_SHARED_SHIFT 11
source

Mark an entry whose child table is shared with other entries, this is what we use in aliasing. The subtree should never be freed through this entry, since every other entry pointing at it would see the change too. This should only ever be set on present entries

#define PTE_SHARED_BIT BIT(PTE_SHARED_SHIFT)
source
#define PTE_TAGGED_TYPE_SHIFT (PAGE_PRESENT_SHIFT + 1)
source

Packed layout:

bit 0 P = 0
bits 1-2 type
bits 3-8 payload low (6 bits)
bit 9 LOCK (not payload)
bit 10 AVAIL2 (not payload)
bits 11-63 payload high (53 bits)

Do note that SHARED is not accounted for here, because that bit is only ever set on PRESENT entries

#define PTE_TAGGED_TYPE_MASK 0x3ULL
source
#define PTE_TAGGED_PAYLOAD_LOW_BITS 6
source
#define PTE_TAGGED_PAYLOAD_LOW_SHIFT 3
source

packed position of the low chunk

#define PTE_TAGGED_PAYLOAD_HIGH_SHIFT
source
Expansion
#define PTE_TAGGED_PAYLOAD_HIGH_SHIFT \
    11 /* packed position of the high chunk \
        */
#define PTE_TAGGED_PAYLOAD_LOW_MASK (BIT(PTE_TAGGED_PAYLOAD_LOW_BITS) - 1)
source
#define PTE_TAGGED_PAYLOAD_BITS
source
#define PTE_TAGGED_GET_TYPE(pte)
source
Expansion
#define PTE_TAGGED_GET_TYPE(pte) \
    (((pte) >> PTE_TAGGED_TYPE_SHIFT) & PTE_TAGGED_TYPE_MASK)
#define PTE_TAGGED_SET_TYPE(type)
source
Expansion
#define PTE_TAGGED_SET_TYPE(type) ((uint64_t) (type) << PTE_TAGGED_TYPE_SHIFT)