Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/mm/hap/nested_ept.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * nested_ept.c: Handling virtulized EPT for guest in nested case.
3
 *
4
 * Copyright (c) 2012, Intel Corporation
5
 *  Xiantao Zhang <xiantao.zhang@intel.com>
6
 *
7
 * This program is free software; you can redistribute it and/or modify it
8
 * under the terms and conditions of the GNU General Public License,
9
 * version 2, as published by the Free Software Foundation.
10
 *
11
 * This program is distributed in the hope it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14
 * more details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; If not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <xen/vm_event.h>
20
#include <xen/event.h>
21
#include <public/vm_event.h>
22
#include <asm/domain.h>
23
#include <asm/page.h>
24
#include <asm/paging.h>
25
#include <asm/p2m.h>
26
#include <asm/mem_sharing.h>
27
#include <asm/hap.h>
28
#include <asm/hvm/support.h>
29
30
#include <asm/hvm/nestedhvm.h>
31
32
#include "private.h"
33
34
#include <asm/hvm/vmx/vmx.h>
35
#include <asm/hvm/vmx/vvmx.h>
36
37
/* Must reserved bits in all level entries  */
38
0
#define EPT_MUST_RSV_BITS (((1ull << PADDR_BITS) - 1) & \
39
0
                           ~((1ull << paddr_bits) - 1))
40
41
#define NEPT_CAP_BITS       \
42
0
        (VMX_EPT_INVEPT_ALL_CONTEXT | VMX_EPT_INVEPT_SINGLE_CONTEXT | \
43
0
         VMX_EPT_INVEPT_INSTRUCTION | VMX_EPT_SUPERPAGE_1GB |         \
44
0
         VMX_EPT_SUPERPAGE_2MB | VMX_EPT_MEMORY_TYPE_WB |             \
45
0
         VMX_EPT_MEMORY_TYPE_UC | VMX_EPT_WALK_LENGTH_4_SUPPORTED |   \
46
0
         VMX_EPT_EXEC_ONLY_SUPPORTED)
47
48
#define NVPID_CAP_BITS \
49
0
        (VMX_VPID_INVVPID_INSTRUCTION | VMX_VPID_INVVPID_INDIVIDUAL_ADDR | \
50
0
         VMX_VPID_INVVPID_SINGLE_CONTEXT | VMX_VPID_INVVPID_ALL_CONTEXT |  \
51
0
         VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL)
