1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation;
5  * version 2.1 of the License.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; If not, see <http://www.gnu.org/licenses/>.
14  */
15 
16 #ifndef XG_PRIVATE_H
17 #define XG_PRIVATE_H
18 
19 #include <inttypes.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/mman.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 
30 #include "xc_private.h"
31 #include "xc_bitops.h"
32 #include "xenguest.h"
33 
34 #include <xen/memory.h>
35 #include <xen/elfnote.h>
36 #include <xen/libelf/libelf.h>
37 
38 #ifndef ELFSIZE
39 #include <limits.h>
40 #if UINT_MAX == ULONG_MAX
41 #define ELFSIZE 32
42 #else
43 #define ELFSIZE 64
44 #endif
45 #endif
46 
47 #define GET_FIELD(_p, _f, _w) (((_w) == 8) ? ((_p)->x64._f) : ((_p)->x32._f))
48 
49 #define SET_FIELD(_p, _f, _v, _w) do {          \
50     if ((_w) == 8)                              \
51         (_p)->x64._f = (_v);                    \
52     else                                        \
53         (_p)->x32._f = (_v);                    \
54 } while (0)
55 
56 struct domain_info_context {
57     unsigned int guest_width;
58     unsigned int p2m_frames;
59     unsigned long p2m_size;
60 };
61 
62 struct xc_dom_loader {
63     const char *name;
64     /* Sadly the error returns from these functions are not consistent: */
65     elf_negerrnoval (*probe) (struct xc_dom_image * dom);
66     elf_negerrnoval (*parser) (struct xc_dom_image * dom);
67     elf_errorstatus (*loader) (struct xc_dom_image * dom);
68 
69     struct xc_dom_loader *next;
70 };
71 
72 #define __init __attribute__ ((constructor))
73 void xc_dom_register_loader(struct xc_dom_loader *loader);
74 
75 char *xc_read_image(xc_interface *xch,
76                     const char *filename, unsigned long *size);
77 char *xc_inflate_buffer(xc_interface *xch,
78                         const char *in_buf,
79                         unsigned long in_size,
80                         unsigned long *out_size);
81 
82 #if !defined(__MINIOS__) || defined(XG_NEED_UNALIGNED)
83 
get_unaligned_le32(const uint8_t * buf)84 static inline unsigned int get_unaligned_le32(const uint8_t *buf)
85 {
86     return ((unsigned int)buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
87 }
88 
89 #endif /* !__MINIOS__ || XG_NEED_UNALIGNED */
90 
91 unsigned long csum_page (void * page);
92 
93 #define _PAGE_PRESENT   0x001
94 #define _PAGE_RW        0x002
95 #define _PAGE_USER      0x004
96 #define _PAGE_PWT       0x008
97 #define _PAGE_PCD       0x010
98 #define _PAGE_ACCESSED  0x020
99 #define _PAGE_DIRTY     0x040
100 #define _PAGE_PAT       0x080
101 #define _PAGE_PSE       0x080
102 #define _PAGE_GLOBAL    0x100
103 
104 #define VIRT_BITS_I386     32
105 #define VIRT_BITS_X86_64   48
106 
107 #define PGTBL_LEVELS_I386       3
108 #define PGTBL_LEVELS_X86_64     4
109 
110 #define PGTBL_LEVEL_SHIFT_X86   9
111 
112 #define L1_PAGETABLE_SHIFT_PAE        12
113 #define L2_PAGETABLE_SHIFT_PAE        21
114 #define L3_PAGETABLE_SHIFT_PAE        30
115 #define L1_PAGETABLE_ENTRIES_PAE     512
116 #define L2_PAGETABLE_ENTRIES_PAE     512
117 #define L3_PAGETABLE_ENTRIES_PAE       4
118 
119 #define L1_PAGETABLE_SHIFT_X86_64     12
120 #define L2_PAGETABLE_SHIFT_X86_64     21
121 #define L3_PAGETABLE_SHIFT_X86_64     30
122 #define L4_PAGETABLE_SHIFT_X86_64     39
123 #define L1_PAGETABLE_ENTRIES_X86_64  512
124 #define L2_PAGETABLE_ENTRIES_X86_64  512
125 #define L3_PAGETABLE_ENTRIES_X86_64  512
126 #define L4_PAGETABLE_ENTRIES_X86_64  512
127 
128 typedef uint64_t x86_pgentry_t;
129 
130 #define PAGE_SHIFT_ARM          12
131 #define PAGE_SIZE_ARM           (1UL << PAGE_SHIFT_ARM)
132 #define PAGE_MASK_ARM           (~(PAGE_SIZE_ARM-1))
133 
134 #define PAGE_SHIFT_X86          12
135 #define PAGE_SIZE_X86           (1UL << PAGE_SHIFT_X86)
136 #define PAGE_MASK_X86           (~(PAGE_SIZE_X86-1))
137 
138 #define NRPAGES(x) (ROUNDUP(x, PAGE_SHIFT) >> PAGE_SHIFT)
139 
xc_pfn_to_mfn(xen_pfn_t pfn,xen_pfn_t * p2m,unsigned gwidth)140 static inline xen_pfn_t xc_pfn_to_mfn(xen_pfn_t pfn, xen_pfn_t *p2m,
141                                       unsigned gwidth)
142 {
143     if ( gwidth == sizeof(uint64_t) )
144         /* 64 bit guest.  Need to truncate their pfns for 32 bit toolstacks. */
145         return ((uint64_t *)p2m)[pfn];
146     else
147     {
148         /* 32 bit guest.  Need to expand INVALID_MFN for 64 bit toolstacks. */
149         uint32_t mfn = ((uint32_t *)p2m)[pfn];
150 
151         return mfn == ~0U ? INVALID_MFN : mfn;
152     }
153 }
154 
155 
156 /* Masks for PTE<->PFN conversions */
157 #define MADDR_BITS_X86  ((dinfo->guest_width == 8) ? 52 : 44)
158 #define MFN_MASK_X86    ((1ULL << (MADDR_BITS_X86 - PAGE_SHIFT_X86)) - 1)
159 
160 int pin_table(xc_interface *xch, unsigned int type, unsigned long mfn,
161               uint32_t dom);
162 
163 /*
164  * The M2P is made up of some number of 'chunks' of at least 2MB in size.
165  * The below definitions and utility function(s) deal with mapping the M2P
166  * regarldess of the underlying machine memory size or architecture.
167  */
168 #define M2P_SHIFT       L2_PAGETABLE_SHIFT_PAE
169 #define M2P_CHUNK_SIZE  (1 << M2P_SHIFT)
170 #define M2P_SIZE(_m)    ROUNDUP(((_m) * sizeof(xen_pfn_t)), M2P_SHIFT)
171 #define M2P_CHUNKS(_m)  (M2P_SIZE((_m)) >> M2P_SHIFT)
172 
173 #if defined(__x86_64__) || defined(__i386__)
174 #include <xen/lib/x86/cpu-policy.h>
175 
176 struct xc_cpu_policy {
177     struct cpu_policy policy;
178     xen_cpuid_leaf_t leaves[CPUID_MAX_SERIALISED_LEAVES];
179     xen_msr_entry_t msrs[MSR_MAX_SERIALISED_ENTRIES];
180 };
181 #endif /* x86 */
182 
183 #endif /* XG_PRIVATE_H */
184