1 /******************************************************************************
2  *
3  * tools/libxc/xc_mem_access.c
4  *
5  * Interface to low-level memory access mode functionality
6  *
7  * Copyright (c) 2011 Virtuata, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "xc_private.h"
24 #include <xen/memory.h>
25 
xc_set_mem_access(xc_interface * xch,uint32_t domain_id,xenmem_access_t access,uint64_t first_pfn,uint32_t nr)26 int xc_set_mem_access(xc_interface *xch,
27                       uint32_t domain_id,
28                       xenmem_access_t access,
29                       uint64_t first_pfn,
30                       uint32_t nr)
31 {
32     xen_mem_access_op_t mao =
33     {
34         .op     = XENMEM_access_op_set_access,
35         .domid  = domain_id,
36         .access = access,
37         .pfn    = first_pfn,
38         .nr     = nr
39     };
40 
41     return do_memory_op(xch, XENMEM_access_op, &mao, sizeof(mao));
42 }
43 
xc_set_mem_access_multi(xc_interface * xch,uint32_t domain_id,uint8_t * access,uint64_t * pages,uint32_t nr)44 int xc_set_mem_access_multi(xc_interface *xch,
45                             uint32_t domain_id,
46                             uint8_t *access,
47                             uint64_t *pages,
48                             uint32_t nr)
49 {
50     DECLARE_HYPERCALL_BOUNCE(access, nr, XC_HYPERCALL_BUFFER_BOUNCE_IN);
51     DECLARE_HYPERCALL_BOUNCE(pages, nr * sizeof(uint64_t),
52                              XC_HYPERCALL_BUFFER_BOUNCE_IN);
53     int rc;
54 
55     xen_mem_access_op_t mao =
56     {
57         .op       = XENMEM_access_op_set_access_multi,
58         .domid    = domain_id,
59         .access   = XENMEM_access_default + 1, /* Invalid value */
60         .pfn      = ~0UL, /* Invalid GFN */
61         .nr       = nr,
62     };
63 
64     if ( xc_hypercall_bounce_pre(xch, pages) ||
65          xc_hypercall_bounce_pre(xch, access) )
66     {
67         PERROR("Could not bounce memory for XENMEM_access_op_set_access_multi");
68         return -1;
69     }
70 
71     set_xen_guest_handle(mao.pfn_list, pages);
72     set_xen_guest_handle(mao.access_list, access);
73 
74     rc = do_memory_op(xch, XENMEM_access_op, &mao, sizeof(mao));
75 
76     xc_hypercall_bounce_post(xch, access);
77     xc_hypercall_bounce_post(xch, pages);
78 
79     return rc;
80 }
81 
xc_get_mem_access(xc_interface * xch,uint32_t domain_id,uint64_t pfn,xenmem_access_t * access)82 int xc_get_mem_access(xc_interface *xch,
83                       uint32_t domain_id,
84                       uint64_t pfn,
85                       xenmem_access_t *access)
86 {
87     int rc;
88     xen_mem_access_op_t mao =
89     {
90         .op    = XENMEM_access_op_get_access,
91         .domid = domain_id,
92         .pfn   = pfn
93     };
94 
95     rc = do_memory_op(xch, XENMEM_access_op, &mao, sizeof(mao));
96 
97     if ( rc == 0 )
98         *access = mao.access;
99 
100     return rc;
101 }
102 
103 /*
104  * Local variables:
105  * mode: C
106  * c-file-style: "BSD"
107  * c-basic-offset: 4
108  * indent-tabs-mode: nil
109  * End:
110  */
111