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 <unistd.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/mman.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 
29 #include "xc_private.h"
30 #include "xenguest.h"
31 
32 #include <xen/memory.h>
33 #include <xen/elfnote.h>
34 
35 #ifndef ELFSIZE
36 #include <limits.h>
37 #if UINT_MAX == ULONG_MAX
38 #define ELFSIZE 32
39 #else
40 #define ELFSIZE 64
41 #endif
42 #endif
43 
44 char *xc_read_image(xc_interface *xch,
45                     const char *filename, unsigned long *size);
46 char *xc_inflate_buffer(xc_interface *xch,
47                         const char *in_buf,
48                         unsigned long in_size,
49                         unsigned long *out_size);
50 
51 unsigned long csum_page (void * page);
52 
53 #define _PAGE_PRESENT   0x001
54 #define _PAGE_RW        0x002
55 #define _PAGE_USER      0x004
56 #define _PAGE_PWT       0x008
57 #define _PAGE_PCD       0x010
58 #define _PAGE_ACCESSED  0x020
59 #define _PAGE_DIRTY     0x040
60 #define _PAGE_PAT       0x080
61 #define _PAGE_PSE       0x080
62 #define _PAGE_GLOBAL    0x100
63 
64 #define VIRT_BITS_I386     32
65 #define VIRT_BITS_X86_64   48
66 
67 #define PGTBL_LEVELS_I386       3
68 #define PGTBL_LEVELS_X86_64     4
69 
70 #define PGTBL_LEVEL_SHIFT_X86   9
71 
72 #define L1_PAGETABLE_SHIFT_PAE        12
73 #define L2_PAGETABLE_SHIFT_PAE        21
74 #define L3_PAGETABLE_SHIFT_PAE        30
75 #define L1_PAGETABLE_ENTRIES_PAE     512
76 #define L2_PAGETABLE_ENTRIES_PAE     512
77 #define L3_PAGETABLE_ENTRIES_PAE       4
78 
79 #define L1_PAGETABLE_SHIFT_X86_64     12
80 #define L2_PAGETABLE_SHIFT_X86_64     21
81 #define L3_PAGETABLE_SHIFT_X86_64     30
82 #define L4_PAGETABLE_SHIFT_X86_64     39
83 #define L1_PAGETABLE_ENTRIES_X86_64  512
84 #define L2_PAGETABLE_ENTRIES_X86_64  512
85 #define L3_PAGETABLE_ENTRIES_X86_64  512
86 #define L4_PAGETABLE_ENTRIES_X86_64  512
87 
88 typedef uint64_t x86_pgentry_t;
89 
90 #define PAGE_SHIFT_ARM          12
91 #define PAGE_SIZE_ARM           (1UL << PAGE_SHIFT_ARM)
92 #define PAGE_MASK_ARM           (~(PAGE_SIZE_ARM-1))
93 
94 #define PAGE_SHIFT_X86          12
95 #define PAGE_SIZE_X86           (1UL << PAGE_SHIFT_X86)
96 #define PAGE_MASK_X86           (~(PAGE_SIZE_X86-1))
97 
98 #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
99 #define NRPAGES(x) (ROUNDUP(x, PAGE_SHIFT) >> PAGE_SHIFT)
100 
101 
102 /* XXX SMH: following skanky macros rely on variable p2m_size being set */
103 /* XXX TJD: also, "guest_width" should be the guest's sizeof(unsigned long) */
104 
105 struct domain_info_context {
106     unsigned int guest_width;
107     unsigned long p2m_size;
108 };
109 
xc_pfn_to_mfn(xen_pfn_t pfn,xen_pfn_t * p2m,unsigned gwidth)110 static inline xen_pfn_t xc_pfn_to_mfn(xen_pfn_t pfn, xen_pfn_t *p2m,
111                                       unsigned gwidth)
112 {
113     if ( gwidth == sizeof(uint64_t) )
114         /* 64 bit guest.  Need to truncate their pfns for 32 bit toolstacks. */
115         return ((uint64_t *)p2m)[pfn];
116     else
117     {
118         /* 32 bit guest.  Need to expand INVALID_MFN for 64 bit toolstacks. */
119         uint32_t mfn = ((uint32_t *)p2m)[pfn];
120 
121         return mfn == ~0U ? INVALID_MFN : mfn;
122     }
123 }
124 
125 /* Number of xen_pfn_t in a page */
126 #define FPP             (PAGE_SIZE/(dinfo->guest_width))
127 
128 /* Number of entries in the pfn_to_mfn_frame_list_list */
129 #define P2M_FLL_ENTRIES (((dinfo->p2m_size)+(FPP*FPP)-1)/(FPP*FPP))
130 
131 /* Number of entries in the pfn_to_mfn_frame_list */
132 #define P2M_FL_ENTRIES  (((dinfo->p2m_size)+FPP-1)/FPP)
133 
134 /* Size in bytes of the pfn_to_mfn_frame_list     */
135 #define P2M_GUEST_FL_SIZE ((P2M_FL_ENTRIES) * (dinfo->guest_width))
136 #define P2M_TOOLS_FL_SIZE ((P2M_FL_ENTRIES) *                           \
137                            max_t(size_t, sizeof(xen_pfn_t), dinfo->guest_width))
138 
139 /* Masks for PTE<->PFN conversions */
140 #define MADDR_BITS_X86  ((dinfo->guest_width == 8) ? 52 : 44)
141 #define MFN_MASK_X86    ((1ULL << (MADDR_BITS_X86 - PAGE_SHIFT_X86)) - 1)
142 #define MADDR_MASK_X86  (MFN_MASK_X86 << PAGE_SHIFT_X86)
143 
144 int pin_table(xc_interface *xch, unsigned int type, unsigned long mfn,
145               uint32_t dom);
146 
147 #endif /* XG_PRIVATE_H */
148