1 | /* |
---|
2 | ** xg_save_restore.h |
---|
3 | ** |
---|
4 | ** Defintions and utilities for save / restore. |
---|
5 | */ |
---|
6 | |
---|
7 | #include "xc_private.h" |
---|
8 | |
---|
9 | /* |
---|
10 | ** We process save/restore/migrate in batches of pages; the below |
---|
11 | ** determines how many pages we (at maximum) deal with in each batch. |
---|
12 | */ |
---|
13 | #define MAX_BATCH_SIZE 1024 /* up to 1024 pages (4MB) at a time */ |
---|
14 | |
---|
15 | /* When pinning page tables at the end of restore, we also use batching. */ |
---|
16 | #define MAX_PIN_BATCH 1024 |
---|
17 | |
---|
18 | |
---|
19 | |
---|
20 | /* |
---|
21 | ** Determine various platform information required for save/restore, in |
---|
22 | ** particular: |
---|
23 | ** |
---|
24 | ** - the maximum MFN on this machine, used to compute the size of |
---|
25 | ** the M2P table; |
---|
26 | ** |
---|
27 | ** - the starting virtual address of the the hypervisor; we use this |
---|
28 | ** to determine which parts of guest address space(s) do and don't |
---|
29 | ** require canonicalization during save/restore; and |
---|
30 | ** |
---|
31 | ** - the number of page-table levels for save/ restore. This should |
---|
32 | ** be a property of the domain, but for the moment we just read it |
---|
33 | ** from the hypervisor. |
---|
34 | ** |
---|
35 | ** Returns 1 on success, 0 on failure. |
---|
36 | */ |
---|
37 | static inline int get_platform_info(int xc_handle, uint32_t dom, |
---|
38 | /* OUT */ unsigned long *max_mfn, |
---|
39 | /* OUT */ unsigned long *hvirt_start, |
---|
40 | /* OUT */ unsigned int *pt_levels) |
---|
41 | { |
---|
42 | xen_capabilities_info_t xen_caps = ""; |
---|
43 | xen_platform_parameters_t xen_params; |
---|
44 | |
---|
45 | if (xc_version(xc_handle, XENVER_platform_parameters, &xen_params) != 0) |
---|
46 | return 0; |
---|
47 | |
---|
48 | if (xc_version(xc_handle, XENVER_capabilities, &xen_caps) != 0) |
---|
49 | return 0; |
---|
50 | |
---|
51 | *max_mfn = xc_memory_op(xc_handle, XENMEM_maximum_ram_page, NULL); |
---|
52 | |
---|
53 | *hvirt_start = xen_params.virt_start; |
---|
54 | |
---|
55 | /* |
---|
56 | * XXX For now, 32bit dom0's can only save/restore 32bit domUs |
---|
57 | * on 64bit hypervisors, so no need to check which type of domain |
---|
58 | * we're dealing with. |
---|
59 | */ |
---|
60 | if (strstr(xen_caps, "xen-3.0-x86_64")) |
---|
61 | #if defined(__i386__) |
---|
62 | *pt_levels = 3; |
---|
63 | #else |
---|
64 | *pt_levels = 4; |
---|
65 | #endif |
---|
66 | else if (strstr(xen_caps, "xen-3.0-x86_32p")) |
---|
67 | *pt_levels = 3; |
---|
68 | else if (strstr(xen_caps, "xen-3.0-x86_32")) |
---|
69 | *pt_levels = 2; |
---|
70 | else |
---|
71 | return 0; |
---|
72 | |
---|
73 | return 1; |
---|
74 | } |
---|
75 | |
---|
76 | |
---|
77 | /* |
---|
78 | ** Save/restore deal with the mfn_to_pfn (M2P) and pfn_to_mfn (P2M) tables. |
---|
79 | ** The M2P simply holds the corresponding PFN, while the top bit of a P2M |
---|
80 | ** entry tell us whether or not the the PFN is currently mapped. |
---|
81 | */ |
---|
82 | |
---|
83 | #define PFN_TO_KB(_pfn) ((_pfn) << (PAGE_SHIFT - 10)) |
---|
84 | |
---|
85 | |
---|
86 | /* |
---|
87 | ** The M2P is made up of some number of 'chunks' of at least 2MB in size. |
---|
88 | ** The below definitions and utility function(s) deal with mapping the M2P |
---|
89 | ** regarldess of the underlying machine memory size or architecture. |
---|
90 | */ |
---|
91 | #define M2P_SHIFT L2_PAGETABLE_SHIFT_PAE |
---|
92 | #define M2P_CHUNK_SIZE (1 << M2P_SHIFT) |
---|
93 | #define M2P_SIZE(_m) ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT) |
---|
94 | #define M2P_CHUNKS(_m) (M2P_SIZE((_m)) >> M2P_SHIFT) |
---|
95 | |
---|
96 | /* Returns TRUE if the PFN is currently mapped */ |
---|
97 | #define is_mapped(pfn_type) (!((pfn_type) & 0x80000000UL)) |
---|