debuggers.hg

view tools/libxc/xg_save_restore.h @ 21067:b4a1832a916f

Update Xen version to 4.0.0-rc6
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 09 18:18:05 2010 +0000 (2010-03-09)
parents 3e4a70d6c50a
children 3ffdb094c2c0
line source
1 /*
2 ** xg_save_restore.h
3 **
4 ** Defintions and utilities for save / restore.
5 */
7 #include "xc_private.h"
9 #include <xen/foreign/x86_32.h>
10 #include <xen/foreign/x86_64.h>
12 /*
13 ** We process save/restore/migrate in batches of pages; the below
14 ** determines how many pages we (at maximum) deal with in each batch.
15 */
16 #define MAX_BATCH_SIZE 1024 /* up to 1024 pages (4MB) at a time */
18 /* When pinning page tables at the end of restore, we also use batching. */
19 #define MAX_PIN_BATCH 1024
23 /*
24 ** Determine various platform information required for save/restore, in
25 ** particular:
26 **
27 ** - the maximum MFN on this machine, used to compute the size of
28 ** the M2P table;
29 **
30 ** - the starting virtual address of the the hypervisor; we use this
31 ** to determine which parts of guest address space(s) do and don't
32 ** require canonicalization during save/restore; and
33 **
34 ** - the number of page-table levels for save/ restore. This should
35 ** be a property of the domain, but for the moment we just read it
36 ** from the hypervisor.
37 **
38 ** - The width of a guest word (unsigned long), in bytes.
39 **
40 ** Returns 1 on success, 0 on failure.
41 */
42 static inline int get_platform_info(int xc_handle, uint32_t dom,
43 /* OUT */ unsigned long *max_mfn,
44 /* OUT */ unsigned long *hvirt_start,
45 /* OUT */ unsigned int *pt_levels,
46 /* OUT */ unsigned int *guest_width)
47 {
48 xen_capabilities_info_t xen_caps = "";
49 xen_platform_parameters_t xen_params;
50 DECLARE_DOMCTL;
52 if (xc_version(xc_handle, XENVER_platform_parameters, &xen_params) != 0)
53 return 0;
55 if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0)
56 return 0;
58 *max_mfn = xc_memory_op(xc_handle, XENMEM_maximum_ram_page, NULL);
60 *hvirt_start = xen_params.virt_start;
62 memset(&domctl, 0, sizeof(domctl));
63 domctl.domain = dom;
64 domctl.cmd = XEN_DOMCTL_get_address_size;
66 if ( do_domctl(xc_handle, &domctl) != 0 )
67 return 0;
69 *guest_width = domctl.u.address_size.size / 8;
71 /* 64-bit tools will see the 64-bit hvirt_start, but 32-bit guests
72 * will be using the compat one. */
73 if ( *guest_width < sizeof (unsigned long) )
74 /* XXX need to fix up a way of extracting this value from Xen if
75 * XXX it becomes variable for domU */
76 *hvirt_start = 0xf5800000;
78 if (strstr(xen_caps, "xen-3.0-x86_64"))
79 /* Depends on whether it's a compat 32-on-64 guest */
80 *pt_levels = ( (*guest_width == 8) ? 4 : 3 );
81 else if (strstr(xen_caps, "xen-3.0-x86_32p"))
82 *pt_levels = 3;
83 else if (strstr(xen_caps, "xen-3.0-x86_32"))
84 *pt_levels = 2;
85 else
86 return 0;
88 return 1;
89 }
92 /*
93 ** Save/restore deal with the mfn_to_pfn (M2P) and pfn_to_mfn (P2M) tables.
94 ** The M2P simply holds the corresponding PFN, while the top bit of a P2M
95 ** entry tell us whether or not the the PFN is currently mapped.
96 */
98 #define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10))
101 /*
102 ** The M2P is made up of some number of 'chunks' of at least 2MB in size.
103 ** The below definitions and utility function(s) deal with mapping the M2P
104 ** regarldess of the underlying machine memory size or architecture.
105 */
106 #define M2P_SHIFT L2_PAGETABLE_SHIFT_PAE
107 #define M2P_CHUNK_SIZE (1 << M2P_SHIFT)
108 #define M2P_SIZE(_m) ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT)
109 #define M2P_CHUNKS(_m) (M2P_SIZE((_m)) >> M2P_SHIFT)
111 /* Returns TRUE if the PFN is currently mapped */
112 #define is_mapped(pfn_type) (!((pfn_type) & 0x80000000UL))
115 #define GET_FIELD(_p, _f) ((dinfo->guest_width==8) ? ((_p)->x64._f) : ((_p)->x32._f))
117 #define SET_FIELD(_p, _f, _v) do { \
118 if (dinfo->guest_width == 8) \
119 (_p)->x64._f = (_v); \
120 else \
121 (_p)->x32._f = (_v); \
122 } while (0)
124 #define UNFOLD_CR3(_c) \
125 ((uint64_t)((dinfo->guest_width == 8) \
126 ? ((_c) >> 12) \
127 : (((uint32_t)(_c) >> 12) | ((uint32_t)(_c) << 20))))
129 #define FOLD_CR3(_c) \
130 ((uint64_t)((dinfo->guest_width == 8) \
131 ? ((uint64_t)(_c)) << 12 \
132 : (((uint32_t)(_c) << 12) | ((uint32_t)(_c) >> 20))))
134 #define MEMCPY_FIELD(_d, _s, _f) do { \
135 if (dinfo->guest_width == 8) \
136 memcpy(&(_d)->x64._f, &(_s)->x64._f,sizeof((_d)->x64._f)); \
137 else \
138 memcpy(&(_d)->x32._f, &(_s)->x32._f,sizeof((_d)->x32._f)); \
139 } while (0)
141 #define MEMSET_ARRAY_FIELD(_p, _f, _v) do { \
142 if (dinfo->guest_width == 8) \
143 memset(&(_p)->x64._f[0], (_v), sizeof((_p)->x64._f)); \
144 else \
145 memset(&(_p)->x32._f[0], (_v), sizeof((_p)->x32._f)); \
146 } while (0)
148 #ifndef MAX
149 #define MAX(_a, _b) ((_a) >= (_b) ? (_a) : (_b))
150 #endif
151 #ifndef MIN
152 #define MIN(_a, _b) ((_a) <= (_b) ? (_a) : (_b))
153 #endif