Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/common/mem_access.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 * mem_access.c
3
 *
4
 * Memory access support.
5
 *
6
 * Copyright (c) 2011 Virtuata, Inc.
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
23
#include <xen/sched.h>
24
#include <xen/guest_access.h>
25
#include <xen/hypercall.h>
26
#include <xen/vm_event.h>
27
#include <xen/mem_access.h>
28
#include <public/memory.h>
29
#include <xsm/xsm.h>
30
31
int mem_access_memop(unsigned long cmd,
32
                     XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg)
33
0
{
34
0
    unsigned long start_iter = cmd & ~MEMOP_CMD_MASK;
35
0
    long rc;
36
0
    xen_mem_access_op_t mao;
37
0
    struct domain *d;
38
0
39
0
    if ( copy_from_guest(&mao, arg, 1) )
40
0
        return -EFAULT;
41
0
42
0
    rc = rcu_lock_live_remote_domain_by_id(mao.domid, &d);
43
0
    if ( rc )
44
0
        return rc;
45
0
46
0
    rc = -EINVAL;
47
0
    if ( !p2m_mem_access_sanity_check(d) )
48
0
        goto out;
49
0
50
0
    rc = xsm_mem_access(XSM_DM_PRIV, d);
51
0
    if ( rc )
52
0
        goto out;
53
0
54
0
    rc = -ENODEV;
55
0
    if ( unlikely(!vm_event_check_ring(d->vm_event_monitor)) )
56
0
        goto out;
57
0
58
0
    switch ( mao.op )
59
0
    {
60
0
61
0
    case XENMEM_access_op_set_access:
62
0
        rc = -EINVAL;
63
0
        if ( (mao.pfn != ~0ull) &&
64
0
             (mao.nr < start_iter ||
65
0
              ((mao.pfn + mao.nr - 1) < mao.pfn) ||
66
0
              ((mao.pfn + mao.nr - 1) > domain_get_maximum_gpfn(d))) )
67
0
            break;
68
0
69
0
        rc = p2m_set_mem_access(d, _gfn(mao.pfn), mao.nr, start_iter,
70
0
                                MEMOP_CMD_MASK, mao.access, 0);
71
0
        if ( rc > 0 )
72
0
        {
73
0
            ASSERT(!(rc & MEMOP_CMD_MASK));
74
0
            rc = hypercall_create_continuation(__HYPERVISOR_memory_op, "lh",
75
0
                                               XENMEM_access_op | rc, arg);
76
0
        }
77
0
        break;
78
0
79
0
    case XENMEM_access_op_set_access_multi:
80
0
        rc = p2m_set_mem_access_multi(d, mao.pfn_list, mao.access_list, mao.nr,
81
0
                                      start_iter, MEMOP_CMD_MASK, 0);
82
0
        if ( rc > 0 )
83
0
        {
84
0
            ASSERT(!(rc & MEMOP_CMD_MASK));
85
0
            rc = hypercall_create_continuation(__HYPERVISOR_memory_op, "lh",
86
0
                                               XENMEM_access_op | rc, arg);
87
0
        }
88
0
        break;
89
0
90
0
    case XENMEM_access_op_get_access:
91
0
    {
92
0
        xenmem_access_t access;
93
0
94
0
        rc = -ENOSYS;
95
0
        if ( unlikely(start_iter) )
96
0
            break;
97
0
98
0
        rc = -EINVAL;
99
0
        if ( (mao.pfn > domain_get_maximum_gpfn(d)) && mao.pfn != ~0ull )
100
0
            break;
101
0
102
0
        rc = p2m_get_mem_access(d, _gfn(mao.pfn), &access);
103
0
        if ( rc != 0 )
104
0
            break;
105
0
106
0
        mao.access = access;
107
0
        rc = __copy_field_to_guest(arg, &mao, access) ? -EFAULT : 0;
108
0
109
0
        break;
110
0
    }
111
0
112
0
    default:
113
0
        rc = -ENOSYS;
114
0
        break;
115
0
    }
116
0
117
0
 out:
118
0
    rcu_unlock_domain(d);
119
0
    return rc;
120
0
}
121
122
/*
123
 * Local variables:
124
 * mode: C
125
 * c-file-style: "BSD"
126
 * c-basic-offset: 4
127
 * indent-tabs-mode: nil
128
 * End:
129
 */