aboutsummaryrefslogtreecommitdiffstats
path: root/tools/tests
diff options
context:
space:
mode:
authorTim Deegan <tim@xen.org>2012-03-08 16:40:05 +0000
committerTim Deegan <tim@xen.org>2012-03-08 16:40:05 +0000
commit770d1e858de56ba8f2e0d7e45c08f48d599528e5 (patch)
treefcae677231c44b4c20c0816f41cbd51074a5412e /tools/tests
parent7a3de767373545388a9fded238b3450c5b21066d (diff)
downloadxen-770d1e858de56ba8f2e0d7e45c08f48d599528e5.tar.gz
xen-770d1e858de56ba8f2e0d7e45c08f48d599528e5.tar.bz2
xen-770d1e858de56ba8f2e0d7e45c08f48d599528e5.zip
Use a reserved pfn in the guest address space to store mem event rings
This solves a long-standing issue in which the pages backing these rings were pages belonging to dom0 user-space processes. Thus, if the process would die unexpectedly, Xen would keep posting events to a page now belonging to some other process. We update all API-consumers in tree (xenpaging and xen-access). This is an API/ABI change, so please speak up if it breaks your accumptions. The patch touches tools, hypervisor x86/hvm bits, and hypervisor x86/mm bits. Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org> Acked-by: Tim Deegan <tim@xen.org> Acked-by: Ian Campbell <ian.campbell@citrix.com> Committed-by: Tim Deegan <tim@xen.org>
Diffstat (limited to 'tools/tests')
-rw-r--r--tools/tests/xen-access/xen-access.c83
1 files changed, 40 insertions, 43 deletions
diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
index d297529e42..fce886432a 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -166,36 +166,13 @@ int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned lon
err:
return -errno;
}
-
-static void *init_page(void)
-{
- void *buffer;
- int ret;
-
- /* Allocated page memory */
- ret = posix_memalign(&buffer, PAGE_SIZE, PAGE_SIZE);
- if ( ret != 0 )
- goto out_alloc;
-
- /* Lock buffer in memory so it can't be paged out */
- ret = mlock(buffer, PAGE_SIZE);
- if ( ret != 0 )
- goto out_lock;
-
- return buffer;
-
- munlock(buffer, PAGE_SIZE);
- out_lock:
- free(buffer);
- out_alloc:
- return NULL;
-}
xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
{
xenaccess_t *xenaccess;
xc_interface *xch;
int rc;
+ unsigned long ring_pfn, mmap_pfn;
xch = xc_interface_open(NULL, NULL, 0);
if ( !xch )
@@ -214,28 +191,42 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
/* Set domain id */
xenaccess->mem_event.domain_id = domain_id;
- /* Initialise ring page */
- xenaccess->mem_event.ring_page = init_page();
- if ( xenaccess->mem_event.ring_page == NULL )
- {
- ERROR("Error initialising ring page");
- goto err;
- }
-
-
- /* Initialise ring */
- SHARED_RING_INIT((mem_event_sring_t *)xenaccess->mem_event.ring_page);
- BACK_RING_INIT(&xenaccess->mem_event.back_ring,
- (mem_event_sring_t *)xenaccess->mem_event.ring_page,
- PAGE_SIZE);
-
/* Initialise lock */
mem_event_ring_lock_init(&xenaccess->mem_event);
+ /* Map the ring page */
+ xc_get_hvm_param(xch, xenaccess->mem_event.domain_id,
+ HVM_PARAM_ACCESS_RING_PFN, &ring_pfn);
+ mmap_pfn = ring_pfn;
+ xenaccess->mem_event.ring_page =
+ xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id,
+ PROT_READ | PROT_WRITE, &mmap_pfn, 1);
+ if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
+ {
+ /* Map failed, populate ring page */
+ rc = xc_domain_populate_physmap_exact(xenaccess->xc_handle,
+ xenaccess->mem_event.domain_id,
+ 1, 0, 0, &ring_pfn);
+ if ( rc != 0 )
+ {
+ PERROR("Failed to populate ring gfn\n");
+ goto err;
+ }
+
+ mmap_pfn = ring_pfn;
+ xenaccess->mem_event.ring_page =
+ xc_map_foreign_batch(xch, xenaccess->mem_event.domain_id,
+ PROT_READ | PROT_WRITE, &mmap_pfn, 1);
+ if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
+ {
+ PERROR("Could not map the ring page\n");
+ goto err;
+ }
+ }
+
/* Initialise Xen */
rc = xc_mem_access_enable(xenaccess->xc_handle, xenaccess->mem_event.domain_id,
- &xenaccess->mem_event.evtchn_port,
- xenaccess->mem_event.ring_page);
+ &xenaccess->mem_event.evtchn_port);
if ( rc != 0 )
{
switch ( errno ) {
@@ -272,6 +263,12 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
xenaccess->mem_event.port = rc;
+ /* Initialise ring */
+ SHARED_RING_INIT((mem_event_sring_t *)xenaccess->mem_event.ring_page);
+ BACK_RING_INIT(&xenaccess->mem_event.back_ring,
+ (mem_event_sring_t *)xenaccess->mem_event.ring_page,
+ PAGE_SIZE);
+
/* Get platform info */
xenaccess->platform_info = malloc(sizeof(xc_platform_info_t));
if ( xenaccess->platform_info == NULL )
@@ -316,8 +313,7 @@ xenaccess_t *xenaccess_init(xc_interface **xch_r, domid_t domain_id)
{
if ( xenaccess->mem_event.ring_page )
{
- munlock(xenaccess->mem_event.ring_page, PAGE_SIZE);
- free(xenaccess->mem_event.ring_page);
+ munmap(xenaccess->mem_event.ring_page, PAGE_SIZE);
}
free(xenaccess->platform_info);
@@ -337,6 +333,7 @@ int xenaccess_teardown(xc_interface *xch, xenaccess_t *xenaccess)
return 0;
/* Tear down domain xenaccess in Xen */
+ munmap(xenaccess->mem_event.ring_page, PAGE_SIZE);
rc = xc_mem_access_disable(xenaccess->xc_handle, xenaccess->mem_event.domain_id);
if ( rc != 0 )
{