debuggers.hg
changeset 17968:fc89fb719214
[IA64] ia64 save/restore new formart. restore part.
Introduce ia64 save/restore new formart. restore part.
The formart twist is necessary for pv_ops linux support saving/restoring
all of the online vcpu context.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Introduce ia64 save/restore new formart. restore part.
The formart twist is necessary for pv_ops linux support saving/restoring
all of the online vcpu context.
Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author | Isaku Yamahata <yamahata@valinux.co.jp> |
---|---|
date | Tue Jun 10 15:58:09 2008 +0900 (2008-06-10) |
parents | 4af5059f4e0d |
children | 1201c7657832 |
files | tools/libxc/ia64/xc_ia64_linux_restore.c tools/libxc/ia64/xc_ia64_save_restore.h |
line diff
1.1 --- a/tools/libxc/ia64/xc_ia64_linux_restore.c Tue Jun 10 15:54:47 2008 +0900 1.2 +++ b/tools/libxc/ia64/xc_ia64_linux_restore.c Tue Jun 10 15:58:09 2008 +0900 1.3 @@ -127,7 +127,7 @@ xc_ia64_recv_vcpu_context(int xc_handle, 1.4 fprintf(stderr, "ip=%016lx, b0=%016lx\n", ctxt->regs.ip, ctxt->regs.b[0]); 1.5 1.6 /* Initialize and set registers. */ 1.7 - ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR; 1.8 + ctxt->flags = VGCF_EXTRA_REGS | VGCF_SET_CR_IRR | VGCF_online; 1.9 if (xc_vcpu_setcontext(xc_handle, dom, vcpu, ctxt) != 0) { 1.10 ERROR("Couldn't set vcpu context"); 1.11 return -1; 1.12 @@ -184,29 +184,57 @@ xc_ia64_recv_shared_info(int xc_handle, 1.13 } 1.14 1.15 static int 1.16 -xc_ia64_pv_recv_context(int xc_handle, int io_fd, uint32_t dom, 1.17 - unsigned long shared_info_frame, 1.18 - struct xen_ia64_p2m_table *p2m_table, 1.19 - unsigned int store_evtchn, unsigned long *store_mfn, 1.20 - unsigned int console_evtchn, 1.21 - unsigned long *console_mfn) 1.22 +xc_ia64_recv_vcpumap(const xc_dominfo_t *info, int io_fd, uint64_t **vcpumapp) 1.23 +{ 1.24 + uint64_t max_virt_cpus; 1.25 + unsigned long vcpumap_size; 1.26 + uint64_t *vcpumap = NULL; 1.27 + 1.28 + *vcpumapp = NULL; 1.29 + 1.30 + if (read_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) { 1.31 + ERROR("error reading max_virt_cpus"); 1.32 + return -1; 1.33 + } 1.34 + if (max_virt_cpus < info->max_vcpu_id) { 1.35 + ERROR("too large max_virt_cpus %i < %i\n", 1.36 + max_virt_cpus, info->max_vcpu_id); 1.37 + return -1; 1.38 + } 1.39 + vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) / 1.40 + sizeof(vcpumap[0]); 1.41 + vcpumap = malloc(vcpumap_size); 1.42 + if (vcpumap == NULL) { 1.43 + ERROR("memory alloc for vcpumap"); 1.44 + return -1; 1.45 + } 1.46 + memset(vcpumap, 0, vcpumap_size); 1.47 + if (read_exact(io_fd, vcpumap, vcpumap_size)) { 1.48 + ERROR("read vcpumap"); 1.49 + free(vcpumap); 1.50 + return -1; 1.51 + } 1.52 + 1.53 + *vcpumapp = vcpumap; 1.54 + return 0; 1.55 +} 1.56 + 1.57 +static int 1.58 +xc_ia64_pv_recv_vcpu_context(int xc_handle, int io_fd, int32_t dom, 1.59 + uint32_t vcpu) 1.60 { 1.61 int rc = -1; 1.62 - unsigned long gmfn; 1.63 1.64 /* A copy of the CPU context of the guest. */ 1.65 vcpu_guest_context_t ctxt; 1.66 - 1.67 - /* A temporary mapping of the guest's start_info page. */ 1.68 - start_info_t *start_info; 1.69 - 1.70 + 1.71 if (lock_pages(&ctxt, sizeof(ctxt))) { 1.72 /* needed for build domctl, but might as well do early */ 1.73 ERROR("Unable to lock_pages ctxt"); 1.74 return -1; 1.75 } 1.76 1.77 - if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, 0, &ctxt)) 1.78 + if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, vcpu, &ctxt)) 1.79 goto out; 1.80 1.81 /* Then get privreg page. */ 1.82 @@ -215,21 +243,42 @@ xc_ia64_pv_recv_context(int xc_handle, i 1.83 goto out; 1.84 } 1.85 1.86 + rc = 0; 1.87 + 1.88 + out: 1.89 + unlock_pages(&ctxt, sizeof(ctxt)); 1.90 + return rc; 1.91 +} 1.92 + 1.93 +static int 1.94 +xc_ia64_pv_recv_shared_info(int xc_handle, int io_fd, int32_t dom, 1.95 + unsigned long shared_info_frame, 1.96 + struct xen_ia64_p2m_table *p2m_table, 1.97 + unsigned int store_evtchn, 1.98 + unsigned long *store_mfn, 1.99 + unsigned int console_evtchn, 1.100 + unsigned long *console_mfn) 1.101 +{ 1.102 + unsigned long gmfn; 1.103 + 1.104 + /* A temporary mapping of the guest's start_info page. */ 1.105 + start_info_t *start_info; 1.106 + 1.107 /* Read shared info. */ 1.108 if (xc_ia64_recv_shared_info(xc_handle, io_fd, dom, 1.109 shared_info_frame, &gmfn)) 1.110 - goto out; 1.111 + return -1; 1.112 1.113 /* Uncanonicalise the suspend-record frame number and poke resume rec. */ 1.114 if (populate_page_if_necessary(xc_handle, dom, gmfn, p2m_table)) { 1.115 ERROR("cannot populate page 0x%lx", gmfn); 1.116 - goto out; 1.117 + return -1; 1.118 } 1.119 start_info = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, 1.120 PROT_READ | PROT_WRITE, gmfn); 1.121 if (start_info == NULL) { 1.122 ERROR("cannot map start_info page"); 1.123 - goto out; 1.124 + return -1; 1.125 } 1.126 start_info->nr_pages = p2m_size; 1.127 start_info->shared_info = shared_info_frame << PAGE_SHIFT; 1.128 @@ -240,10 +289,109 @@ xc_ia64_pv_recv_context(int xc_handle, i 1.129 start_info->console.domU.evtchn = console_evtchn; 1.130 munmap(start_info, PAGE_SIZE); 1.131 1.132 - rc = 0; 1.133 + return 0; 1.134 +} 1.135 + 1.136 +static int 1.137 +xc_ia64_pv_recv_context_ver_one_or_two(int xc_handle, int io_fd, uint32_t dom, 1.138 + unsigned long shared_info_frame, 1.139 + struct xen_ia64_p2m_table *p2m_table, 1.140 + unsigned int store_evtchn, 1.141 + unsigned long *store_mfn, 1.142 + unsigned int console_evtchn, 1.143 + unsigned long *console_mfn) 1.144 +{ 1.145 + int rc; 1.146 + 1.147 + /* vcpu 0 context */ 1.148 + rc = xc_ia64_pv_recv_vcpu_context(xc_handle, io_fd, dom, 0); 1.149 + if (rc) 1.150 + return rc; 1.151 + 1.152 + 1.153 + /* shared_info */ 1.154 + rc = xc_ia64_pv_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame, 1.155 + p2m_table, store_evtchn, store_mfn, 1.156 + console_evtchn, console_mfn); 1.157 + return rc; 1.158 +} 1.159 + 1.160 +static int 1.161 +xc_ia64_pv_recv_context_ver_three(int xc_handle, int io_fd, uint32_t dom, 1.162 + unsigned long shared_info_frame, 1.163 + struct xen_ia64_p2m_table *p2m_table, 1.164 + unsigned int store_evtchn, 1.165 + unsigned long *store_mfn, 1.166 + unsigned int console_evtchn, 1.167 + unsigned long *console_mfn) 1.168 +{ 1.169 + int rc = -1; 1.170 + xc_dominfo_t info; 1.171 + unsigned int i; 1.172 + 1.173 + /* vcpu map */ 1.174 + uint64_t *vcpumap = NULL; 1.175 + 1.176 + if (xc_domain_getinfo(xc_handle, dom, 1, &info) != 1) { 1.177 + ERROR("Could not get domain info"); 1.178 + return -1; 1.179 + } 1.180 + rc = xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap); 1.181 + if (rc != 0) 1.182 + goto out; 1.183 1.184 + /* vcpu context */ 1.185 + for (i = 0; i <= info.max_vcpu_id; i++) { 1.186 + if (!__test_bit(i, vcpumap)) 1.187 + continue; 1.188 + 1.189 + rc = xc_ia64_pv_recv_vcpu_context(xc_handle, io_fd, dom, i); 1.190 + if (rc != 0) 1.191 + goto out; 1.192 + } 1.193 + 1.194 + /* shared_info */ 1.195 + rc = xc_ia64_pv_recv_shared_info(xc_handle, io_fd, dom, shared_info_frame, 1.196 + p2m_table, store_evtchn, store_mfn, 1.197 + console_evtchn, console_mfn); 1.198 out: 1.199 - unlock_pages(&ctxt, sizeof(ctxt)); 1.200 + if (vcpumap != NULL) 1.201 + free(vcpumap); 1.202 + return rc; 1.203 +} 1.204 + 1.205 +static int 1.206 +xc_ia64_pv_recv_context(unsigned long format_version, 1.207 + int xc_handle, int io_fd, uint32_t dom, 1.208 + unsigned long shared_info_frame, 1.209 + struct xen_ia64_p2m_table *p2m_table, 1.210 + unsigned int store_evtchn, 1.211 + unsigned long *store_mfn, 1.212 + unsigned int console_evtchn, 1.213 + unsigned long *console_mfn) 1.214 +{ 1.215 + int rc; 1.216 + switch (format_version) { 1.217 + case XC_IA64_SR_FORMAT_VER_ONE: 1.218 + case XC_IA64_SR_FORMAT_VER_TWO: 1.219 + rc = xc_ia64_pv_recv_context_ver_one_or_two(xc_handle, io_fd, dom, 1.220 + shared_info_frame, 1.221 + p2m_table, store_evtchn, 1.222 + store_mfn, console_evtchn, 1.223 + console_mfn); 1.224 + break; 1.225 + case XC_IA64_SR_FORMAT_VER_THREE: 1.226 + rc = xc_ia64_pv_recv_context_ver_three(xc_handle, io_fd, dom, 1.227 + shared_info_frame, 1.228 + p2m_table, store_evtchn, 1.229 + store_mfn, console_evtchn, 1.230 + console_mfn); 1.231 + break; 1.232 + default: 1.233 + ERROR("Unsupported format version"); 1.234 + rc = -1; 1.235 + break; 1.236 + } 1.237 return rc; 1.238 } 1.239 1.240 @@ -259,9 +407,7 @@ xc_ia64_hvm_recv_context(int xc_handle, 1.241 xc_dominfo_t info; 1.242 unsigned int i; 1.243 1.244 - /* cpu */ 1.245 - uint64_t max_virt_cpus; 1.246 - unsigned long vcpumap_size; 1.247 + /* cpumap */ 1.248 uint64_t *vcpumap = NULL; 1.249 1.250 /* HVM: magic frames for ioreqs and xenstore comms */ 1.251 @@ -289,27 +435,8 @@ xc_ia64_hvm_recv_context(int xc_handle, 1.252 ERROR("Could not get domain info"); 1.253 goto out; 1.254 } 1.255 - if (read_exact(io_fd, &max_virt_cpus, sizeof(max_virt_cpus))) { 1.256 - ERROR("error reading max_virt_cpus"); 1.257 - goto out; 1.258 - } 1.259 - if (max_virt_cpus < info.max_vcpu_id) { 1.260 - ERROR("too large max_virt_cpus %i < %i\n", 1.261 - max_virt_cpus, info.max_vcpu_id); 1.262 + if (xc_ia64_recv_vcpumap(&info, io_fd, &vcpumap)) 1.263 goto out; 1.264 - } 1.265 - vcpumap_size = (max_virt_cpus + 1 + sizeof(vcpumap[0]) - 1) / 1.266 - sizeof(vcpumap[0]); 1.267 - vcpumap = malloc(vcpumap_size); 1.268 - if (vcpumap == NULL) { 1.269 - ERROR("memory alloc for vcpumap"); 1.270 - goto out; 1.271 - } 1.272 - memset(vcpumap, 0, vcpumap_size); 1.273 - if (read_exact(io_fd, vcpumap, vcpumap_size)) { 1.274 - ERROR("read vcpumap"); 1.275 - goto out; 1.276 - } 1.277 1.278 /* vcpu context */ 1.279 for (i = 0; i <= info.max_vcpu_id; i++) { 1.280 @@ -322,7 +449,7 @@ xc_ia64_hvm_recv_context(int xc_handle, 1.281 if (xc_ia64_recv_vcpu_context(xc_handle, io_fd, dom, i, &ctxt)) 1.282 goto out; 1.283 1.284 - // system context of vcpu is recieved as hvm context. 1.285 + /* system context of vcpu is recieved as hvm context. */ 1.286 } 1.287 1.288 /* Set HVM-specific parameters */ 1.289 @@ -350,6 +477,7 @@ xc_ia64_hvm_recv_context(int xc_handle, 1.290 ERROR("error setting HVM params: %i", rc); 1.291 goto out; 1.292 } 1.293 + rc = -1; 1.294 *store_mfn = magic_pfns[0]; 1.295 1.296 /* Read HVM context */ 1.297 @@ -437,7 +565,9 @@ xc_domain_restore(int xc_handle, int io_ 1.298 ERROR("Error when reading version"); 1.299 goto out; 1.300 } 1.301 - if (ver != XC_IA64_SR_FORMAT_VER_ONE && ver != XC_IA64_SR_FORMAT_VER_TWO) { 1.302 + if (ver != XC_IA64_SR_FORMAT_VER_ONE && 1.303 + ver != XC_IA64_SR_FORMAT_VER_TWO && 1.304 + ver != XC_IA64_SR_FORMAT_VER_THREE) { 1.305 ERROR("version of save doesn't match"); 1.306 goto out; 1.307 } 1.308 @@ -468,7 +598,8 @@ xc_domain_restore(int xc_handle, int io_ 1.309 } 1.310 shared_info_frame = domctl.u.getdomaininfo.shared_info_frame; 1.311 1.312 - if (ver == XC_IA64_SR_FORMAT_VER_TWO) { 1.313 + if (ver == XC_IA64_SR_FORMAT_VER_THREE || 1.314 + ver == XC_IA64_SR_FORMAT_VER_TWO) { 1.315 unsigned int memmap_info_num_pages; 1.316 unsigned long memmap_size; 1.317 xen_ia64_memmap_info_t *memmap_info; 1.318 @@ -548,7 +679,8 @@ xc_domain_restore(int xc_handle, int io_ 1.319 goto out; 1.320 1.321 if (!hvm) 1.322 - rc = xc_ia64_pv_recv_context(xc_handle, io_fd, dom, shared_info_frame, 1.323 + rc = xc_ia64_pv_recv_context(ver, 1.324 + xc_handle, io_fd, dom, shared_info_frame, 1.325 &p2m_table, store_evtchn, store_mfn, 1.326 console_evtchn, console_mfn); 1.327 else
2.1 --- a/tools/libxc/ia64/xc_ia64_save_restore.h Tue Jun 10 15:54:47 2008 +0900 2.2 +++ b/tools/libxc/ia64/xc_ia64_save_restore.h Tue Jun 10 15:58:09 2008 +0900 2.3 @@ -27,7 +27,9 @@ 2.4 #define XC_IA64_SR_FORMAT_VER_ONE 1UL 2.5 /* using foreign p2m exposure version */ 2.6 #define XC_IA64_SR_FORMAT_VER_TWO 2UL 2.7 -#define XC_IA64_SR_FORMAT_VER_MAX 2UL 2.8 + /* only pv change: send vcpumap and all vcpu context */ 2.9 +#define XC_IA64_SR_FORMAT_VER_THREE 3UL 2.10 +#define XC_IA64_SR_FORMAT_VER_MAX 3UL 2.11 2.12 #define XC_IA64_SR_FORMAT_VER_CURRENT XC_IA64_SR_FORMAT_VER_TWO 2.13