diff options
author | Tim Deegan <tim@xen.org> | 2012-03-08 16:40:05 +0000 |
---|---|---|
committer | Tim Deegan <tim@xen.org> | 2012-03-08 16:40:05 +0000 |
commit | 770d1e858de56ba8f2e0d7e45c08f48d599528e5 (patch) | |
tree | fcae677231c44b4c20c0816f41cbd51074a5412e /tools/libxc | |
parent | 7a3de767373545388a9fded238b3450c5b21066d (diff) | |
download | xen-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/libxc')
-rw-r--r-- | tools/libxc/xc_domain_restore.c | 42 | ||||
-rw-r--r-- | tools/libxc/xc_domain_save.c | 36 | ||||
-rw-r--r-- | tools/libxc/xc_hvm_build.c | 21 | ||||
-rw-r--r-- | tools/libxc/xc_mem_access.c | 6 | ||||
-rw-r--r-- | tools/libxc/xc_mem_event.c | 3 | ||||
-rw-r--r-- | tools/libxc/xc_mem_paging.c | 6 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 8 | ||||
-rw-r--r-- | tools/libxc/xg_save_restore.h | 4 |
8 files changed, 107 insertions, 19 deletions
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c index 06bea86718..3e4d5183a5 100644 --- a/tools/libxc/xc_domain_restore.c +++ b/tools/libxc/xc_domain_restore.c @@ -677,6 +677,9 @@ typedef struct { int max_vcpu_id; uint64_t vcpumap; uint64_t identpt; + uint64_t paging_ring_pfn; + uint64_t access_ring_pfn; + uint64_t sharing_ring_pfn; uint64_t vm86_tss; uint64_t console_pfn; uint64_t acpi_ioport_location; @@ -750,6 +753,39 @@ static int pagebuf_get_one(xc_interface *xch, struct restore_ctx *ctx, // DPRINTF("EPT identity map address: %llx\n", buf->identpt); return pagebuf_get_one(xch, ctx, buf, fd, dom); + case XC_SAVE_ID_HVM_PAGING_RING_PFN: + /* Skip padding 4 bytes then read the paging ring location. */ + if ( RDEXACT(fd, &buf->paging_ring_pfn, sizeof(uint32_t)) || + RDEXACT(fd, &buf->paging_ring_pfn, sizeof(uint64_t)) ) + { + PERROR("error read the paging ring pfn"); + return -1; + } + // DPRINTF("paging ring pfn address: %llx\n", buf->paging_ring_pfn); + return pagebuf_get_one(xch, ctx, buf, fd, dom); + + case XC_SAVE_ID_HVM_ACCESS_RING_PFN: + /* Skip padding 4 bytes then read the mem access ring location. */ + if ( RDEXACT(fd, &buf->access_ring_pfn, sizeof(uint32_t)) || + RDEXACT(fd, &buf->access_ring_pfn, sizeof(uint64_t)) ) + { + PERROR("error read the access ring pfn"); + return -1; + } + // DPRINTF("access ring pfn address: %llx\n", buf->access_ring_pfn); + return pagebuf_get_one(xch, ctx, buf, fd, dom); + + case XC_SAVE_ID_HVM_SHARING_RING_PFN: + /* Skip padding 4 bytes then read the sharing ring location. */ + if ( RDEXACT(fd, &buf->sharing_ring_pfn, sizeof(uint32_t)) || + RDEXACT(fd, &buf->sharing_ring_pfn, sizeof(uint64_t)) ) + { + PERROR("error read the sharing ring pfn"); + return -1; + } + // DPRINTF("sharing ring pfn address: %llx\n", buf->sharing_ring_pfn); + return pagebuf_get_one(xch, ctx, buf, fd, dom); + case XC_SAVE_ID_HVM_VM86_TSS: /* Skip padding 4 bytes then read the vm86 TSS location. */ if ( RDEXACT(fd, &buf->vm86_tss, sizeof(uint32_t)) || @@ -1460,6 +1496,12 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom, /* should this be deferred? does it change? */ if ( pagebuf.identpt ) xc_set_hvm_param(xch, dom, HVM_PARAM_IDENT_PT, pagebuf.identpt); + if ( pagebuf.paging_ring_pfn ) + xc_set_hvm_param(xch, dom, HVM_PARAM_PAGING_RING_PFN, pagebuf.paging_ring_pfn); + if ( pagebuf.access_ring_pfn ) + xc_set_hvm_param(xch, dom, HVM_PARAM_ACCESS_RING_PFN, pagebuf.access_ring_pfn); + if ( pagebuf.sharing_ring_pfn ) + xc_set_hvm_param(xch, dom, HVM_PARAM_SHARING_RING_PFN, pagebuf.sharing_ring_pfn); if ( pagebuf.vm86_tss ) xc_set_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, pagebuf.vm86_tss); if ( pagebuf.console_pfn ) diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c index 9fa39b2f1c..a9216ddf71 100644 --- a/tools/libxc/xc_domain_save.c +++ b/tools/libxc/xc_domain_save.c @@ -1639,6 +1639,42 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t dom, uint32_t max_iter goto out; } + chunk.id = XC_SAVE_ID_HVM_PAGING_RING_PFN; + chunk.data = 0; + xc_get_hvm_param(xch, dom, HVM_PARAM_PAGING_RING_PFN, + (unsigned long *)&chunk.data); + + if ( (chunk.data != 0) && + wrexact(io_fd, &chunk, sizeof(chunk)) ) + { + PERROR("Error when writing the paging ring pfn for guest"); + goto out; + } + + chunk.id = XC_SAVE_ID_HVM_ACCESS_RING_PFN; + chunk.data = 0; + xc_get_hvm_param(xch, dom, HVM_PARAM_ACCESS_RING_PFN, + (unsigned long *)&chunk.data); + + if ( (chunk.data != 0) && + wrexact(io_fd, &chunk, sizeof(chunk)) ) + { + PERROR("Error when writing the access ring pfn for guest"); + goto out; + } + + chunk.id = XC_SAVE_ID_HVM_SHARING_RING_PFN; + chunk.data = 0; + xc_get_hvm_param(xch, dom, HVM_PARAM_SHARING_RING_PFN, + (unsigned long *)&chunk.data); + + if ( (chunk.data != 0) && + wrexact(io_fd, &chunk, sizeof(chunk)) ) + { + PERROR("Error when writing the sharing ring pfn for guest"); + goto out; + } + chunk.id = XC_SAVE_ID_HVM_VM86_TSS; chunk.data = 0; xc_get_hvm_param(xch, dom, HVM_PARAM_VM86_TSS, diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 780b23f5b2..696c012291 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -38,12 +38,15 @@ #define SUPERPAGE_1GB_SHIFT 18 #define SUPERPAGE_1GB_NR_PFNS (1UL << SUPERPAGE_1GB_SHIFT) -#define SPECIALPAGE_BUFIOREQ 0 -#define SPECIALPAGE_XENSTORE 1 -#define SPECIALPAGE_IOREQ 2 -#define SPECIALPAGE_IDENT_PT 3 -#define SPECIALPAGE_CONSOLE 4 -#define NR_SPECIAL_PAGES 5 +#define SPECIALPAGE_PAGING 0 +#define SPECIALPAGE_ACCESS 1 +#define SPECIALPAGE_SHARING 2 +#define SPECIALPAGE_BUFIOREQ 3 +#define SPECIALPAGE_XENSTORE 4 +#define SPECIALPAGE_IOREQ 5 +#define SPECIALPAGE_IDENT_PT 6 +#define SPECIALPAGE_CONSOLE 7 +#define NR_SPECIAL_PAGES 8 #define special_pfn(x) (0xff000u - NR_SPECIAL_PAGES + (x)) static void build_hvm_info(void *hvm_info_page, uint64_t mem_size, @@ -356,6 +359,12 @@ static int setup_guest(xc_interface *xch, special_pfn(SPECIALPAGE_IOREQ)); xc_set_hvm_param(xch, dom, HVM_PARAM_CONSOLE_PFN, special_pfn(SPECIALPAGE_CONSOLE)); + xc_set_hvm_param(xch, dom, HVM_PARAM_PAGING_RING_PFN, + special_pfn(SPECIALPAGE_PAGING)); + xc_set_hvm_param(xch, dom, HVM_PARAM_ACCESS_RING_PFN, + special_pfn(SPECIALPAGE_ACCESS)); + xc_set_hvm_param(xch, dom, HVM_PARAM_SHARING_RING_PFN, + special_pfn(SPECIALPAGE_SHARING)); /* * Identity-map page table is required for running with CR0.PG=0 when diff --git a/tools/libxc/xc_mem_access.c b/tools/libxc/xc_mem_access.c index a3786025f5..01fcf41a40 100644 --- a/tools/libxc/xc_mem_access.c +++ b/tools/libxc/xc_mem_access.c @@ -25,7 +25,7 @@ int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, - uint32_t *port, void *ring_page) + uint32_t *port) { if ( !port ) { @@ -36,7 +36,7 @@ int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, return xc_mem_event_control(xch, domain_id, XEN_DOMCTL_MEM_EVENT_OP_ACCESS_ENABLE, XEN_DOMCTL_MEM_EVENT_OP_ACCESS, - port, ring_page); + port); } int xc_mem_access_disable(xc_interface *xch, domid_t domain_id) @@ -44,7 +44,7 @@ int xc_mem_access_disable(xc_interface *xch, domid_t domain_id) return xc_mem_event_control(xch, domain_id, XEN_DOMCTL_MEM_EVENT_OP_ACCESS_DISABLE, XEN_DOMCTL_MEM_EVENT_OP_ACCESS, - NULL, NULL); + NULL); } int xc_mem_access_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn) diff --git a/tools/libxc/xc_mem_event.c b/tools/libxc/xc_mem_event.c index fcca47c764..d43a0af33e 100644 --- a/tools/libxc/xc_mem_event.c +++ b/tools/libxc/xc_mem_event.c @@ -24,7 +24,7 @@ #include "xc_private.h" int xc_mem_event_control(xc_interface *xch, domid_t domain_id, unsigned int op, - unsigned int mode, uint32_t *port, void *ring_page) + unsigned int mode, uint32_t *port) { DECLARE_DOMCTL; int rc; @@ -33,7 +33,6 @@ int xc_mem_event_control(xc_interface *xch, domid_t domain_id, unsigned int op, domctl.domain = domain_id; domctl.u.mem_event_op.op = op; domctl.u.mem_event_op.mode = mode; - domctl.u.mem_event_op.ring_addr = (unsigned long) ring_page; rc = do_domctl(xch, &domctl); if ( !rc && port ) diff --git a/tools/libxc/xc_mem_paging.c b/tools/libxc/xc_mem_paging.c index f8eaa870b3..ab8c5ba5c6 100644 --- a/tools/libxc/xc_mem_paging.c +++ b/tools/libxc/xc_mem_paging.c @@ -25,7 +25,7 @@ int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id, - uint32_t *port, void *ring_page) + uint32_t *port) { if ( !port ) { @@ -36,7 +36,7 @@ int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id, return xc_mem_event_control(xch, domain_id, XEN_DOMCTL_MEM_EVENT_OP_PAGING_ENABLE, XEN_DOMCTL_MEM_EVENT_OP_PAGING, - port, ring_page); + port); } int xc_mem_paging_disable(xc_interface *xch, domid_t domain_id) @@ -44,7 +44,7 @@ int xc_mem_paging_disable(xc_interface *xch, domid_t domain_id) return xc_mem_event_control(xch, domain_id, XEN_DOMCTL_MEM_EVENT_OP_PAGING_DISABLE, XEN_DOMCTL_MEM_EVENT_OP_PAGING, - NULL, NULL); + NULL); } int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id, unsigned long gfn) diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 823d47a2ac..b4dd9e80e0 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -1892,13 +1892,12 @@ int xc_tmem_restore_extra(xc_interface *xch, int dom, int fd); * mem_event operations */ int xc_mem_event_control(xc_interface *xch, domid_t domain_id, unsigned int op, - unsigned int mode, uint32_t *port, void *ring_page); + unsigned int mode, uint32_t *port); int xc_mem_event_memop(xc_interface *xch, domid_t domain_id, unsigned int op, unsigned int mode, uint64_t gfn, void *buffer); -int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id, - uint32_t *port, void *ring_page); +int xc_mem_paging_enable(xc_interface *xch, domid_t domain_id, uint32_t *port); int xc_mem_paging_disable(xc_interface *xch, domid_t domain_id); int xc_mem_paging_nominate(xc_interface *xch, domid_t domain_id, unsigned long gfn); @@ -1907,8 +1906,7 @@ int xc_mem_paging_prep(xc_interface *xch, domid_t domain_id, unsigned long gfn); int xc_mem_paging_load(xc_interface *xch, domid_t domain_id, unsigned long gfn, void *buffer); -int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, - uint32_t *port, void *ring_page); +int xc_mem_access_enable(xc_interface *xch, domid_t domain_id, uint32_t *port); int xc_mem_access_disable(xc_interface *xch, domid_t domain_id); int xc_mem_access_resume(xc_interface *xch, domid_t domain_id, unsigned long gfn); diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h index 6286b6814a..89f3504911 100644 --- a/tools/libxc/xg_save_restore.h +++ b/tools/libxc/xg_save_restore.h @@ -254,6 +254,10 @@ #define XC_SAVE_ID_COMPRESSED_DATA -12 /* Marker to indicate arrival of compressed data */ #define XC_SAVE_ID_ENABLE_COMPRESSION -13 /* Marker to enable compression logic at receiver side */ #define XC_SAVE_ID_HVM_GENERATION_ID_ADDR -14 +/* Markers for the pfn's hosting these mem event rings */ +#define XC_SAVE_ID_HVM_PAGING_RING_PFN -15 +#define XC_SAVE_ID_HVM_ACCESS_RING_PFN -16 +#define XC_SAVE_ID_HVM_SHARING_RING_PFN -17 /* ** We process save/restore/migrate in batches of pages; the below |