/root/src/xen/xen/arch/x86/pv/mm.h
Line | Count | Source (jump to first uncovered line) |
1 | | #ifndef __PV_MM_H__ |
2 | | #define __PV_MM_H__ |
3 | | |
4 | | l1_pgentry_t *map_guest_l1e(unsigned long linear, mfn_t *gl1mfn); |
5 | | |
6 | | int new_guest_cr3(mfn_t mfn); |
7 | | |
8 | | /* Read a PV guest's l1e that maps this linear address. */ |
9 | | static inline l1_pgentry_t guest_get_eff_l1e(unsigned long linear) |
10 | 0 | { |
11 | 0 | l1_pgentry_t l1e; |
12 | 0 |
|
13 | 0 | ASSERT(!paging_mode_translate(current->domain)); |
14 | 0 | ASSERT(!paging_mode_external(current->domain)); |
15 | 0 |
|
16 | 0 | if ( unlikely(!__addr_ok(linear)) || |
17 | 0 | __copy_from_user(&l1e, |
18 | 0 | &__linear_l1_table[l1_linear_offset(linear)], |
19 | 0 | sizeof(l1_pgentry_t)) ) |
20 | 0 | l1e = l1e_empty(); |
21 | 0 |
|
22 | 0 | return l1e; |
23 | 0 | } Unexecuted instantiation: ro-page-fault.c:guest_get_eff_l1e Unexecuted instantiation: grant_table.c:guest_get_eff_l1e Unexecuted instantiation: emul-priv-op.c:guest_get_eff_l1e Unexecuted instantiation: mm.c:guest_get_eff_l1e |
24 | | |
25 | | /* |
26 | | * PTE updates can be done with ordinary writes except: |
27 | | * 1. Debug builds get extra checking by using CMPXCHG[8B]. |
28 | | */ |
29 | | #ifndef NDEBUG |
30 | | #define PTE_UPDATE_WITH_CMPXCHG |
31 | | #else |
32 | | #undef PTE_UPDATE_WITH_CMPXCHG |
33 | | #endif |
34 | | |
35 | | /* |
36 | | * How to write an entry to the guest pagetables. |
37 | | * Returns false for failure (pointer not valid), true for success. |
38 | | */ |
39 | | static inline bool update_intpte(intpte_t *p, intpte_t old, intpte_t new, |
40 | | unsigned long mfn, struct vcpu *v, |
41 | | bool preserve_ad) |
42 | 0 | { |
43 | 0 | bool rv = true; |
44 | 0 |
|
45 | 0 | #ifndef PTE_UPDATE_WITH_CMPXCHG |
46 | | if ( !preserve_ad ) |
47 | | { |
48 | | rv = paging_write_guest_entry(v, p, new, _mfn(mfn)); |
49 | | } |
50 | | else |
51 | | #endif |
52 | 0 | { |
53 | 0 | intpte_t t = old; |
54 | 0 |
|
55 | 0 | for ( ; ; ) |
56 | 0 | { |
57 | 0 | intpte_t _new = new; |
58 | 0 |
|
59 | 0 | if ( preserve_ad ) |
60 | 0 | _new |= old & (_PAGE_ACCESSED | _PAGE_DIRTY); |
61 | 0 |
|
62 | 0 | rv = paging_cmpxchg_guest_entry(v, p, &t, _new, _mfn(mfn)); |
63 | 0 | if ( unlikely(rv == 0) ) |
64 | 0 | { |
65 | 0 | gdprintk(XENLOG_WARNING, |
66 | 0 | "Failed to update %" PRIpte " -> %" PRIpte |
67 | 0 | ": saw %" PRIpte "\n", old, _new, t); |
68 | 0 | break; |
69 | 0 | } |
70 | 0 |
|
71 | 0 | if ( t == old ) |
72 | 0 | break; |
73 | 0 |
|
74 | 0 | /* Allowed to change in Accessed/Dirty flags only. */ |
75 | 0 | BUG_ON((t ^ old) & ~(intpte_t)(_PAGE_ACCESSED|_PAGE_DIRTY)); |
76 | 0 |
|
77 | 0 | old = t; |
78 | 0 | } |
79 | 0 | } |
80 | 0 | return rv; |
81 | 0 | } Unexecuted instantiation: mm.c:update_intpte Unexecuted instantiation: grant_table.c:update_intpte Unexecuted instantiation: ro-page-fault.c:update_intpte Unexecuted instantiation: emul-priv-op.c:update_intpte |
82 | | |
83 | | /* |
84 | | * Macro that wraps the appropriate type-changes around update_intpte(). |
85 | | * Arguments are: type, ptr, old, new, mfn, vcpu |
86 | | */ |
87 | | #define UPDATE_ENTRY(_t,_p,_o,_n,_m,_v,_ad) \ |
88 | 0 | update_intpte(&_t ## e_get_intpte(*(_p)), \ |
89 | 0 | _t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \ |
90 | 0 | (_m), (_v), (_ad)) |
91 | | |
92 | | static inline l1_pgentry_t adjust_guest_l1e(l1_pgentry_t l1e, |
93 | | const struct domain *d) |
94 | 0 | { |
95 | 0 | if ( likely(l1e_get_flags(l1e) & _PAGE_PRESENT) && |
96 | 0 | likely(!is_pv_32bit_domain(d)) ) |
97 | 0 | { |
98 | 0 | /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */ |
99 | 0 | if ( (l1e_get_flags(l1e) & (_PAGE_GUEST_KERNEL | _PAGE_GLOBAL)) == |
100 | 0 | (_PAGE_GUEST_KERNEL | _PAGE_GLOBAL) ) |
101 | 0 | gdprintk(XENLOG_WARNING, "Global bit is set in kernel page %lx\n", |
102 | 0 | l1e_get_pfn(l1e)); |
103 | 0 |
|
104 | 0 | if ( !(l1e_get_flags(l1e) & _PAGE_USER) ) |
105 | 0 | l1e_add_flags(l1e, (_PAGE_GUEST_KERNEL | _PAGE_USER)); |
106 | 0 |
|
107 | 0 | if ( !(l1e_get_flags(l1e) & _PAGE_GUEST_KERNEL) ) |
108 | 0 | l1e_add_flags(l1e, (_PAGE_GLOBAL | _PAGE_USER)); |
109 | 0 | } |
110 | 0 |
|
111 | 0 | return l1e; |
112 | 0 | } Unexecuted instantiation: mm.c:adjust_guest_l1e Unexecuted instantiation: ro-page-fault.c:adjust_guest_l1e Unexecuted instantiation: emul-priv-op.c:adjust_guest_l1e Unexecuted instantiation: grant_table.c:adjust_guest_l1e |
113 | | |
114 | | static inline l2_pgentry_t adjust_guest_l2e(l2_pgentry_t l2e, |
115 | | const struct domain *d) |
116 | 0 | { |
117 | 0 | if ( likely(l2e_get_flags(l2e) & _PAGE_PRESENT) && |
118 | 0 | likely(!is_pv_32bit_domain(d)) ) |
119 | 0 | l2e_add_flags(l2e, _PAGE_USER); |
120 | 0 |
|
121 | 0 | return l2e; |
122 | 0 | } Unexecuted instantiation: ro-page-fault.c:adjust_guest_l2e Unexecuted instantiation: grant_table.c:adjust_guest_l2e Unexecuted instantiation: mm.c:adjust_guest_l2e Unexecuted instantiation: emul-priv-op.c:adjust_guest_l2e |
123 | | |
124 | | static inline l3_pgentry_t adjust_guest_l3e(l3_pgentry_t l3e, |
125 | | const struct domain *d) |
126 | 0 | { |
127 | 0 | if ( likely(l3e_get_flags(l3e) & _PAGE_PRESENT) ) |
128 | 0 | l3e_add_flags(l3e, (likely(!is_pv_32bit_domain(d)) |
129 | 0 | ? _PAGE_USER : _PAGE_USER | _PAGE_RW)); |
130 | 0 |
|
131 | 0 | return l3e; |
132 | 0 | } Unexecuted instantiation: mm.c:adjust_guest_l3e Unexecuted instantiation: emul-priv-op.c:adjust_guest_l3e Unexecuted instantiation: grant_table.c:adjust_guest_l3e Unexecuted instantiation: ro-page-fault.c:adjust_guest_l3e |
133 | | |
134 | | static inline l3_pgentry_t unadjust_guest_l3e(l3_pgentry_t l3e, |
135 | | const struct domain *d) |
136 | 0 | { |
137 | 0 | if ( unlikely(is_pv_32bit_domain(d)) && |
138 | 0 | likely(l3e_get_flags(l3e) & _PAGE_PRESENT) ) |
139 | 0 | l3e_remove_flags(l3e, _PAGE_USER | _PAGE_RW | _PAGE_ACCESSED); |
140 | 0 |
|
141 | 0 | return l3e; |
142 | 0 | } Unexecuted instantiation: ro-page-fault.c:unadjust_guest_l3e Unexecuted instantiation: mm.c:unadjust_guest_l3e Unexecuted instantiation: grant_table.c:unadjust_guest_l3e Unexecuted instantiation: emul-priv-op.c:unadjust_guest_l3e |
143 | | |
144 | | static inline l4_pgentry_t adjust_guest_l4e(l4_pgentry_t l4e, |
145 | | const struct domain *d) |
146 | 0 | { |
147 | 0 | if ( likely(l4e_get_flags(l4e) & _PAGE_PRESENT) && |
148 | 0 | likely(!is_pv_32bit_domain(d)) ) |
149 | 0 | l4e_add_flags(l4e, _PAGE_USER); |
150 | 0 |
|
151 | 0 | return l4e; |
152 | 0 | } Unexecuted instantiation: mm.c:adjust_guest_l4e Unexecuted instantiation: emul-priv-op.c:adjust_guest_l4e Unexecuted instantiation: ro-page-fault.c:adjust_guest_l4e Unexecuted instantiation: grant_table.c:adjust_guest_l4e |
153 | | |
154 | | #endif /* __PV_MM_H__ */ |