]>
Commit | Line | Data |
---|---|---|
9ed49310 JK |
1 | diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/libxc/xc_mem_access.c xen-4.4.0/tools/libxc/xc_mem_access.c |
2 | --- xen-4.4.0.orig/tools/libxc/xc_mem_access.c 2014-03-10 11:43:57.000000000 +0100 | |
3 | +++ xen-4.4.0/tools/libxc/xc_mem_access.c 2014-06-18 10:19:54.000000000 +0200 | |
4 | @@ -24,19 +24,9 @@ | |
5 | #include "xc_private.h" | |
6 | ||
7 | ||
8 | -int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, | |
9 | - uint32_t *port) | |
10 | +void *xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port) | |
11 | { | |
12 | - if ( !port ) | |
13 | - { | |
14 | - errno = EINVAL; | |
15 | - return -1; | |
16 | - } | |
17 | - | |
18 | - return xc_mem_event_control(xch, domain_id, | |
19 | - XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE, | |
20 | - XEN_DOMCTL_MEM_EVENT_OP_ACCESS, | |
21 | - port); | |
22 | + return xc_mem_event_enable(xch, domain_id, HVM_PARAM_ACCESS_RING_PFN, port); | |
23 | } | |
24 | ||
25 | int xc_mem_access_disable(xc_interface *xch, domid_t domain_id) | |
26 | diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/libxc/xc_mem_event.c xen-4.4.0/tools/libxc/xc_mem_event.c | |
27 | --- xen-4.4.0.orig/tools/libxc/xc_mem_event.c 2014-03-10 11:43:57.000000000 +0100 | |
28 | +++ xen-4.4.0/tools/libxc/xc_mem_event.c 2014-06-18 10:19:54.000000000 +0200 | |
29 | @@ -56,3 +56,118 @@ | |
30 | return do_memory_op(xch, mode, &meo, sizeof(meo)); | |
31 | } | |
32 | ||
33 | +void *xc_mem_event_enable(xc_interface *xch, domid_t domain_id, int param, | |
34 | + uint32_t *port) | |
35 | +{ | |
36 | + void *ring_page = NULL; | |
37 | + unsigned long ring_pfn, mmap_pfn; | |
38 | + unsigned int op, mode; | |
39 | + int rc1, rc2, saved_errno; | |
40 | + | |
41 | + if ( !port ) | |
42 | + { | |
43 | + errno = EINVAL; | |
44 | + return NULL; | |
45 | + } | |
46 | + | |
47 | + /* Pause the domain for ring page setup */ | |
48 | + rc1 = xc_domain_pause(xch, domain_id); | |
49 | + if ( rc1 != 0 ) | |
50 | + { | |
51 | + PERROR("Unable to pause domain\n"); | |
52 | + return NULL; | |
53 | + } | |
54 | + | |
55 | + /* Get the pfn of the ring page */ | |
56 | + rc1 = xc_get_hvm_param(xch, domain_id, param, &ring_pfn); | |
57 | + if ( rc1 != 0 ) | |
58 | + { | |
59 | + PERROR("Failed to get pfn of ring page\n"); | |
60 | + goto out; | |
61 | + } | |
62 | + | |
63 | + mmap_pfn = ring_pfn; | |
64 | + ring_page = xc_map_foreign_batch(xch, domain_id, PROT_READ | PROT_WRITE, | |
65 | + &mmap_pfn, 1); | |
66 | + if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB ) | |
67 | + { | |
68 | + /* Map failed, populate ring page */ | |
69 | + rc1 = xc_domain_populate_physmap_exact(xch, domain_id, 1, 0, 0, | |
70 | + &ring_pfn); | |
71 | + if ( rc1 != 0 ) | |
72 | + { | |
73 | + PERROR("Failed to populate ring pfn\n"); | |
74 | + goto out; | |
75 | + } | |
76 | + | |
77 | + mmap_pfn = ring_pfn; | |
78 | + ring_page = xc_map_foreign_batch(xch, domain_id, PROT_READ | PROT_WRITE, | |
79 | + &mmap_pfn, 1); | |
80 | + if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB ) | |
81 | + { | |
82 | + PERROR("Could not map the ring page\n"); | |
83 | + goto out; | |
84 | + } | |
85 | + } | |
86 | + | |
87 | + switch ( param ) | |
88 | + { | |
89 | + case HVM_PARAM_PAGING_RING_PFN: | |
90 | + op = XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE; | |
91 | + mode = XEN_DOMCTL_MEM_EVENT_OP_PAGING; | |
92 | + break; | |
93 | + | |
94 | + case HVM_PARAM_ACCESS_RING_PFN: | |
95 | + op = XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE; | |
96 | + mode = XEN_DOMCTL_MEM_EVENT_OP_ACCESS; | |
97 | + break; | |
98 | + | |
99 | + case HVM_PARAM_SHARING_RING_PFN: | |
100 | + op = XEN_DOMCTL_MEM_EVENT_OP_SHARING_ENABLE; | |
101 | + mode = XEN_DOMCTL_MEM_EVENT_OP_SHARING; | |
102 | + break; | |
103 | + | |
104 | + /* | |
105 | + * This is for the outside chance that the HVM_PARAM is valid but is invalid | |
106 | + * as far as mem_event goes. | |
107 | + */ | |
108 | + default: | |
109 | + errno = EINVAL; | |
110 | + rc1 = -1; | |
111 | + goto out; | |
112 | + } | |
113 | + | |
114 | + rc1 = xc_mem_event_control(xch, domain_id, op, mode, port); | |
115 | + if ( rc1 != 0 ) | |
116 | + { | |
117 | + PERROR("Failed to enable mem_event\n"); | |
118 | + goto out; | |
119 | + } | |
120 | + | |
121 | + /* Remove the ring_pfn from the guest's physmap */ | |
122 | + rc1 = xc_domain_decrease_reservation_exact(xch, domain_id, 1, 0, &ring_pfn); | |
123 | + if ( rc1 != 0 ) | |
124 | + PERROR("Failed to remove ring page from guest physmap"); | |
125 | + | |
126 | + out: | |
127 | + saved_errno = errno; | |
128 | + | |
129 | + rc2 = xc_domain_unpause(xch, domain_id); | |
130 | + if ( rc1 != 0 || rc2 != 0 ) | |
131 | + { | |
132 | + if ( rc2 != 0 ) | |
133 | + { | |
134 | + if ( rc1 == 0 ) | |
135 | + saved_errno = errno; | |
136 | + PERROR("Unable to unpause domain"); | |
137 | + } | |
138 | + | |
139 | + if ( ring_page ) | |
140 | + munmap(ring_page, XC_PAGE_SIZE); | |
141 | + ring_page = NULL; | |
142 | + | |
143 | + errno = saved_errno; | |
144 | + } | |
145 | + | |
146 | + return ring_page; | |
147 | +} | |
148 | diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/libxc/xenctrl.h xen-4.4.0/tools/libxc/xenctrl.h | |
149 | --- xen-4.4.0.orig/tools/libxc/xenctrl.h 2014-03-10 11:43:57.000000000 +0100 | |
150 | +++ xen-4.4.0/tools/libxc/xenctrl.h 2014-06-18 10:19:54.000000000 +0200 | |
151 | @@ -2040,6 +2040,12 @@ | |
152 | int xc_mem_event_memop(xc_interface *xch, domid_t domain_id, | |
153 | unsigned int op, unsigned int mode, | |
154 | uint64_t gfn, void *buffer); | |
155 | +/* | |
156 | + * Enables mem_event and returns the mapped ring page indicated by param. | |
157 | + * param can be HVM_PARAM_PAGING/ACCESS/SHARING_RING_PFN | |
158 | + */ | |
159 | +void *xc_mem_event_enable(xc_interface *xch, domid_t domain_id, int param, | |
160 | + uint32_t *port); | |
161 | ||
162 | /** | |
163 | * Mem paging operations. | |
164 | @@ -2060,7 +2066,13 @@ | |
165 | * Access tracking operations. | |
166 | * Supported only on Intel EPT 64 bit processors. | |
167 | */ | |
168 | -int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port); | |
169 | + | |
170 | +/* | |
171 | + * Enables mem_access and returns the mapped ring page. | |
172 | + * Will return NULL on error. | |
173 | + * Caller has to unmap this page when done. | |
174 | + */ | |
175 | +void *xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port); | |
176 | int xc_mem_access_disable(xc_interface *xch, domid_t domain_id); | |
177 | int xc_mem_access_resume(xc_interface *xch, domid_t domain_id, | |
178 | unsigned long gfn); | |
179 | diff -durN -x '*~' -x '*.orig' -x '*.rej' xen-4.4.0.orig/tools/tests/xen-access/xen-access.c xen-4.4.0/tools/tests/xen-access/xen-access.c | |
180 | --- xen-4.4.0.orig/tools/tests/xen-access/xen-access.c 2014-03-10 11:43:57.000000000 +0100 | |
181 | +++ xen-4.4.0/tools/tests/xen-access/xen-access.c 2014-06-18 10:20:55.000000000 +0200 | |
182 | @@ -231,7 +231,6 @@ | |
183 | xenaccess_t *xenaccess = 0; | |
184 | xc_interface *xch; | |
185 | int rc; | |
186 | - unsigned long ring_pfn, mmap_pfn; | |
187 | ||
188 | xch = xc_interface_open(NULL, NULL, 0); | |
189 | if ( !xch ) | |
190 | @@ -253,40 +252,12 @@ | |
191 | /* Initialise lock */ | |
192 | mem_event_ring_lock_init(&xenaccess->mem_event); | |
193 | ||
194 | - /* Map the ring page */ | |
195 | - xc_get_hvm_param(xch, xenaccess->mem_event.domain_id, | |
196 | - HVM_PARAM_ACCESS_RING_PFN, &ring_pfn); | |
197 | - mmap_pfn = ring_pfn; | |
198 | - xenaccess->mem_event.ring_page = | |
199 | - xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id, | |
200 | - PROT_READ | PROT_WRITE, &mmap_pfn, 1); | |
201 | - if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB ) | |
202 | - { | |
203 | - /* Map failed, populate ring page */ | |
204 | - rc = xc_domain_populate_physmap_exact(xenaccess->xc_handle, | |
205 | - xenaccess->mem_event.domain_id, | |
206 | - 1, 0, 0, &ring_pfn); | |
207 | - if ( rc != 0 ) | |
208 | - { | |
209 | - PERROR("Failed to populate ring gfn\n"); | |
210 | - goto err; | |
211 | - } | |
212 | - | |
213 | - mmap_pfn = ring_pfn; | |
214 | - xenaccess->mem_event.ring_page = | |
215 | - xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id, | |
216 | - PROT_READ | PROT_WRITE, &mmap_pfn, 1); | |
217 | - if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB ) | |
218 | - { | |
219 | - PERROR("Could not map the ring page\n"); | |
220 | - goto err; | |
221 | - } | |
222 | - } | |
223 | - | |
224 | - /* Initialise Xen */ | |
225 | - rc = xc_mem_access_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id, | |
226 | - &xenaccess->mem_event.evtchn_port); | |
227 | - if ( rc != 0 ) | |
228 | + /* Enable mem_access */ | |
229 | + xenaccess->mem_event.ring_page = | |
230 | + xc_mem_access_enable(xenaccess->xc_handle, | |
231 | + xenaccess->mem_event.domain_id, | |
232 | + &xenaccess->mem_event.evtchn_port); | |
233 | + if ( xenaccess->mem_event.ring_page == NULL ) | |
234 | { | |
235 | switch ( errno ) { | |
236 | case EBUSY: | |
237 | @@ -296,7 +267,7 @@ | |
238 | ERROR("EPT not supported for this guest"); | |
239 | break; | |
240 | default: | |
241 | - perror("Error initialising shared page"); | |
242 | + perror("Error enabling mem_access"); | |
243 | break; | |
244 | } | |
245 | goto err; | |
246 | @@ -330,11 +301,6 @@ | |
247 | (mem_event_sring_t *)xenaccess->mem_event.ring_page, | |
248 | PAGE_SIZE); | |
249 | ||
250 | - /* Now that the ring is set, remove it from the guest's physmap */ | |
251 | - if ( xc_domain_decrease_reservation_exact(xch, | |
252 | - xenaccess->mem_event.domain_id, 1, 0, &ring_pfn) ) | |
253 | - PERROR("Failed to remove ring from guest physmap"); | |
254 | - | |
255 | /* Get platform info */ | |
256 | xenaccess->platform_info = malloc(sizeof(xc_platform_info_t)); | |
257 | if ( xenaccess->platform_info == NULL ) |