Coverage Report

Created: 2017-10-25 09:10

/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__ */