52
53
0
#define NEPT_1G_ENTRY_FLAG (1 << 11)
54
0
#define NEPT_2M_ENTRY_FLAG (1 << 10)
55
0
#define NEPT_4K_ENTRY_FLAG (1 << 9)
56
57
bool_t nept_sp_entry(ept_entry_t e)
58
0
{
59
0
    return !!(e.sp);
60
0
}
61
62
static bool_t nept_rsv_bits_check(ept_entry_t e, uint32_t level)
63
0
{
64
0
    uint64_t rsv_bits = EPT_MUST_RSV_BITS;
65
0
66
0
    switch ( level )
67
0
    {
68
0
    case 1:
69
0
        break;
70
0
    case 2 ... 3:
71
0
        if ( nept_sp_entry(e) )
72
0
            rsv_bits |=  ((1ull << (9 * (level - 1))) - 1) << PAGE_SHIFT;
73
0
        else
74
0
            rsv_bits |= EPTE_EMT_MASK | EPTE_IGMT_MASK;
75
0
        break;
76
0
    case 4:
77
0
        rsv_bits |= EPTE_EMT_MASK | EPTE_IGMT_MASK | EPTE_SUPER_PAGE_MASK;
78
0
        break;
79
0
    default:
80
0
        gdprintk(XENLOG_ERR,"Unsupported EPT paging level: %d\n", level);
81
0
        BUG();
82
0
        break;
83
0
    }
84
0
    return !!(e.epte & rsv_bits);
85
0
}
86
87
/* EMT checking*/
88
static bool_t nept_emt_bits_check(ept_entry_t e, uint32_t level)
89
0
{
90
0
    if ( e.sp || level == 1 )
91
0
    {
92
0
        if ( e.emt == EPT_EMT_RSV0 || e.emt == EPT_EMT_RSV1 ||
93
0
             e.emt == EPT_EMT_RSV2 )
94
0
            return 1;
95
0
    }
96
0
    return 0;
97
0
}
98
99
static bool_t nept_permission_check(uint32_t rwx_acc, uint32_t rwx_bits)
100
0
{
101
0
    return !(EPTE_RWX_MASK & rwx_acc & ~rwx_bits);
102
0
}
103
104
/* nept's non-present check */
105
static bool_t nept_non_present_check(ept_entry_t e)
106
0
{
107
0
    if ( e.epte & EPTE_RWX_MASK )
108
0
        return 0;
109
0
    return 1;
110
0
}
111
112
uint64_t nept_get_ept_vpid_cap(void)
113
0
{
114
0
    uint64_t caps = 0;
115
0
116
0
    if ( cpu_has_vmx_ept )
117
0
        caps |= NEPT_CAP_BITS;
118
0
    if ( !cpu_has_vmx_ept_exec_only_supported )
119
0
        caps &= ~VMX_EPT_EXEC_ONLY_SUPPORTED;
120
0
    if ( cpu_has_vmx_vpid )
121
0
        caps |= NVPID_CAP_BITS;
122
0
123
0
    return caps;
124
0
}
125
126
static bool_t nept_rwx_bits_check(ept_entry_t e)
127
0
{
128
0
    /*write only or write/execute only*/
129
0
    uint8_t rwx_bits = e.epte & EPTE_RWX_MASK;
130
0
131
0
    if ( rwx_bits == ept_access_w || rwx_bits == ept_access_wx )
132
0
        return 1;
133
0
134
0
    if ( rwx_bits == ept_access_x &&
135
0
         !(nept_get_ept_vpid_cap() & VMX_EPT_EXEC_ONLY_SUPPORTED) )
136
0
        return 1;
137
0
138
0
    return 0;
139
0
}
140
141
/* nept's misconfiguration check */
142
static bool_t nept_misconfiguration_check(ept_entry_t e, uint32_t level)
143
0
{
144
0
    return nept_rsv_bits_check(e, level) ||
145
0
           nept_emt_bits_check(e, level) ||
146
0
           nept_rwx_bits_check(e);
147
0
}
148
149
static int ept_lvl_table_offset(unsigned long gpa, int lvl)
150
0
{
151
0
    return (gpa >> (EPT_L4_PAGETABLE_SHIFT -(4 - lvl) * 9)) &
152
0
           (EPT_PAGETABLE_ENTRIES - 1);
153
0
}
154
155
static uint32_t
156
nept_walk_tables(struct vcpu *v, unsigned long l2ga, ept_walk_t *gw)
157
0
{
158
0
    int lvl;
159
0
    p2m_type_t p2mt;
160
0
    uint32_t rc = 0, ret = 0, gflags;
161
0
    struct domain *d = v->domain;
162
0
    struct p2m_domain *p2m = d->arch.p2m;
163
0
    gfn_t base_gfn = _gfn(nhvm_vcpu_p2m_base(v) >> PAGE_SHIFT);
164
0
    mfn_t lxmfn;
165
0
    ept_entry_t *lxp = NULL;
166
0
167
0
    memset(gw, 0, sizeof(*gw));
168
0
169
0
    for (lvl = 4; lvl > 0; lvl--)
170
0
    {
171
0
        lxp = map_domain_gfn(p2m, base_gfn, &lxmfn, &p2mt, P2M_ALLOC, &rc);
172
0
        if ( !lxp )
173
0
            goto map_err;
174
0
        gw->lxe[lvl] = lxp[ept_lvl_table_offset(l2ga, lvl)];
175
0
        unmap_domain_page(lxp);
176
0
        put_page(mfn_to_page(mfn_x(lxmfn)));
177
0
178
0
        if ( nept_non_present_check(gw->lxe[lvl]) )
179
0
            goto non_present;
180
0
181
0
        if ( nept_misconfiguration_check(gw->lxe[lvl], lvl) )
182
0
            goto misconfig_err;
183
0
184
0
        if ( (lvl == 2 || lvl == 3) && nept_sp_entry(gw->lxe[lvl]) )
185
0
        {
186
0
            /* Generate a fake l1 table entry so callers don't all
187
0
             * have to understand superpages. */
188
0
            unsigned long gfn_lvl_mask =  (1ull << ((lvl - 1) * 9)) - 1;
189
0
            gfn_t start = _gfn(gw->lxe[lvl].mfn);
190
0
            /* Increment the pfn by the right number of 4k pages. */
191
0
            start = _gfn((gfn_x(start) & ~gfn_lvl_mask) +
192
0
                     ((l2ga >> PAGE_SHIFT) & gfn_lvl_mask));
193
0
            gflags = (gw->lxe[lvl].epte & EPTE_FLAG_MASK) |
194
0
                     (lvl == 3 ? NEPT_1G_ENTRY_FLAG: NEPT_2M_ENTRY_FLAG);
195
0
            gw->lxe[0].epte = (gfn_x(start) << PAGE_SHIFT) | gflags;
196
0
            goto done;
197
0
        }
198
0
        if ( lvl > 1 )
199
0
            base_gfn = _gfn(gw->lxe[lvl].mfn);
200
0
    }
201
0
202
0
    /* If this is not a super entry, we can reach here. */
203
0
    gflags = (gw->lxe[1].epte & EPTE_FLAG_MASK) | NEPT_4K_ENTRY_FLAG;
204
0
    gw->lxe[0].epte = (gw->lxe[1].epte & PAGE_MASK) | gflags;
205
0
206
0
done:
207
0
    ret = EPT_TRANSLATE_SUCCEED;
208
0
    goto out;
209
0
210
0
map_err:
211
0
    if ( rc == PFEC_page_paged )
212
0
    {
213
0
        ret = EPT_TRANSLATE_RETRY;
214
0
        goto out;
215
0
    }
216
0
    /* fall through to misconfig error */
217
0
misconfig_err:
218
0
    ret =  EPT_TRANSLATE_MISCONFIG;
219
0
    goto out;
220
0
221
0
non_present:
222
0
    ret = EPT_TRANSLATE_VIOLATION;
223
0
    /* fall through. */
224
0
out:
225
0
    return ret;
226
0
}
227
228
/* Translate a L2 guest address to L1 gpa via L1 EPT paging structure */
229
230
int nept_translate_l2ga(struct vcpu *v, paddr_t l2ga,
231
                        unsigned int *page_order, uint32_t rwx_acc,
232
                        unsigned long *l1gfn, uint8_t *p2m_acc,
233
                        uint64_t *exit_qual, uint32_t *exit_reason)
