From mboxrd@z Thu Jan 1 00:00:00 1970 From: Wen Congyang Subject: [RFC Patch v2 09/16] colo: implement restore_callbacks update_p2m() Date: Thu, 11 Jul 2013 16:35:41 +0800 Message-ID: <1373531748-12547-10-git-send-email-wency@cn.fujitsu.com> References: <1373531748-12547-1-git-send-email-wency@cn.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1373531748-12547-1-git-send-email-wency@cn.fujitsu.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Dong Eddie , Lai Jiangshan , xen-devl , Shriram Rajagopalan Cc: Jiang Yunhong , Wen Congyang , Ye Wei , Xu Yao , Hong Tao List-Id: xen-devel@lists.xenproject.org This patch implements restore callbacks for colo: 1. update_p2m(): Just update the dirty pages which store p2m. Signed-off-by: Ye Wei Signed-off-by: Jiang Yunhong Signed-off-by: Wen Congyang --- tools/libxc/xc_domain_restore_colo.c | 78 ++++++++++++++++++++++++++++++++++ tools/libxc/xc_save_restore_colo.h | 1 + 2 files changed, 79 insertions(+), 0 deletions(-) diff --git a/tools/libxc/xc_domain_restore_colo.c b/tools/libxc/xc_domain_restore_colo.c index 50009fa..70cdd16 100644 --- a/tools/libxc/xc_domain_restore_colo.c +++ b/tools/libxc/xc_domain_restore_colo.c @@ -524,3 +524,81 @@ int colo_flush_memory(struct restore_data *comm_data, void *data) return 0; } + +int colo_update_p2m_table(struct restore_data *comm_data, void *data) +{ + struct restore_colo_data *colo_data = data; + unsigned long i, j, n, pfn; + unsigned long *p2m_frame_list = comm_data->p2m_frame_list; + struct domain_info_context *dinfo = comm_data->dinfo; + unsigned long *pfn_type = comm_data->pfn_type; + xc_interface *xch = comm_data->xch; + uint32_t dom = comm_data->dom; + unsigned long *dirty_pages = colo_data->dirty_pages; + unsigned long *p2m_frame_list_temp = colo_data->p2m_frame_list_temp; + + /* A temporay mapping of the guest's p2m table(all dirty pages) */ + xen_pfn_t *live_p2m; + /* A temporay mapping of the guest's p2m table(1 page) */ + xen_pfn_t *live_p2m_one; + unsigned long *p2m; + + j = 0; + for (i = 0; i < P2M_FL_ENTRIES; i++) + { + pfn = p2m_frame_list[i]; + if ((pfn >= dinfo->p2m_size) || (pfn_type[pfn] != XEN_DOMCTL_PFINFO_NOTAB)) + { + ERROR("PFN-to-MFN frame number %li (%#lx) is bad", i, pfn); + return -1; + } + + if (!test_bit(pfn, dirty_pages)) + continue; + + p2m_frame_list_temp[j++] = comm_data->p2m[pfn]; + } + + if (j) + { + /* Copy the P2M we've constructed to the 'live' P2M */ + if (!(live_p2m = xc_map_foreign_pages(xch, dom, PROT_WRITE, + p2m_frame_list_temp, j))) + { + PERROR("Couldn't map p2m table"); + return -1; + } + + j = 0; + for (i = 0; i < P2M_FL_ENTRIES; i++) + { + pfn = p2m_frame_list[i]; + if (!test_bit(pfn, dirty_pages)) + continue; + + live_p2m_one = (xen_pfn_t *)((char *)live_p2m + PAGE_SIZE * j++); + /* If the domain we're restoring has a different word size to ours, + * we need to adjust the live_p2m assignment appropriately */ + if (dinfo->guest_width > sizeof (xen_pfn_t)) + { + n = (i + 1) * FPP - 1; + for (i = FPP - 1; i >= 0; i--) + ((uint64_t *)live_p2m_one)[i] = (long)comm_data->p2m[n--]; + } + else if (dinfo->guest_width < sizeof (xen_pfn_t)) + { + n = i * FPP; + for (i = 0; i < FPP; i++) + ((uint32_t *)live_p2m_one)[i] = comm_data->p2m[n++]; + } + else + { + p2m = (xen_pfn_t *)((char *)comm_data->p2m + PAGE_SIZE * i); + memcpy(live_p2m_one, p2m, PAGE_SIZE); + } + } + munmap(live_p2m, j * PAGE_SIZE); + } + + return 0; +} diff --git a/tools/libxc/xc_save_restore_colo.h b/tools/libxc/xc_save_restore_colo.h index 8af75b4..98e5128 100644 --- a/tools/libxc/xc_save_restore_colo.h +++ b/tools/libxc/xc_save_restore_colo.h @@ -8,5 +8,6 @@ extern int colo_init(struct restore_data *, void **); extern void colo_free(struct restore_data *, void *); extern char *colo_get_page(struct restore_data *, void *, unsigned long); extern int colo_flush_memory(struct restore_data *, void *); +extern int colo_update_p2m_table(struct restore_data *, void *); #endif -- 1.7.4