~jderose/ubuntu/raring/qemu/vde-again

« back to all changes in this revision

Viewing changes to tests/test-mmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno, Aurelien Jarno
  • Date: 2009-03-07 06:20:34 UTC
  • mfrom: (1.1.9 upstream)
  • mto: This revision was merged to the branch mainline in revision 7.
  • Revision ID: james.westby@ubuntu.com-20090307062034-i3pead4mw653v2el
Tags: 0.10.0-1
[ Aurelien Jarno ]
* New upstream release:
  - Fix fr-be keyboard mapping (closes: bug#514462).
  - Fix stat64 structure on ppc-linux-user (closes: bug#470231).
  - Add a chroot option (closes: bug#415996).
  - Add evdev support (closes: bug#513210).
  - Fix loop on symlinks in user mode (closes: bug#297572).
  - Bump depends on openbios-sparc.
  - Depends on openbios-ppc.
  - Update 12_signal_powerpc_support.patch.
  - Update 21_net_soopts.patch.
  - Drop 44_socklen_t_check.patch (merged upstream).
  - Drop 49_null_check.patch (merged upstream).
  - Update 64_ppc_asm_constraints.patch.
  - Drop security/CVE-2008-0928-fedora.patch (merged upstream).
  - Drop security/CVE-2007-5730.patch (merged upstream).
* patches/80_stable-branch.patch: add patches from stable branch:
  - Fix race condition between signal handler/execution loop (closes:
    bug#474386, bug#501731).
* debian/copyright: update.
* Compile and install .dtb files:
  - debian/control: build-depends on device-tree-compiler.
  - debian/patches/81_compile_dtb.patch: new patch from upstream.
  - debian/rules: compile and install bamboo.dtb and mpc8544.dtb.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Small test program to verify simulated mmap behaviour.
 
3
 *
 
4
 * When running qemu-linux-user with the -p flag, you may need to tell
 
5
 * this test program about the pagesize because getpagesize() will not reflect
 
6
 * the -p choice. Simply pass one argument beeing the pagesize.
 
7
 *
 
8
 * Copyright (c) 2007 AXIS Communications AB
 
9
 * Written by Edgar E. Iglesias.
 
10
 *
 
11
 * This program is free software; you can redistribute it and/or modify
 
12
 * it under the terms of the GNU General Public License as published by
 
13
 * the Free Software Foundation; either version 2 of the License, or
 
14
 * (at your option) any later version.
 
15
 *
 
16
 * This program is distributed in the hope that it will be useful,
 
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
19
 * GNU General Public License for more details.
 
20
 * 
 
21
 * You should have received a copy of the GNU General Public License
 
22
 * along with this program; if not, write to the Free Software
 
23
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
 
24
 *  MA 02110-1301, USA.
 
25
 */
 
26
 
 
27
#include <stdio.h>
 
28
#include <stdlib.h>
 
29
#include <stdint.h>
 
30
#include <string.h>
 
31
#include <unistd.h>
 
32
 
 
33
#include <sys/mman.h>
 
34
 
 
35
#define D(x)
 
36
 
 
37
#define fail_unless(x)                                         \
 
38
do                                                             \
 
39
{                                                              \
 
40
  if (!(x)) {                                                  \
 
41
    fprintf (stderr, "FAILED at %s:%d\n", __FILE__, __LINE__); \
 
42
    exit (EXIT_FAILURE);                                       \
 
43
  }                                                            \
 
44
} while (0);
 
45
 
 
46
unsigned char *dummybuf;
 
47
static unsigned int pagesize;
 
48
static unsigned int pagemask;
 
49
int test_fd;
 
50
size_t test_fsize;
 
51
 
 
52
void check_aligned_anonymous_unfixed_mmaps(void)
 
53
{
 
54
        void *p1;
 
55
        void *p2;
 
56
        void *p3;
 
57
        void *p4;
 
58
        void *p5;
 
59
        uintptr_t p;
 
60
        int i;
 
61
 
 
62
        fprintf (stderr, "%s", __func__);
 
63
        for (i = 0; i < 0x1fff; i++)
 
64
        {
 
65
                size_t len;
 
66
 
 
67
                len = pagesize + (pagesize * i & 7);
 
68
                p1 = mmap(NULL, len, PROT_READ, 
 
69
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
70
                p2 = mmap(NULL, len, PROT_READ, 
 
71
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
72
                p3 = mmap(NULL, len, PROT_READ, 
 
73
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
74
                p4 = mmap(NULL, len, PROT_READ, 
 
75
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
76
                p5 = mmap(NULL, len, PROT_READ, 
 
77
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
78
 
 
79
                /* Make sure we get pages aligned with the pagesize. The
 
80
                   target expects this.  */
 
81
                fail_unless (p1 != MAP_FAILED);
 
82
                fail_unless (p2 != MAP_FAILED);
 
83
                fail_unless (p3 != MAP_FAILED);
 
84
                fail_unless (p4 != MAP_FAILED);
 
85
                fail_unless (p5 != MAP_FAILED);
 
86
                p = (uintptr_t) p1;
 
87
                D(printf ("p=%x\n", p));
 
88
                fail_unless ((p & pagemask) == 0);
 
89
                p = (uintptr_t) p2;
 
90
                fail_unless ((p & pagemask) == 0);
 
91
                p = (uintptr_t) p3;
 
92
                fail_unless ((p & pagemask) == 0);
 
93
                p = (uintptr_t) p4;
 
94
                fail_unless ((p & pagemask) == 0);
 
95
                p = (uintptr_t) p5;
 
96
                fail_unless ((p & pagemask) == 0);
 
97
 
 
98
                /* Make sure we can read from the entire area.  */
 
99
                memcpy (dummybuf, p1, pagesize);
 
100
                memcpy (dummybuf, p2, pagesize);
 
101
                memcpy (dummybuf, p3, pagesize);
 
102
                memcpy (dummybuf, p4, pagesize);
 
103
                memcpy (dummybuf, p5, pagesize);
 
104
 
 
105
                munmap (p1, len);
 
106
                munmap (p2, len);
 
107
                munmap (p3, len);
 
108
                munmap (p4, len);
 
109
                munmap (p5, len);
 
110
        }
 
111
        fprintf (stderr, " passed\n");
 
112
}
 
113
 
 
114
void check_large_anonymous_unfixed_mmap(void)
 
115
{
 
116
        void *p1;
 
117
        uintptr_t p;
 
118
        size_t len;
 
119
 
 
120
        fprintf (stderr, "%s", __func__);
 
121
 
 
122
        len = 0x02000000;
 
123
        p1 = mmap(NULL, len, PROT_READ, 
 
124
                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
125
 
 
126
        /* Make sure we get pages aligned with the pagesize. The
 
127
           target expects this.  */
 
128
        fail_unless (p1 != MAP_FAILED);
 
129
        p = (uintptr_t) p1;
 
130
        fail_unless ((p & pagemask) == 0);
 
131
        
 
132
        /* Make sure we can read from the entire area.  */
 
133
        memcpy (dummybuf, p1, pagesize);
 
134
        munmap (p1, len);
 
135
        fprintf (stderr, " passed\n");
 
136
}
 
137
 
 
138
void check_aligned_anonymous_unfixed_colliding_mmaps(void)
 
139
{
 
140
        char *p1;
 
141
        char *p2;
 
142
        char *p3;
 
143
        uintptr_t p;
 
144
        int i;
 
145
 
 
146
        fprintf (stderr, "%s", __func__);
 
147
        for (i = 0; i < 0x2fff; i++)
 
148
        {
 
149
                int nlen;
 
150
                p1 = mmap(NULL, pagesize, PROT_READ, 
 
151
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
152
                fail_unless (p1 != MAP_FAILED);
 
153
                p = (uintptr_t) p1;
 
154
                fail_unless ((p & pagemask) == 0);
 
155
                memcpy (dummybuf, p1, pagesize);
 
156
 
 
157
                p2 = mmap(NULL, pagesize, PROT_READ, 
 
158
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
159
                fail_unless (p2 != MAP_FAILED);
 
160
                p = (uintptr_t) p2;
 
161
                fail_unless ((p & pagemask) == 0);
 
162
                memcpy (dummybuf, p2, pagesize);
 
163
 
 
164
 
 
165
                munmap (p1, pagesize);
 
166
                nlen = pagesize * 8;
 
167
                p3 = mmap(NULL, nlen, PROT_READ, 
 
168
                          MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
169
 
 
170
                /* Check if the mmaped areas collide.  */
 
171
                if (p3 < p2 
 
172
                    && (p3 + nlen) > p2)
 
173
                        fail_unless (0);
 
174
 
 
175
                memcpy (dummybuf, p3, pagesize);
 
176
 
 
177
                /* Make sure we get pages aligned with the pagesize. The
 
178
                   target expects this.  */
 
179
                fail_unless (p3 != MAP_FAILED);
 
180
                p = (uintptr_t) p3;
 
181
                fail_unless ((p & pagemask) == 0);
 
182
                munmap (p2, pagesize);
 
183
                munmap (p3, nlen);
 
184
        }
 
185
        fprintf (stderr, " passed\n");
 
186
}
 
187
 
 
188
void check_aligned_anonymous_fixed_mmaps(void)
 
189
{
 
190
        char *addr;
 
191
        void *p1;
 
192
        uintptr_t p;
 
193
        int i;
 
194
 
 
195
        /* Find a suitable address to start with.  */
 
196
        addr = mmap(NULL, pagesize * 40, PROT_READ | PROT_WRITE, 
 
197
                    MAP_PRIVATE | MAP_ANONYMOUS,
 
198
                    -1, 0);
 
199
        fprintf (stderr, "%s addr=%p", __func__, addr);
 
200
        fail_unless (addr != MAP_FAILED);
 
201
 
 
202
        for (i = 0; i < 40; i++)
 
203
        {
 
204
                /* Create submaps within our unfixed map.  */
 
205
                p1 = mmap(addr, pagesize, PROT_READ, 
 
206
                          MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
 
207
                          -1, 0);
 
208
                /* Make sure we get pages aligned with the pagesize. 
 
209
                   The target expects this.  */
 
210
                p = (uintptr_t) p1;
 
211
                fail_unless (p1 == addr);
 
212
                fail_unless ((p & pagemask) == 0);              
 
213
                memcpy (dummybuf, p1, pagesize);
 
214
                munmap (p1, pagesize);
 
215
                addr += pagesize;
 
216
        }
 
217
        fprintf (stderr, " passed\n");
 
218
}
 
219
 
 
220
void check_aligned_anonymous_fixed_mmaps_collide_with_host(void)
 
221
{
 
222
        char *addr;
 
223
        void *p1;
 
224
        uintptr_t p;
 
225
        int i;
 
226
 
 
227
        /* Find a suitable address to start with.  Right were the x86 hosts
 
228
         stack is.  */
 
229
        addr = ((void *)0x80000000);
 
230
        fprintf (stderr, "%s addr=%p", __func__, addr);
 
231
        fprintf (stderr, "FIXME: QEMU fails to track pages used by the host.");
 
232
 
 
233
        for (i = 0; i < 20; i++)
 
234
        {
 
235
                /* Create submaps within our unfixed map.  */
 
236
                p1 = mmap(addr, pagesize, PROT_READ | PROT_WRITE, 
 
237
                          MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
 
238
                          -1, 0);
 
239
                /* Make sure we get pages aligned with the pagesize. 
 
240
                   The target expects this.  */
 
241
                p = (uintptr_t) p1;
 
242
                fail_unless (p1 == addr);
 
243
                fail_unless ((p & pagemask) == 0);              
 
244
                memcpy (p1, dummybuf, pagesize);
 
245
                munmap (p1, pagesize);
 
246
                addr += pagesize;
 
247
        }
 
248
        fprintf (stderr, " passed\n");
 
249
}
 
250
 
 
251
void check_file_unfixed_mmaps(void)
 
252
{
 
253
        unsigned int *p1, *p2, *p3;
 
254
        uintptr_t p;
 
255
        int i;
 
256
 
 
257
        fprintf (stderr, "%s", __func__);
 
258
        for (i = 0; i < 0x10; i++)
 
259
        {
 
260
                size_t len;
 
261
 
 
262
                len = pagesize;
 
263
                p1 = mmap(NULL, len, PROT_READ, 
 
264
                          MAP_PRIVATE, 
 
265
                          test_fd, 0);
 
266
                p2 = mmap(NULL, len, PROT_READ, 
 
267
                          MAP_PRIVATE, 
 
268
                          test_fd, pagesize);
 
269
                p3 = mmap(NULL, len, PROT_READ, 
 
270
                          MAP_PRIVATE, 
 
271
                          test_fd, pagesize * 2);
 
272
 
 
273
                fail_unless (p1 != MAP_FAILED);
 
274
                fail_unless (p2 != MAP_FAILED);
 
275
                fail_unless (p3 != MAP_FAILED);
 
276
 
 
277
                /* Make sure we get pages aligned with the pagesize. The
 
278
                   target expects this.  */
 
279
                p = (uintptr_t) p1;
 
280
                fail_unless ((p & pagemask) == 0);
 
281
                p = (uintptr_t) p2;
 
282
                fail_unless ((p & pagemask) == 0);
 
283
                p = (uintptr_t) p3;
 
284
                fail_unless ((p & pagemask) == 0);
 
285
 
 
286
                /* Verify that the file maps was made correctly.  */
 
287
                D(printf ("p1=%d p2=%d p3=%d\n", *p1, *p2, *p3));
 
288
                fail_unless (*p1 == 0);
 
289
                fail_unless (*p2 == (pagesize / sizeof *p2));
 
290
                fail_unless (*p3 == ((pagesize * 2) / sizeof *p3));
 
291
 
 
292
                memcpy (dummybuf, p1, pagesize);
 
293
                memcpy (dummybuf, p2, pagesize);
 
294
                memcpy (dummybuf, p3, pagesize);
 
295
                munmap (p1, len);
 
296
                munmap (p2, len);
 
297
                munmap (p3, len);
 
298
        }
 
299
        fprintf (stderr, " passed\n");
 
300
}
 
301
 
 
302
void check_file_unfixed_eof_mmaps(void)
 
303
{
 
304
        char *cp;
 
305
        unsigned int *p1;
 
306
        uintptr_t p;
 
307
        int i;
 
308
 
 
309
        fprintf (stderr, "%s", __func__);
 
310
        for (i = 0; i < 0x10; i++)
 
311
        {
 
312
                p1 = mmap(NULL, pagesize, PROT_READ, 
 
313
                          MAP_PRIVATE, 
 
314
                          test_fd, 
 
315
                          (test_fsize - sizeof *p1) & ~pagemask);
 
316
 
 
317
                fail_unless (p1 != MAP_FAILED);
 
318
 
 
319
                /* Make sure we get pages aligned with the pagesize. The
 
320
                   target expects this.  */
 
321
                p = (uintptr_t) p1;
 
322
                fail_unless ((p & pagemask) == 0);
 
323
                /* Verify that the file maps was made correctly.  */
 
324
                fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1]
 
325
                             == ((test_fsize - sizeof *p1) / sizeof *p1));
 
326
 
 
327
                /* Verify that the end of page is accessable and zeroed.  */
 
328
                cp = (void *) p1;
 
329
                fail_unless (cp[pagesize - 4] == 0);
 
330
                munmap (p1, pagesize);
 
331
        }
 
332
        fprintf (stderr, " passed\n");
 
333
}
 
334
 
 
335
void check_file_fixed_eof_mmaps(void)
 
336
{
 
337
        char *addr;
 
338
        char *cp;
 
339
        unsigned int *p1;
 
340
        uintptr_t p;
 
341
        int i;
 
342
 
 
343
        /* Find a suitable address to start with.  */
 
344
        addr = mmap(NULL, pagesize * 44, PROT_READ, 
 
345
                    MAP_PRIVATE | MAP_ANONYMOUS,
 
346
                    -1, 0);
 
347
 
 
348
        fprintf (stderr, "%s addr=%p", __func__, (void *)addr);
 
349
        fail_unless (addr != MAP_FAILED);
 
350
 
 
351
        for (i = 0; i < 0x10; i++)
 
352
        {
 
353
                /* Create submaps within our unfixed map.  */
 
354
                p1 = mmap(addr, pagesize, PROT_READ, 
 
355
                          MAP_PRIVATE | MAP_FIXED, 
 
356
                          test_fd, 
 
357
                          (test_fsize - sizeof *p1) & ~pagemask);
 
358
 
 
359
                fail_unless (p1 != MAP_FAILED);
 
360
 
 
361
                /* Make sure we get pages aligned with the pagesize. The
 
362
                   target expects this.  */
 
363
                p = (uintptr_t) p1;
 
364
                fail_unless ((p & pagemask) == 0);
 
365
 
 
366
                /* Verify that the file maps was made correctly.  */
 
367
                fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1]
 
368
                             == ((test_fsize - sizeof *p1) / sizeof *p1));
 
369
 
 
370
                /* Verify that the end of page is accessable and zeroed.  */
 
371
                cp = (void *)p1;
 
372
                fail_unless (cp[pagesize - 4] == 0);
 
373
                munmap (p1, pagesize);
 
374
                addr += pagesize;
 
375
        }
 
376
        fprintf (stderr, " passed\n");
 
377
}
 
378
 
 
379
void check_file_fixed_mmaps(void)
 
380
{
 
381
        unsigned char *addr;
 
382
        unsigned int *p1, *p2, *p3, *p4;
 
383
        int i;
 
384
 
 
385
        /* Find a suitable address to start with.  */
 
386
        addr = mmap(NULL, pagesize * 40 * 4, PROT_READ, 
 
387
                    MAP_PRIVATE | MAP_ANONYMOUS,
 
388
                    -1, 0);
 
389
        fprintf (stderr, "%s addr=%p", __func__, (void *)addr);
 
390
        fail_unless (addr != MAP_FAILED);
 
391
 
 
392
        for (i = 0; i < 40; i++)
 
393
        {
 
394
                p1 = mmap(addr, pagesize, PROT_READ, 
 
395
                          MAP_PRIVATE | MAP_FIXED,
 
396
                          test_fd, 0);
 
397
                p2 = mmap(addr + pagesize, pagesize, PROT_READ, 
 
398
                          MAP_PRIVATE | MAP_FIXED,
 
399
                          test_fd, pagesize);
 
400
                p3 = mmap(addr + pagesize * 2, pagesize, PROT_READ, 
 
401
                          MAP_PRIVATE | MAP_FIXED,
 
402
                          test_fd, pagesize * 2);
 
403
                p4 = mmap(addr + pagesize * 3, pagesize, PROT_READ, 
 
404
                          MAP_PRIVATE | MAP_FIXED,
 
405
                          test_fd, pagesize * 3);
 
406
 
 
407
                /* Make sure we get pages aligned with the pagesize. 
 
408
                   The target expects this.  */
 
409
                fail_unless (p1 == (void *)addr);
 
410
                fail_unless (p2 == (void *)addr + pagesize);
 
411
                fail_unless (p3 == (void *)addr + pagesize * 2);
 
412
                fail_unless (p4 == (void *)addr + pagesize * 3);
 
413
 
 
414
                /* Verify that the file maps was made correctly.  */
 
415
                fail_unless (*p1 == 0);
 
416
                fail_unless (*p2 == (pagesize / sizeof *p2));
 
417
                fail_unless (*p3 == ((pagesize * 2) / sizeof *p3));
 
418
                fail_unless (*p4 == ((pagesize * 3) / sizeof *p4));
 
419
 
 
420
                memcpy (dummybuf, p1, pagesize);
 
421
                memcpy (dummybuf, p2, pagesize);
 
422
                memcpy (dummybuf, p3, pagesize);
 
423
                memcpy (dummybuf, p4, pagesize);
 
424
 
 
425
                munmap (p1, pagesize);
 
426
                munmap (p2, pagesize);
 
427
                munmap (p3, pagesize);
 
428
                munmap (p4, pagesize);
 
429
                addr += pagesize * 4;
 
430
        }
 
431
        fprintf (stderr, " passed\n");
 
432
}
 
433
 
 
434
int main(int argc, char **argv)
 
435
{
 
436
        char tempname[] = "/tmp/.cmmapXXXXXX";
 
437
        unsigned int i;
 
438
 
 
439
        /* Trust the first argument, otherwise probe the system for our
 
440
           pagesize.  */
 
441
        if (argc > 1)
 
442
                pagesize = strtoul(argv[1], NULL, 0);
 
443
        else
 
444
                pagesize = sysconf(_SC_PAGESIZE);
 
445
 
 
446
        /* Assume pagesize is a power of two.  */
 
447
        pagemask = pagesize - 1;
 
448
        dummybuf = malloc (pagesize);
 
449
        printf ("pagesize=%u pagemask=%x\n", pagesize, pagemask);
 
450
 
 
451
        test_fd = mkstemp(tempname);
 
452
        unlink(tempname);
 
453
 
 
454
        /* Fill the file with int's counting from zero and up.  */
 
455
        for (i = 0; i < (pagesize * 4) / sizeof i; i++)
 
456
                write (test_fd, &i, sizeof i);
 
457
        /* Append a few extra writes to make the file end at non 
 
458
           page boundary.  */
 
459
        write (test_fd, &i, sizeof i); i++;
 
460
        write (test_fd, &i, sizeof i); i++;
 
461
        write (test_fd, &i, sizeof i); i++;
 
462
 
 
463
        test_fsize = lseek(test_fd, 0, SEEK_CUR);
 
464
 
 
465
        /* Run the tests.  */
 
466
        check_aligned_anonymous_unfixed_mmaps();
 
467
        check_aligned_anonymous_unfixed_colliding_mmaps();
 
468
        check_aligned_anonymous_fixed_mmaps();
 
469
        check_file_unfixed_mmaps();
 
470
        check_file_fixed_mmaps();
 
471
        check_file_fixed_eof_mmaps();
 
472
        check_file_unfixed_eof_mmaps();
 
473
 
 
474
        /* Fails at the moment.  */
 
475
        /* check_aligned_anonymous_fixed_mmaps_collide_with_host(); */
 
476
 
 
477
        return EXIT_SUCCESS;
 
478
}