1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker * Copyright (C) 2012 Linux Test Project, Inc.
3*49cdfc7eSAndroid Build Coastguard Worker *
4*49cdfc7eSAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*49cdfc7eSAndroid Build Coastguard Worker * modify it under the terms of version 2 of the GNU General Public
6*49cdfc7eSAndroid Build Coastguard Worker * License as published by the Free Software Foundation.
7*49cdfc7eSAndroid Build Coastguard Worker *
8*49cdfc7eSAndroid Build Coastguard Worker * This program is distributed in the hope that it would be useful,
9*49cdfc7eSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
10*49cdfc7eSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11*49cdfc7eSAndroid Build Coastguard Worker *
12*49cdfc7eSAndroid Build Coastguard Worker * Further, this software is distributed without any warranty that it
13*49cdfc7eSAndroid Build Coastguard Worker * is free of the rightful claim of any third person regarding
14*49cdfc7eSAndroid Build Coastguard Worker * infringement or the like. Any license provided herein, whether
15*49cdfc7eSAndroid Build Coastguard Worker * implied or otherwise, applies only to this software file. Patent
16*49cdfc7eSAndroid Build Coastguard Worker * licenses, if any, provided herein do not apply to combinations of
17*49cdfc7eSAndroid Build Coastguard Worker * this program with other software, or any other product whatsoever.
18*49cdfc7eSAndroid Build Coastguard Worker *
19*49cdfc7eSAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License
20*49cdfc7eSAndroid Build Coastguard Worker * along with this program; if not, write the Free Software
21*49cdfc7eSAndroid Build Coastguard Worker * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22*49cdfc7eSAndroid Build Coastguard Worker * 02110-1301, USA.
23*49cdfc7eSAndroid Build Coastguard Worker */
24*49cdfc7eSAndroid Build Coastguard Worker /*
25*49cdfc7eSAndroid Build Coastguard Worker * Test Name: mremap05
26*49cdfc7eSAndroid Build Coastguard Worker *
27*49cdfc7eSAndroid Build Coastguard Worker * Test Description:
28*49cdfc7eSAndroid Build Coastguard Worker * Verify that MREMAP_FIXED fails without MREMAP_MAYMOVE.
29*49cdfc7eSAndroid Build Coastguard Worker * Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if target address
30*49cdfc7eSAndroid Build Coastguard Worker * is not page aligned.
31*49cdfc7eSAndroid Build Coastguard Worker * Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if old range
32*49cdfc7eSAndroid Build Coastguard Worker * overlaps with new range.
33*49cdfc7eSAndroid Build Coastguard Worker * Verify that MREMAP_FIXED|MREMAP_MAYMOVE can move mapping to new address.
34*49cdfc7eSAndroid Build Coastguard Worker * Verify that MREMAP_FIXED|MREMAP_MAYMOVE unmaps previous mapping
35*49cdfc7eSAndroid Build Coastguard Worker * at the address range specified by new_address and new_size.
36*49cdfc7eSAndroid Build Coastguard Worker */
37*49cdfc7eSAndroid Build Coastguard Worker
38*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
39*49cdfc7eSAndroid Build Coastguard Worker #include "config.h"
40*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mman.h>
41*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
42*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
43*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
44*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
45*49cdfc7eSAndroid Build Coastguard Worker
46*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "mremap05";
47*49cdfc7eSAndroid Build Coastguard Worker
48*49cdfc7eSAndroid Build Coastguard Worker struct test_case_t {
49*49cdfc7eSAndroid Build Coastguard Worker char *old_address;
50*49cdfc7eSAndroid Build Coastguard Worker char *new_address;
51*49cdfc7eSAndroid Build Coastguard Worker size_t old_size; /* in pages */
52*49cdfc7eSAndroid Build Coastguard Worker size_t new_size; /* in pages */
53*49cdfc7eSAndroid Build Coastguard Worker int flags;
54*49cdfc7eSAndroid Build Coastguard Worker const char *msg;
55*49cdfc7eSAndroid Build Coastguard Worker void *exp_ret;
56*49cdfc7eSAndroid Build Coastguard Worker int exp_errno;
57*49cdfc7eSAndroid Build Coastguard Worker char *ret;
58*49cdfc7eSAndroid Build Coastguard Worker void (*setup) (struct test_case_t *);
59*49cdfc7eSAndroid Build Coastguard Worker void (*cleanup) (struct test_case_t *);
60*49cdfc7eSAndroid Build Coastguard Worker };
61*49cdfc7eSAndroid Build Coastguard Worker
62*49cdfc7eSAndroid Build Coastguard Worker static void setup(void);
63*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void);
64*49cdfc7eSAndroid Build Coastguard Worker static void setup0(struct test_case_t *);
65*49cdfc7eSAndroid Build Coastguard Worker static void setup1(struct test_case_t *);
66*49cdfc7eSAndroid Build Coastguard Worker static void setup2(struct test_case_t *);
67*49cdfc7eSAndroid Build Coastguard Worker static void setup3(struct test_case_t *);
68*49cdfc7eSAndroid Build Coastguard Worker static void setup4(struct test_case_t *);
69*49cdfc7eSAndroid Build Coastguard Worker static void cleanup0(struct test_case_t *);
70*49cdfc7eSAndroid Build Coastguard Worker static void cleanup1(struct test_case_t *);
71*49cdfc7eSAndroid Build Coastguard Worker
72*49cdfc7eSAndroid Build Coastguard Worker struct test_case_t tdat[] = {
73*49cdfc7eSAndroid Build Coastguard Worker {
74*49cdfc7eSAndroid Build Coastguard Worker .old_size = 1,
75*49cdfc7eSAndroid Build Coastguard Worker .new_size = 1,
76*49cdfc7eSAndroid Build Coastguard Worker .flags = MREMAP_FIXED,
77*49cdfc7eSAndroid Build Coastguard Worker .msg = "MREMAP_FIXED requires MREMAP_MAYMOVE",
78*49cdfc7eSAndroid Build Coastguard Worker .exp_ret = MAP_FAILED,
79*49cdfc7eSAndroid Build Coastguard Worker .exp_errno = EINVAL,
80*49cdfc7eSAndroid Build Coastguard Worker .setup = setup0,
81*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup0},
82*49cdfc7eSAndroid Build Coastguard Worker {
83*49cdfc7eSAndroid Build Coastguard Worker .old_size = 1,
84*49cdfc7eSAndroid Build Coastguard Worker .new_size = 1,
85*49cdfc7eSAndroid Build Coastguard Worker .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
86*49cdfc7eSAndroid Build Coastguard Worker .msg = "new_addr has to be page aligned",
87*49cdfc7eSAndroid Build Coastguard Worker .exp_ret = MAP_FAILED,
88*49cdfc7eSAndroid Build Coastguard Worker .exp_errno = EINVAL,
89*49cdfc7eSAndroid Build Coastguard Worker .setup = setup1,
90*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup0},
91*49cdfc7eSAndroid Build Coastguard Worker {
92*49cdfc7eSAndroid Build Coastguard Worker .old_size = 2,
93*49cdfc7eSAndroid Build Coastguard Worker .new_size = 1,
94*49cdfc7eSAndroid Build Coastguard Worker .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
95*49cdfc7eSAndroid Build Coastguard Worker .msg = "old/new area must not overlap",
96*49cdfc7eSAndroid Build Coastguard Worker .exp_ret = MAP_FAILED,
97*49cdfc7eSAndroid Build Coastguard Worker .exp_errno = EINVAL,
98*49cdfc7eSAndroid Build Coastguard Worker .setup = setup2,
99*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup0},
100*49cdfc7eSAndroid Build Coastguard Worker {
101*49cdfc7eSAndroid Build Coastguard Worker .old_size = 1,
102*49cdfc7eSAndroid Build Coastguard Worker .new_size = 1,
103*49cdfc7eSAndroid Build Coastguard Worker .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
104*49cdfc7eSAndroid Build Coastguard Worker .msg = "mremap #1",
105*49cdfc7eSAndroid Build Coastguard Worker .setup = setup3,
106*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup0},
107*49cdfc7eSAndroid Build Coastguard Worker {
108*49cdfc7eSAndroid Build Coastguard Worker .old_size = 1,
109*49cdfc7eSAndroid Build Coastguard Worker .new_size = 1,
110*49cdfc7eSAndroid Build Coastguard Worker .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
111*49cdfc7eSAndroid Build Coastguard Worker .msg = "mremap #2",
112*49cdfc7eSAndroid Build Coastguard Worker .setup = setup4,
113*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup1},
114*49cdfc7eSAndroid Build Coastguard Worker };
115*49cdfc7eSAndroid Build Coastguard Worker
116*49cdfc7eSAndroid Build Coastguard Worker static int pagesize;
117*49cdfc7eSAndroid Build Coastguard Worker static int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);
118*49cdfc7eSAndroid Build Coastguard Worker
free_test_area(void * p,int size)119*49cdfc7eSAndroid Build Coastguard Worker static void free_test_area(void *p, int size)
120*49cdfc7eSAndroid Build Coastguard Worker {
121*49cdfc7eSAndroid Build Coastguard Worker SAFE_MUNMAP(cleanup, p, size);
122*49cdfc7eSAndroid Build Coastguard Worker }
123*49cdfc7eSAndroid Build Coastguard Worker
get_test_area(int size,int free_area)124*49cdfc7eSAndroid Build Coastguard Worker static void *get_test_area(int size, int free_area)
125*49cdfc7eSAndroid Build Coastguard Worker {
126*49cdfc7eSAndroid Build Coastguard Worker void *p;
127*49cdfc7eSAndroid Build Coastguard Worker p = mmap(NULL, size, PROT_READ | PROT_WRITE,
128*49cdfc7eSAndroid Build Coastguard Worker MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
129*49cdfc7eSAndroid Build Coastguard Worker if (p == MAP_FAILED)
130*49cdfc7eSAndroid Build Coastguard Worker tst_brkm(TBROK | TERRNO, cleanup, "get_test_area mmap");
131*49cdfc7eSAndroid Build Coastguard Worker if (free_area)
132*49cdfc7eSAndroid Build Coastguard Worker free_test_area(p, size);
133*49cdfc7eSAndroid Build Coastguard Worker return p;
134*49cdfc7eSAndroid Build Coastguard Worker }
135*49cdfc7eSAndroid Build Coastguard Worker
test_mremap(struct test_case_t * t)136*49cdfc7eSAndroid Build Coastguard Worker static void test_mremap(struct test_case_t *t)
137*49cdfc7eSAndroid Build Coastguard Worker {
138*49cdfc7eSAndroid Build Coastguard Worker t->ret = mremap(t->old_address, t->old_size, t->new_size, t->flags,
139*49cdfc7eSAndroid Build Coastguard Worker t->new_address);
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker if (t->ret == t->exp_ret) {
142*49cdfc7eSAndroid Build Coastguard Worker if (t->ret != MAP_FAILED) {
143*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "%s", t->msg);
144*49cdfc7eSAndroid Build Coastguard Worker if (*(t->ret) == 0x1)
145*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "%s value OK", t->msg);
146*49cdfc7eSAndroid Build Coastguard Worker else
147*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "%s value failed", t->msg);
148*49cdfc7eSAndroid Build Coastguard Worker } else {
149*49cdfc7eSAndroid Build Coastguard Worker if (errno == t->exp_errno)
150*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TPASS, "%s", t->msg);
151*49cdfc7eSAndroid Build Coastguard Worker else
152*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL | TERRNO, "%s", t->msg);
153*49cdfc7eSAndroid Build Coastguard Worker }
154*49cdfc7eSAndroid Build Coastguard Worker } else {
155*49cdfc7eSAndroid Build Coastguard Worker tst_resm(TFAIL, "%s ret: %p, expected: %p", t->msg,
156*49cdfc7eSAndroid Build Coastguard Worker t->ret, t->exp_ret);
157*49cdfc7eSAndroid Build Coastguard Worker }
158*49cdfc7eSAndroid Build Coastguard Worker }
159*49cdfc7eSAndroid Build Coastguard Worker
setup0(struct test_case_t * t)160*49cdfc7eSAndroid Build Coastguard Worker static void setup0(struct test_case_t *t)
161*49cdfc7eSAndroid Build Coastguard Worker {
162*49cdfc7eSAndroid Build Coastguard Worker t->old_address = get_test_area(t->old_size * pagesize, 0);
163*49cdfc7eSAndroid Build Coastguard Worker t->new_address = get_test_area(t->new_size * pagesize, 1);
164*49cdfc7eSAndroid Build Coastguard Worker }
165*49cdfc7eSAndroid Build Coastguard Worker
setup1(struct test_case_t * t)166*49cdfc7eSAndroid Build Coastguard Worker static void setup1(struct test_case_t *t)
167*49cdfc7eSAndroid Build Coastguard Worker {
168*49cdfc7eSAndroid Build Coastguard Worker t->old_address = get_test_area(t->old_size * pagesize, 0);
169*49cdfc7eSAndroid Build Coastguard Worker t->new_address = get_test_area((t->new_size + 1) * pagesize, 1) + 1;
170*49cdfc7eSAndroid Build Coastguard Worker }
171*49cdfc7eSAndroid Build Coastguard Worker
setup2(struct test_case_t * t)172*49cdfc7eSAndroid Build Coastguard Worker static void setup2(struct test_case_t *t)
173*49cdfc7eSAndroid Build Coastguard Worker {
174*49cdfc7eSAndroid Build Coastguard Worker t->old_address = get_test_area(t->old_size * pagesize, 0);
175*49cdfc7eSAndroid Build Coastguard Worker t->new_address = t->old_address;
176*49cdfc7eSAndroid Build Coastguard Worker }
177*49cdfc7eSAndroid Build Coastguard Worker
setup3(struct test_case_t * t)178*49cdfc7eSAndroid Build Coastguard Worker static void setup3(struct test_case_t *t)
179*49cdfc7eSAndroid Build Coastguard Worker {
180*49cdfc7eSAndroid Build Coastguard Worker t->old_address = get_test_area(t->old_size * pagesize, 0);
181*49cdfc7eSAndroid Build Coastguard Worker t->new_address = get_test_area(t->new_size * pagesize, 1);
182*49cdfc7eSAndroid Build Coastguard Worker t->exp_ret = t->new_address;
183*49cdfc7eSAndroid Build Coastguard Worker *(t->old_address) = 0x1;
184*49cdfc7eSAndroid Build Coastguard Worker }
185*49cdfc7eSAndroid Build Coastguard Worker
setup4(struct test_case_t * t)186*49cdfc7eSAndroid Build Coastguard Worker static void setup4(struct test_case_t *t)
187*49cdfc7eSAndroid Build Coastguard Worker {
188*49cdfc7eSAndroid Build Coastguard Worker t->old_address = get_test_area(t->old_size * pagesize, 0);
189*49cdfc7eSAndroid Build Coastguard Worker t->new_address = get_test_area(t->new_size * pagesize, 0);
190*49cdfc7eSAndroid Build Coastguard Worker t->exp_ret = t->new_address;
191*49cdfc7eSAndroid Build Coastguard Worker *(t->old_address) = 0x1;
192*49cdfc7eSAndroid Build Coastguard Worker *(t->new_address) = 0x2;
193*49cdfc7eSAndroid Build Coastguard Worker }
194*49cdfc7eSAndroid Build Coastguard Worker
cleanup0(struct test_case_t * t)195*49cdfc7eSAndroid Build Coastguard Worker static void cleanup0(struct test_case_t *t)
196*49cdfc7eSAndroid Build Coastguard Worker {
197*49cdfc7eSAndroid Build Coastguard Worker if (t->ret == MAP_FAILED)
198*49cdfc7eSAndroid Build Coastguard Worker free_test_area(t->old_address, t->old_size * pagesize);
199*49cdfc7eSAndroid Build Coastguard Worker else
200*49cdfc7eSAndroid Build Coastguard Worker free_test_area(t->ret, t->new_size * pagesize);
201*49cdfc7eSAndroid Build Coastguard Worker }
202*49cdfc7eSAndroid Build Coastguard Worker
cleanup1(struct test_case_t * t)203*49cdfc7eSAndroid Build Coastguard Worker static void cleanup1(struct test_case_t *t)
204*49cdfc7eSAndroid Build Coastguard Worker {
205*49cdfc7eSAndroid Build Coastguard Worker if (t->ret == MAP_FAILED) {
206*49cdfc7eSAndroid Build Coastguard Worker free_test_area(t->old_address, t->old_size * pagesize);
207*49cdfc7eSAndroid Build Coastguard Worker free_test_area(t->new_address, t->new_size * pagesize);
208*49cdfc7eSAndroid Build Coastguard Worker } else {
209*49cdfc7eSAndroid Build Coastguard Worker free_test_area(t->ret, t->new_size * pagesize);
210*49cdfc7eSAndroid Build Coastguard Worker }
211*49cdfc7eSAndroid Build Coastguard Worker }
212*49cdfc7eSAndroid Build Coastguard Worker
main(int ac,char ** av)213*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char **av)
214*49cdfc7eSAndroid Build Coastguard Worker {
215*49cdfc7eSAndroid Build Coastguard Worker int lc, testno;
216*49cdfc7eSAndroid Build Coastguard Worker
217*49cdfc7eSAndroid Build Coastguard Worker tst_parse_opts(ac, av, NULL, NULL);
218*49cdfc7eSAndroid Build Coastguard Worker
219*49cdfc7eSAndroid Build Coastguard Worker setup();
220*49cdfc7eSAndroid Build Coastguard Worker for (lc = 0; TEST_LOOPING(lc); lc++) {
221*49cdfc7eSAndroid Build Coastguard Worker tst_count = 0;
222*49cdfc7eSAndroid Build Coastguard Worker for (testno = 0; testno < TST_TOTAL; testno++) {
223*49cdfc7eSAndroid Build Coastguard Worker tdat[testno].setup(&tdat[testno]);
224*49cdfc7eSAndroid Build Coastguard Worker test_mremap(&tdat[testno]);
225*49cdfc7eSAndroid Build Coastguard Worker tdat[testno].cleanup(&tdat[testno]);
226*49cdfc7eSAndroid Build Coastguard Worker }
227*49cdfc7eSAndroid Build Coastguard Worker }
228*49cdfc7eSAndroid Build Coastguard Worker cleanup();
229*49cdfc7eSAndroid Build Coastguard Worker tst_exit();
230*49cdfc7eSAndroid Build Coastguard Worker }
231*49cdfc7eSAndroid Build Coastguard Worker
setup(void)232*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
233*49cdfc7eSAndroid Build Coastguard Worker {
234*49cdfc7eSAndroid Build Coastguard Worker pagesize = getpagesize();
235*49cdfc7eSAndroid Build Coastguard Worker }
236*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)237*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
238*49cdfc7eSAndroid Build Coastguard Worker {
239*49cdfc7eSAndroid Build Coastguard Worker }
240