net: Add network_offset to blocks
[akaros.git] / kern / arch / x86 / pmap_ops.h
1 /* Copyright (c) 2015 Google Inc.
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Arch-specific operations for page tables and PTEs.
6  *
7  * Unfortunately, many of these ops are called from within a memwalk callback,
8  * which expects a full pte.  But doing walks for a KPT and an EPT at the same
9  * time is a pain, and for now we'll do the walks serially.  Because of that, a
10  * given pte_t may have a KPTE and/or an EPTE.  Ideally, it'd be *and*. */
11
12 #pragma once
13
14 #include <arch/vmm/ept.h>
15 #include <arch/kpt.h>
16
17 /* TODO: (EPT)  build a CONFIG mode where we assert the EPT agrees with the KPT
18  * for all of the read ops */
19
20 static inline bool pte_walk_okay(pte_t pte)
21 {
22         return pte ? TRUE : FALSE;
23 }
24
25 /* PTE states:
26  *  - present: the PTE is involved in a valid page table walk, can be used
27  *  for some form of hardware access (read, write, user, etc), and with the
28  *  physaddr part pointing to a physical page.
29  *
30  *      - mapped: the PTE is involved in some sort of mapping, e.g. a VMR.  We're
31  *      storing something in the PTE, but it is isn't necessarily present.
32  *      Currently, all mapped pages should point to an actual physical page.
33  *      All present are mapped, but not vice versa.  Mapped pages can point to a
34  *      real page, but with no access permissions, which is the main distinction
35  *      between present and mapped.
36  *
37  *      - paged_out: we don't actually use this yet.  Since mapped vs present is
38  *      based on the PTE present bits, we'd need to use reserved bits in the PTE to
39  *      differentiate between other states.  Right now, paged_out == mapped, as far
40  *      as the code is concerned.
41  *
42  *      - unmapped: completely unused. (0 value) */
43 static inline bool pte_is_present(pte_t pte)
44 {
45         return kpte_is_present(pte);
46 }
47
48 static inline bool pte_is_unmapped(pte_t pte)
49 {
50         return kpte_is_unmapped(pte);
51 }
52
53 static inline bool pte_is_mapped(pte_t pte)
54 {
55         return kpte_is_mapped(pte);
56 }
57
58 static inline bool pte_is_paged_out(pte_t pte)
59 {
60         return kpte_is_paged_out(pte);
61 }
62
63 static inline bool pte_is_dirty(pte_t pte)
64 {
65         return kpte_is_dirty(pte) ||
66                epte_is_dirty(kpte_to_epte(pte));
67 }
68
69 static inline bool pte_is_accessed(pte_t pte)
70 {
71         return kpte_is_accessed(pte) ||
72                epte_is_accessed(kpte_to_epte(pte));
73 }
74
75 /* Used in debugging code - want something better involving the walk */
76 static inline bool pte_is_jumbo(pte_t pte)
77 {
78         return kpte_is_jumbo(pte);
79 }
80
81 static inline physaddr_t pte_get_paddr(pte_t pte)
82 {
83         return kpte_get_paddr(pte);
84 }
85
86 /* Returns the PTE in an unsigned long, for debugging mostly. */
87 static inline unsigned long pte_print(pte_t pte)
88 {
89         return kpte_print(pte);
90 }
91
92 static inline void pte_write(pte_t pte, physaddr_t pa, int settings)
93 {
94         kpte_write(pte, pa, settings);
95         epte_write(kpte_to_epte(pte), pa, settings);
96 }
97
98 static inline void pte_clear_present(pte_t pte)
99 {
100         kpte_clear_present(pte);
101         epte_clear_present(kpte_to_epte(pte));
102 }
103
104 static inline void pte_clear(pte_t pte)
105 {
106         kpte_clear(pte);
107         epte_clear(kpte_to_epte(pte));
108 }
109
110 /* These are used by memcpy_*_user, but are very dangerous (and possibly used
111  * incorrectly there).  These aren't the overall perms for a VA.  For U and W,
112  * we need the intersection of the PTEs along the walk and not just the last
113  * one.  It just so happens that the W is only cleared on the last PTE, so the
114  * check works for that.  But if there was a page under ULIM that wasn't U due
115  * to an intermediate PTE, we'd miss that. */
116 static inline bool pte_has_perm_ur(pte_t pte)
117 {
118         return kpte_has_perm_ur(pte);
119 }
120
121 static inline bool pte_has_perm_urw(pte_t pte)
122 {
123         return kpte_has_perm_urw(pte);
124 }
125
126 /* Settings includes protection (maskable via PTE_PROT) and other bits, such as
127  * jumbo, dirty, accessed, etc.  Whatever this returns can get fed back to
128  * pte_write.
129  *
130  * Arch-indep settings include: PTE_PERM (U, W, P, etc), PTE_D, PTE_A, PTE_PS.
131  * Other OSs (x86) may include others. */
132 static inline int pte_get_settings(pte_t pte)
133 {
134         return kpte_get_settings(pte);
135 }
136
137 static inline void pte_replace_perm(pte_t pte, int perm)
138 {
139         kpte_replace_perm(pte, perm);
140         epte_replace_perm(kpte_to_epte(pte), perm);
141 }