234
0
{
235
0
    uint32_t rc, rwx_bits = 0;
236
0
    ept_walk_t gw;
237
0
    rwx_acc &= EPTE_RWX_MASK;
238
0
239
0
    *l1gfn = gfn_x(INVALID_GFN);
240
0
241
0
    rc = nept_walk_tables(v, l2ga, &gw);
242
0
    switch ( rc )
243
0
    {
244
0
    case EPT_TRANSLATE_SUCCEED:
245
0
        if ( likely(gw.lxe[0].epte & NEPT_2M_ENTRY_FLAG) )
246
0
        {
247
0
            rwx_bits = gw.lxe[4].epte & gw.lxe[3].epte & gw.lxe[2].epte &
248
0
                       EPTE_RWX_MASK;
249
0
            *page_order = 9;
250
0
        }
251
0
        else if ( gw.lxe[0].epte & NEPT_4K_ENTRY_FLAG )
252
0
        {
253
0
            rwx_bits = gw.lxe[4].epte & gw.lxe[3].epte & gw.lxe[2].epte &
254
0
                       gw.lxe[1].epte & EPTE_RWX_MASK;
255
0
            *page_order = 0;
256
0
        }
257
0
        else if ( gw.lxe[0].epte & NEPT_1G_ENTRY_FLAG  )
258
0
        {
259
0
            rwx_bits = gw.lxe[4].epte & gw.lxe[3].epte  & EPTE_RWX_MASK;
260
0
            *page_order = 18;
261
0
        }
262
0
        else
263
0
        {
264
0
            gdprintk(XENLOG_ERR, "Uncorrect l1 entry!\n");
265
0
            BUG();
266
0
        }
267
0
        if ( nept_permission_check(rwx_acc, rwx_bits) )
268
0
        {
269
0
            *l1gfn = gw.lxe[0].mfn;
270
0
            *p2m_acc = (uint8_t)rwx_bits;
271
0
            break;
272
0
        }
273
0
        rc = EPT_TRANSLATE_VIOLATION;
274
0
    /* Fall through to EPT violation if permission check fails. */
275
0
    case EPT_TRANSLATE_VIOLATION:
276
0
        *exit_qual = (*exit_qual & 0xffffffc0) | (rwx_bits << 3) | rwx_acc;
277
0
        *exit_reason = EXIT_REASON_EPT_VIOLATION;
278
0
        break;
279
0
280
0
    case EPT_TRANSLATE_MISCONFIG:
281
0
        rc = EPT_TRANSLATE_MISCONFIG;
282
0
        *exit_qual = 0;
283
0
        *exit_reason = EXIT_REASON_EPT_MISCONFIG;
284
0
        break;
285
0
    case EPT_TRANSLATE_RETRY:
286
0
        break;
287
0
    default:
288
0
        gdprintk(XENLOG_ERR, "Unsupported ept translation type!:%d\n", rc);
289
0
        BUG();
290
0
        break;
291
0
    }
292
0
    return rc;
293
0
}