aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_offline_page.c
diff options
context:
space:
mode:
authorDario Faggioli <dario.faggioli@citrix.com>2013-09-10 19:54:12 +0200
committerIan Campbell <ian.campbell@citrix.com>2013-09-13 13:10:07 +0100
commit266abb240738bb37ccb28623806273c58523f422 (patch)
treee76529b1acdc3a21ebd82fb5d776a45d8c2ba0bc /tools/libxc/xc_offline_page.c
parentdfdfcdc6f7c51ef7e5d0547120d0ac943ef43c67 (diff)
downloadxen-266abb240738bb37ccb28623806273c58523f422.tar.gz
xen-266abb240738bb37ccb28623806273c58523f422.tar.bz2
xen-266abb240738bb37ccb28623806273c58523f422.zip
libxc: introduce xc_map_domain_meminfo (and xc_unmap_domain_meminfo)
And use it in xc_exchange_page(). This is basically because the following change need something really similar to the set of steps that are here abstracted in these two functions. Despite of the change in the interface and in the signature of some functions, this is pure code motion. No functional changes involved. Signed-off-by: Dario Faggioli <dario.faggioli@citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/libxc/xc_offline_page.c')
-rw-r--r--tools/libxc/xc_offline_page.c185
1 files changed, 30 insertions, 155 deletions
diff --git a/tools/libxc/xc_offline_page.c b/tools/libxc/xc_offline_page.c
index 1f6dbc6d5e..fbb53f5f0f 100644
--- a/tools/libxc/xc_offline_page.c
+++ b/tools/libxc/xc_offline_page.c
@@ -33,17 +33,6 @@
#include "xg_private.h"
#include "xg_save_restore.h"
-struct domain_mem_info{
- int domid;
- unsigned int pt_level;
- unsigned int guest_width;
- xen_pfn_t *pfn_type;
- xen_pfn_t *p2m_table;
- unsigned long p2m_size;
- xen_pfn_t *m2p_table;
- int max_mfn;
-};
-
struct pte_backup_entry
{
xen_pfn_t table_mfn;
@@ -180,139 +169,6 @@ static int xc_is_page_granted_v2(xc_interface *xch, xen_pfn_t gpfn,
return (i != gnt_num);
}
-static xen_pfn_t pfn_to_mfn(xen_pfn_t pfn, xen_pfn_t *p2m, int gwidth)
-{
- return ((xen_pfn_t) ((gwidth==8)?
- (((uint64_t *)p2m)[(pfn)]):
- ((((uint32_t *)p2m)[(pfn)]) == 0xffffffffU ?
- (-1UL) :
- (((uint32_t *)p2m)[(pfn)]))));
-}
-
-static int get_pt_level(xc_interface *xch, uint32_t domid,
- unsigned int *pt_level,
- unsigned int *gwidth)
-{
- xen_capabilities_info_t xen_caps = "";
-
- if (xc_version(xch, XENVER_capabilities, &xen_caps) != 0)
- return -1;
-
- if (xc_domain_get_guest_width(xch, domid, gwidth) != 0)
- return -1;
-
- if (strstr(xen_caps, "xen-3.0-x86_64"))
- /* Depends on whether it's a compat 32-on-64 guest */
- *pt_level = ( (*gwidth == 8) ? 4 : 3 );
- else if (strstr(xen_caps, "xen-3.0-x86_32p"))
- *pt_level = 3;
- else if (strstr(xen_caps, "xen-3.0-x86_32"))
- *pt_level = 2;
- else
- return -1;
-
- return 0;
-}
-
-static int close_mem_info(xc_interface *xch, struct domain_mem_info *minfo)
-{
- if (minfo->pfn_type)
- free(minfo->pfn_type);
- munmap(minfo->m2p_table, M2P_SIZE(minfo->max_mfn));
- munmap(minfo->p2m_table, P2M_FLL_ENTRIES * PAGE_SIZE);
- minfo->p2m_table = minfo->m2p_table = NULL;
-
- return 0;
-}
-
-static int init_mem_info(xc_interface *xch, int domid,
- struct domain_mem_info *minfo,
- xc_dominfo_t *info)
-{
- uint64_aligned_t shared_info_frame;
- shared_info_any_t *live_shinfo = NULL;
- int i, rc;
-
- /* Only be initialized once */
- if (minfo->pfn_type || minfo->m2p_table || minfo->p2m_table)
- return -EINVAL;
-
- if ( get_pt_level(xch, domid, &minfo->pt_level,
- &minfo->guest_width) )
- {
- ERROR("Unable to get PT level info.");
- return -EFAULT;
- }
- dinfo->guest_width = minfo->guest_width;
-
- shared_info_frame = info->shared_info_frame;
-
- live_shinfo = xc_map_foreign_range(xch, domid,
- PAGE_SIZE, PROT_READ, shared_info_frame);
- if ( !live_shinfo )
- {
- ERROR("Couldn't map live_shinfo");
- return -EFAULT;
- }
-
- if ( (rc = xc_core_arch_map_p2m_writable(xch, minfo->guest_width,
- info, live_shinfo, &minfo->p2m_table, &minfo->p2m_size)) )
- {
- ERROR("Couldn't map p2m table %x\n", rc);
- goto failed;
- }
- munmap(live_shinfo, PAGE_SIZE);
- live_shinfo = NULL;
-
- dinfo->p2m_size = minfo->p2m_size;
-
- minfo->max_mfn = xc_maximum_ram_page(xch);
- if ( !(minfo->m2p_table =
- xc_map_m2p(xch, minfo->max_mfn, PROT_READ, NULL)) )
- {
- ERROR("Failed to map live M2P table");
- goto failed;
- }
-
- /* Get pfn type */
- minfo->pfn_type = calloc(sizeof(*minfo->pfn_type), minfo->p2m_size);
- if (!minfo->pfn_type)
- {
- ERROR("Failed to malloc pfn_type\n");
- goto failed;
- }
-
- for (i = 0; i < minfo->p2m_size; i++)
- minfo->pfn_type[i] = pfn_to_mfn(i, minfo->p2m_table,
- minfo->guest_width);
-
- for (i = 0; i < minfo->p2m_size ; i+=1024)
- {
- int count = ((dinfo->p2m_size - i ) > 1024 ) ? 1024: (dinfo->p2m_size - i);
- if ( ( rc = xc_get_pfn_type_batch(xch, domid, count,
- minfo->pfn_type + i)) )
- {
- ERROR("Failed to get pfn_type %x\n", rc);
- goto failed;
- }
- }
- return 0;
-
-failed:
- if (minfo->pfn_type)
- {
- free(minfo->pfn_type);
- minfo->pfn_type = NULL;
- }
- if (live_shinfo)
- munmap(live_shinfo, PAGE_SIZE);
- munmap(minfo->m2p_table, M2P_SIZE(minfo->max_mfn));
- munmap(minfo->p2m_table, P2M_FLL_ENTRIES * PAGE_SIZE);
- minfo->p2m_table = minfo->m2p_table = NULL;
-
- return -1;
-}
-
static int backup_ptes(xen_pfn_t table_mfn, int offset,
struct pte_backup *backup)
{
@@ -402,7 +258,7 @@ static int __update_pte(xc_interface *xch,
}
static int change_pte(xc_interface *xch, int domid,
- struct domain_mem_info *minfo,
+ struct xc_domain_meminfo *minfo,
struct pte_backup *backup,
struct xc_mmu *mmu,
pte_func func,
@@ -412,7 +268,7 @@ static int change_pte(xc_interface *xch, int domid,
uint64_t i;
void *content = NULL;
- pte_num = PAGE_SIZE / ((minfo->pt_level == 2) ? 4 : 8);
+ pte_num = PAGE_SIZE / ((minfo->pt_levels == 2) ? 4 : 8);
for (i = 0; i < minfo->p2m_size; i++)
{
@@ -435,7 +291,7 @@ static int change_pte(xc_interface *xch, int domid,
for (j = 0; j < pte_num; j++)
{
- if ( minfo->pt_level == 2 )
+ if ( minfo->pt_levels == 2 )
pte = ((const uint32_t*)content)[j];
else
pte = ((const uint64_t*)content)[j];
@@ -447,7 +303,7 @@ static int change_pte(xc_interface *xch, int domid,
case 1:
if ( xc_add_mmu_update(xch, mmu,
table_mfn << PAGE_SHIFT |
- j * ( (minfo->pt_level == 2) ?
+ j * ( (minfo->pt_levels == 2) ?
sizeof(uint32_t): sizeof(uint64_t)) |
MMU_PT_UPDATE_PRESERVE_AD,
new_pte) )
@@ -480,7 +336,7 @@ failed:
}
static int update_pte(xc_interface *xch, int domid,
- struct domain_mem_info *minfo,
+ struct xc_domain_meminfo *minfo,
struct pte_backup *backup,
struct xc_mmu *mmu,
unsigned long new_mfn)
@@ -490,7 +346,7 @@ static int update_pte(xc_interface *xch, int domid,
}
static int clear_pte(xc_interface *xch, int domid,
- struct domain_mem_info *minfo,
+ struct xc_domain_meminfo *minfo,
struct pte_backup *backup,
struct xc_mmu *mmu,
xen_pfn_t mfn)
@@ -538,7 +394,7 @@ static int is_page_exchangable(xc_interface *xch, int domid, xen_pfn_t mfn,
int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
{
xc_dominfo_t info;
- struct domain_mem_info minfo;
+ struct xc_domain_meminfo minfo;
struct xc_mmu *mmu = NULL;
struct pte_backup old_ptes = {NULL, 0, 0};
grant_entry_v1_t *gnttab_v1 = NULL;
@@ -549,6 +405,8 @@ int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
int rc, result = -1;
uint32_t status;
xen_pfn_t new_mfn, gpfn;
+ xen_pfn_t *m2p_table;
+ int max_mfn;
if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 )
{
@@ -568,10 +426,26 @@ int xc_exchange_page(xc_interface *xch, int domid, xen_pfn_t mfn)
return -EINVAL;
}
- /* Get domain's memory information */
+ /* Map M2P and obtain gpfn */
+ max_mfn = xc_maximum_ram_page(xch);
+ if ( !(m2p_table = xc_map_m2p(xch, max_mfn, PROT_READ, NULL)) )
+ {
+ PERROR("Failed to map live M2P table");
+ return -EFAULT;
+ }
+ gpfn = m2p_table[mfn];
+
+ /* Map domain's memory information */
memset(&minfo, 0, sizeof(minfo));
- init_mem_info(xch, domid, &minfo, &info);
- gpfn = minfo.m2p_table[mfn];
+ if ( xc_map_domain_meminfo(xch, domid, &minfo) )
+ {
+ PERROR("Could not map domain's memory information\n");
+ return -EFAULT;
+ }
+
+ /* For translation macros */
+ dinfo->guest_width = minfo.guest_width;
+ dinfo->p2m_size = minfo.p2m_size;
/* Don't exchange CR3 for PAE guest in PAE host environment */
if (minfo.guest_width > sizeof(long))
@@ -766,7 +640,8 @@ failed:
if (gnttab_v2)
munmap(gnttab_v2, gnt_num / (PAGE_SIZE/sizeof(grant_entry_v2_t)));
- close_mem_info(xch, &minfo);
+ xc_unmap_domain_meminfo(xch, &minfo);
+ munmap(m2p_table, M2P_SIZE(max_mfn));
return result;
}