1 | /****************************************************************************** |
---|
2 | * xg_private.c |
---|
3 | * |
---|
4 | * Helper functions for the rest of the library. |
---|
5 | */ |
---|
6 | |
---|
7 | #include <stdlib.h> |
---|
8 | #include <unistd.h> |
---|
9 | #include <zlib.h> |
---|
10 | #include <strings.h> |
---|
11 | |
---|
12 | #include "xg_private.h" |
---|
13 | |
---|
14 | int lock_pages(void *addr, size_t len) |
---|
15 | { |
---|
16 | int e = 0; |
---|
17 | #ifndef __sun__ |
---|
18 | e = mlock(addr, len); |
---|
19 | #endif |
---|
20 | return (e); |
---|
21 | } |
---|
22 | |
---|
23 | void unlock_pages(void *addr, size_t len) |
---|
24 | { |
---|
25 | #ifndef __sun__ |
---|
26 | safe_munlock(addr, len); |
---|
27 | #endif |
---|
28 | } |
---|
29 | |
---|
30 | char *xc_read_image(const char *filename, unsigned long *size) |
---|
31 | { |
---|
32 | int kernel_fd = -1; |
---|
33 | gzFile kernel_gfd = NULL; |
---|
34 | char *image = NULL, *tmp; |
---|
35 | unsigned int bytes; |
---|
36 | |
---|
37 | if ( (filename == NULL) || (size == NULL) ) |
---|
38 | return NULL; |
---|
39 | |
---|
40 | if ( (kernel_fd = open(filename, O_RDONLY)) < 0 ) |
---|
41 | { |
---|
42 | PERROR("Could not open kernel image"); |
---|
43 | goto out; |
---|
44 | } |
---|
45 | |
---|
46 | if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL ) |
---|
47 | { |
---|
48 | PERROR("Could not allocate decompression state for state file"); |
---|
49 | goto out; |
---|
50 | } |
---|
51 | |
---|
52 | *size = 0; |
---|
53 | |
---|
54 | #define CHUNK 1*1024*1024 |
---|
55 | while(1) |
---|
56 | { |
---|
57 | if ( (tmp = realloc(image, *size + CHUNK)) == NULL ) |
---|
58 | { |
---|
59 | PERROR("Could not allocate memory for kernel image"); |
---|
60 | free(image); |
---|
61 | image = NULL; |
---|
62 | goto out; |
---|
63 | } |
---|
64 | image = tmp; |
---|
65 | |
---|
66 | bytes = gzread(kernel_gfd, image + *size, CHUNK); |
---|
67 | switch (bytes) |
---|
68 | { |
---|
69 | case -1: |
---|
70 | PERROR("Error reading kernel image"); |
---|
71 | free(image); |
---|
72 | image = NULL; |
---|
73 | goto out; |
---|
74 | case 0: /* EOF */ |
---|
75 | goto out; |
---|
76 | default: |
---|
77 | *size += bytes; |
---|
78 | break; |
---|
79 | } |
---|
80 | } |
---|
81 | #undef CHUNK |
---|
82 | |
---|
83 | out: |
---|
84 | if ( *size == 0 ) |
---|
85 | { |
---|
86 | PERROR("Could not read kernel image"); |
---|
87 | free(image); |
---|
88 | image = NULL; |
---|
89 | } |
---|
90 | else if ( image ) |
---|
91 | { |
---|
92 | /* Shrink allocation to fit image. */ |
---|
93 | tmp = realloc(image, *size); |
---|
94 | if ( tmp ) |
---|
95 | image = tmp; |
---|
96 | } |
---|
97 | |
---|
98 | if ( kernel_gfd != NULL ) |
---|
99 | gzclose(kernel_gfd); |
---|
100 | else if ( kernel_fd >= 0 ) |
---|
101 | close(kernel_fd); |
---|
102 | return image; |
---|
103 | } |
---|
104 | |
---|
105 | char *xc_inflate_buffer(const char *in_buf, unsigned long in_size, |
---|
106 | unsigned long *out_size) |
---|
107 | { |
---|
108 | int sts; |
---|
109 | z_stream zStream; |
---|
110 | unsigned long out_len; |
---|
111 | char *out_buf; |
---|
112 | |
---|
113 | /* Not compressed? Then return the original buffer. */ |
---|
114 | if ( ((unsigned char)in_buf[0] != 0x1F) || |
---|
115 | ((unsigned char)in_buf[1] != 0x8B) ) |
---|
116 | { |
---|
117 | if ( out_size != NULL ) |
---|
118 | *out_size = in_size; |
---|
119 | return (char *)in_buf; |
---|
120 | } |
---|
121 | |
---|
122 | out_len = (unsigned char)in_buf[in_size-4] + |
---|
123 | (256 * ((unsigned char)in_buf[in_size-3] + |
---|
124 | (256 * ((unsigned char)in_buf[in_size-2] + |
---|
125 | (256 * (unsigned char)in_buf[in_size-1]))))); |
---|
126 | |
---|
127 | bzero(&zStream, sizeof(zStream)); |
---|
128 | out_buf = malloc(out_len + 16); /* Leave a little extra space */ |
---|
129 | if ( out_buf == NULL ) |
---|
130 | { |
---|
131 | ERROR("Error mallocing buffer\n"); |
---|
132 | return NULL; |
---|
133 | } |
---|
134 | |
---|
135 | zStream.next_in = (unsigned char *)in_buf; |
---|
136 | zStream.avail_in = in_size; |
---|
137 | zStream.next_out = (unsigned char *)out_buf; |
---|
138 | zStream.avail_out = out_len+16; |
---|
139 | sts = inflateInit2(&zStream, (MAX_WBITS+32)); /* +32 means "handle gzip" */ |
---|
140 | if ( sts != Z_OK ) |
---|
141 | { |
---|
142 | ERROR("inflateInit failed, sts %d\n", sts); |
---|
143 | free(out_buf); |
---|
144 | return NULL; |
---|
145 | } |
---|
146 | |
---|
147 | /* Inflate in one pass/call */ |
---|
148 | sts = inflate(&zStream, Z_FINISH); |
---|
149 | if ( sts != Z_STREAM_END ) |
---|
150 | { |
---|
151 | ERROR("inflate failed, sts %d\n", sts); |
---|
152 | free(out_buf); |
---|
153 | return NULL; |
---|
154 | } |
---|
155 | |
---|
156 | if ( out_size != NULL ) |
---|
157 | *out_size = out_len; |
---|
158 | |
---|
159 | return out_buf; |
---|
160 | } |
---|
161 | |
---|
162 | /*******************/ |
---|
163 | |
---|
164 | int pin_table( |
---|
165 | int xc_handle, unsigned int type, unsigned long mfn, domid_t dom) |
---|
166 | { |
---|
167 | struct mmuext_op op; |
---|
168 | |
---|
169 | op.cmd = type; |
---|
170 | op.arg1.mfn = mfn; |
---|
171 | |
---|
172 | if ( xc_mmuext_op(xc_handle, &op, 1, dom) < 0 ) |
---|
173 | return 1; |
---|
174 | |
---|
175 | return 0; |
---|
176 | } |
---|
177 | |
---|
178 | /* This is shared between save and restore, and may generally be useful. */ |
---|
179 | unsigned long csum_page(void *page) |
---|
180 | { |
---|
181 | int i; |
---|
182 | unsigned long *p = page; |
---|
183 | unsigned long long sum=0; |
---|
184 | |
---|
185 | for ( i = 0; i < (PAGE_SIZE/sizeof(unsigned long)); i++ ) |
---|
186 | sum += p[i]; |
---|
187 | |
---|
188 | return sum ^ (sum>>32); |
---|
189 | } |
---|
190 | |
---|
191 | __attribute__((weak)) |
---|
192 | int xc_hvm_build(int xc_handle, |
---|
193 | uint32_t domid, |
---|
194 | int memsize, |
---|
195 | const char *image_name) |
---|
196 | { |
---|
197 | errno = ENOSYS; |
---|
198 | return -1; |
---|
199 | } |
---|
200 | |
---|
201 | /* |
---|
202 | * Local variables: |
---|
203 | * mode: C |
---|
204 | * c-set-style: "BSD" |
---|
205 | * c-basic-offset: 4 |
---|
206 | * tab-width: 4 |
---|
207 | * indent-tabs-mode: nil |
---|
208 | * End: |
---|
209 | */ |
---|