aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenpaging
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/xenpaging
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/xenpaging')
-rw-r--r--tools/xenpaging/xenpaging.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c
index 06ccdd9960..b9ba00fa11 100644
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -281,6 +281,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
xentoollog_logger *dbg = NULL;
char *p;
int rc;
+ unsigned long ring_pfn, mmap_pfn;
/* Allocate memory */
paging = calloc(1, sizeof(struct xenpaging));
@@ -337,24 +338,39 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
goto err;
}
- /* Initialise ring page */
- paging->mem_event.ring_page = init_page();
- if ( paging->mem_event.ring_page == NULL )
+ /* Map the ring page */
+ xc_get_hvm_param(xch, paging->mem_event.domain_id,
+ HVM_PARAM_PAGING_RING_PFN, &ring_pfn);
+ mmap_pfn = ring_pfn;
+ paging->mem_event.ring_page =
+ xc_map_foreign_batch(xch, paging->mem_event.domain_id,
+ PROT_READ | PROT_WRITE, &mmap_pfn, 1);
+ if ( mmap_pfn & XEN_DOMCTL_PFINFO_XTAB )
{
- PERROR("Error initialising ring page");
- goto err;
- }
+ /* Map failed, populate ring page */
+ rc = xc_domain_populate_physmap_exact(paging->xc_handle,
+ paging->mem_event.domain_id,
+ 1, 0, 0, &ring_pfn);
+ if ( rc != 0 )
+ {
+ PERROR("Failed to populate ring gfn\n");
+ goto err;
+ }
- /* Initialise ring */
- SHARED_RING_INIT((mem_event_sring_t *)paging->mem_event.ring_page);
- BACK_RING_INIT(&paging->mem_event.back_ring,
- (mem_event_sring_t *)paging->mem_event.ring_page,
- PAGE_SIZE);
+ mmap_pfn = ring_pfn;
+ paging->mem_event.ring_page =
+ xc_map_foreign_batch(xch, paging->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_paging_enable(xch, paging->mem_event.domain_id,
- &paging->mem_event.evtchn_port,
- paging->mem_event.ring_page);
+ &paging->mem_event.evtchn_port);
if ( rc != 0 )
{
switch ( errno ) {
@@ -394,6 +410,12 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
paging->mem_event.port = rc;
+ /* Initialise ring */
+ SHARED_RING_INIT((mem_event_sring_t *)paging->mem_event.ring_page);
+ BACK_RING_INIT(&paging->mem_event.back_ring,
+ (mem_event_sring_t *)paging->mem_event.ring_page,
+ PAGE_SIZE);
+
/* Get max_pages from guest if not provided via cmdline */
if ( !paging->max_pages )
{
@@ -469,8 +491,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
if ( paging->mem_event.ring_page )
{
- munlock(paging->mem_event.ring_page, PAGE_SIZE);
- free(paging->mem_event.ring_page);
+ munmap(paging->mem_event.ring_page, PAGE_SIZE);
}
free(dom_path);
@@ -495,6 +516,7 @@ static void xenpaging_teardown(struct xenpaging *paging)
paging->xc_handle = NULL;
/* Tear down domain paging in Xen */
+ munmap(paging->mem_event.ring_page, PAGE_SIZE);
rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id);
if ( rc != 0 )
{