blob: 6064d6c434ad3a624be2521ac34fbb6dd5a9f033 [file] [log] [blame]
subrata_modakbf831b52007-10-25 14:20:10 +00001/*
2 * Copyright (C) Ricardo Salveti de Araujo, 2007
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
Wanlong Gaofed96412012-10-24 10:10:29 +080020 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
subrata_modakbf831b52007-10-25 14:20:10 +000022 */
23
24/*
25 * NAME
26 * remap_file_pages02
27 *
28 * DESCRIPTION
29 * The remap_file_pages() system call is used to create a non-linear
30 * mapping, that is, a mapping in which the pages of the file are mapped
31 * into a non-sequential order in memory. The advantage of using
32 * remap_file_pages() over using repeated calls to mmap(2) is that
33 * the former approach does not require the kernel to create
34 * additional VMA (Virtual Memory Area) data structures.
35 *
36 * Runs remap_file_pages with wrong values and see if got the expected error
37 *
38 * Setup:
39 * 1. Global:
subrata_modak4bb656a2009-02-26 12:02:09 +000040 * 2. Create a file, do a normal mmap with MAP_SHARED flag
subrata_modakbf831b52007-10-25 14:20:10 +000041 *
42 * Test:
43 * 1. Test with a valid mmap but without MAP_SHARED flag
44 * 2. Test with a invalid start argument
45 * 3. Test with a invalid size argument
46 * 4. Test with a invalid prot argument
subrata_modakbf831b52007-10-25 14:20:10 +000047 *
48 * Cleanup:
49 * Remove the file and erase the tmp directory
50 *
51 * Usage: <for command-line>
52 * remap_file_pages02 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
53 * where, -c n : Run n copies concurrently.
54 * -f : Turn off functionality Testing.
55 * -i n : Execute test n times.
56 * -I x : Execute test for x seconds.
57 * -P x : Pause for x seconds between iterations.
58 * -t : Turn on syscall timing.
59 *
60 * HISTORY
61 *
subrata_modak98507592008-02-14 09:20:38 +000062 * 02/11/2008 - Removed the pgoff test case, as the latest kernels doesn't
63 * verify the page offset (http://lkml.org/lkml/2007/11/29/325) - Ricardo
64 * Salveti de Araujo, <rsalvetidev@gmail.com>
subrata_modak4bb656a2009-02-26 12:02:09 +000065 *
subrata_modakbf831b52007-10-25 14:20:10 +000066 * 19/10/2007 - Created by Ricardo Salveti de Araujo, <rsalvetidev@gmail.com>
67 */
68
69#define _GNU_SOURCE
70#include <sys/mman.h>
71#include <sys/types.h>
72#include <sys/stat.h>
73#include <fcntl.h>
74#include <stdio.h>
75#include <unistd.h>
76#include <errno.h>
77#include <syscall.h>
78#include <linux/unistd.h>
79
subrata_modak56207ce2009-03-23 13:35:39 +000080#include "test.h" /*LTP Specific Include File */
subrata_modakbf831b52007-10-25 14:20:10 +000081
82/* Test case defines */
83#define WINDOW_START 0x48000000
84
Zeng Linggang9d048f82015-01-29 18:20:45 +080085static int page_sz;
subrata_modakbf831b52007-10-25 14:20:10 +000086size_t page_words;
87size_t cache_pages;
88size_t cache_sz;
89size_t window_pages;
90size_t window_sz;
91
92static void setup();
93static int setup01(int test);
94static int setup02(int test);
95static int setup03(int test);
96static int setup04(int test);
subrata_modakbf831b52007-10-25 14:20:10 +000097static void cleanup();
98
Cyril Hrubisfdce7d52013-04-04 18:35:48 +020099char *TCID = "remap_file_pages02";
100int TST_TOTAL = 4;
subrata_modakbf831b52007-10-25 14:20:10 +0000101
102static char *cache_contents;
subrata_modak56207ce2009-03-23 13:35:39 +0000103int fd; /* File descriptor used at the test */
subrata_modakbf831b52007-10-25 14:20:10 +0000104char *data = NULL;
105char *data01 = NULL;
106
107static struct test_case_t {
subrata_modak56207ce2009-03-23 13:35:39 +0000108 char *err_desc; /* Error description */
109 int exp_errno; /* Expected error number */
110 char *exp_errval; /* Expected error value string */
111 int (*setupfunc) (int); /* Test setup function */
112 int (*cleanfunc) (int); /* Test clean function */
113 void *start; /* Start argument */
114 size_t size; /* Size argument */
115 int prot; /* Prot argument */
116 ssize_t pgoff; /* Pgoff argument */
117 int flags; /* Flags argument */
subrata_modakbf831b52007-10-25 14:20:10 +0000118} testcase[] = {
subrata_modak56207ce2009-03-23 13:35:39 +0000119 {
120 "start does not refer to a valid mapping created with the "
121 "MAP_SHARED flag", EINVAL, "EINVAL", setup01, NULL,
122 NULL, 0, 0, 2, 0}, {
123 "start is invalid", EINVAL, "EINVAL", setup02, NULL, NULL, 0, 0, 2, 0},
124 {
125 "size is invalid", EINVAL, "EINVAL", setup03, NULL, NULL, 0, 0, 0, 0},
126 {
127 "prot is invalid", EINVAL, "EINVAL", setup04, NULL, NULL, 0, 0,
128 2, 0}
subrata_modakbf831b52007-10-25 14:20:10 +0000129};
130
subrata_modak56207ce2009-03-23 13:35:39 +0000131int main(int ac, char **av)
subrata_modakbf831b52007-10-25 14:20:10 +0000132{
Cyril Hrubis89af32a2012-10-24 16:39:11 +0200133 int lc, i;
Cyril Hrubis0b9589f2014-05-27 17:40:33 +0200134 const char *msg;
subrata_modakbf831b52007-10-25 14:20:10 +0000135
subrata_modak631d20d2008-10-15 15:12:21 +0000136#if defined (__s390__) || (__s390x__) || (__ia64__)
subrata_modak56207ce2009-03-23 13:35:39 +0000137 /* Disables the test in case the kernel version is lower than 2.6.12 and arch is s390 */
138 if ((tst_kvercmp(2, 6, 12)) < 0) {
139 tst_resm(TWARN,
140 "This test can only run on kernels that are 2.6.12 and higher");
141 exit(0);
142 }
subrata_modak6aa34d02008-01-21 06:52:54 +0000143#endif
144
Garrett Coopera9e49f12010-12-16 10:54:03 -0800145 if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
Garrett Cooper60fa8012010-11-22 13:50:58 -0800146 tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
subrata_modakbf831b52007-10-25 14:20:10 +0000147
subrata_modakbf831b52007-10-25 14:20:10 +0000148 setup();
149
subrata_modakbf831b52007-10-25 14:20:10 +0000150 for (lc = 0; TEST_LOOPING(lc); lc++) {
151
Caspar Zhangd59a6592013-03-07 14:59:12 +0800152 tst_count = 0;
subrata_modakbf831b52007-10-25 14:20:10 +0000153
154 for (i = 0; i < TST_TOTAL; i++) {
155 /* do the setup if the test have one */
subrata_modak56207ce2009-03-23 13:35:39 +0000156 if (testcase[i].setupfunc
157 && testcase[i].setupfunc(i) == -1) {
158 tst_resm(TWARN,
159 "Failed to setup test %d"
160 " Skipping test", i);
subrata_modakbf831b52007-10-25 14:20:10 +0000161 continue;
162 }
163
164 /* run the test */
subrata_modak56207ce2009-03-23 13:35:39 +0000165 TEST(remap_file_pages
166 (testcase[i].start, testcase[i].size,
167 testcase[i].prot, testcase[i].pgoff,
168 testcase[i].flags));
subrata_modakbf831b52007-10-25 14:20:10 +0000169
170 /* do the cleanup if the test have one */
subrata_modak56207ce2009-03-23 13:35:39 +0000171 if (testcase[i].cleanfunc
172 && testcase[i].cleanfunc(i) == -1) {
173 tst_brkm(TBROK, cleanup,
174 "Failed to cleanup test %d,"
175 " quitting the test", i);
subrata_modakbf831b52007-10-25 14:20:10 +0000176 }
177
178 /* verify the return code */
subrata_modak56207ce2009-03-23 13:35:39 +0000179 if ((TEST_RETURN == -1)
180 && (TEST_ERRNO == testcase[i].exp_errno)) {
181 tst_resm(TPASS,
182 "remap_file_pages(2) expected failure;"
183 " Got errno - %s : %s",
184 testcase[i].exp_errval,
185 testcase[i].err_desc);
subrata_modakbf831b52007-10-25 14:20:10 +0000186 } else {
subrata_modak56207ce2009-03-23 13:35:39 +0000187 tst_resm(TFAIL,
188 "remap_file_pages(2) failed to produce"
189 " expected error: %d, errno: %s."
190 " because got error %d",
191 testcase[i].exp_errno,
192 testcase[i].exp_errval, TEST_ERRNO);
subrata_modakbf831b52007-10-25 14:20:10 +0000193 }
subrata_modak56207ce2009-03-23 13:35:39 +0000194 } /* end of test loops */
195 } /* end of test looping */
subrata_modakbf831b52007-10-25 14:20:10 +0000196
197 /* clean up and exit */
198 cleanup();
199
Garrett Cooper53740502010-12-16 00:04:01 -0800200 tst_exit();
subrata_modakbf831b52007-10-25 14:20:10 +0000201}
202
203/*
204 * setup01() - create a mmap area without MAP_SHARED flag
205 * - it uses the fd created at the main setup function
206 */
subrata_modak56207ce2009-03-23 13:35:39 +0000207int setup01(int test)
subrata_modakbf831b52007-10-25 14:20:10 +0000208{
subrata_modak56207ce2009-03-23 13:35:39 +0000209 data01 = mmap(NULL, cache_sz, PROT_READ | PROT_WRITE,
210 MAP_PRIVATE, fd, 0);
subrata_modakbf831b52007-10-25 14:20:10 +0000211
212 if (data01 == MAP_FAILED) {
subrata_modak56207ce2009-03-23 13:35:39 +0000213 tst_resm(TWARN, "mmap Error, errno=%d : %s", errno,
214 strerror(errno));
subrata_modakbf831b52007-10-25 14:20:10 +0000215 return -1;
216 }
217
218 /* set up the test case struct for this test */
219 testcase[test].start = data01;
220 testcase[test].size = page_sz;
221
222 return 0;
223}
224
225/*
226 * setup02() - start is invalid
227 */
subrata_modak56207ce2009-03-23 13:35:39 +0000228int setup02(int test)
subrata_modakbf831b52007-10-25 14:20:10 +0000229{
230 /* set up the test case struct for this test */
231 testcase[test].start = data + cache_sz;
232 testcase[test].size = page_sz;
233
234 return 0;
235}
236
237/*
238 * setup03() - size is invalid
239 */
subrata_modak56207ce2009-03-23 13:35:39 +0000240int setup03(int test)
subrata_modakbf831b52007-10-25 14:20:10 +0000241{
242 /* set up the test case struct for this test */
243 testcase[test].start = data;
244 testcase[test].size = cache_sz + page_sz;
245
246 return 0;
247}
248
249/*
250 * setup04() - prot is invalid
251 */
subrata_modak56207ce2009-03-23 13:35:39 +0000252int setup04(int test)
subrata_modakbf831b52007-10-25 14:20:10 +0000253{
254 /* set up the test case struct for this test */
255 testcase[test].start = data;
256 testcase[test].size = page_sz;
257 testcase[test].prot = -1;
258
259 return 0;
260}
261
262/*
subrata_modakbf831b52007-10-25 14:20:10 +0000263 * setup() - performs all ONE TIME setup for this test
264 * - creates a defaul mmaped area to be able to run remap_file_pages
265 */
Mike Frysingerc57fba52014-04-09 18:56:30 -0400266void setup(void)
subrata_modakbf831b52007-10-25 14:20:10 +0000267{
268 int i, j;
269
subrata_modakbf831b52007-10-25 14:20:10 +0000270 tst_sig(FORK, DEF_HANDLER, cleanup);
271
subrata_modakbf831b52007-10-25 14:20:10 +0000272 TEST_PAUSE;
273
subrata_modakbf831b52007-10-25 14:20:10 +0000274 tst_tmpdir();
275
276 /* Get page size */
277 if ((page_sz = getpagesize()) < 0) {
278 tst_brkm(TFAIL, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000279 "getpagesize() fails to get system page size");
subrata_modakbf831b52007-10-25 14:20:10 +0000280 }
281
subrata_modak56207ce2009-03-23 13:35:39 +0000282 page_words = (page_sz / sizeof(char));
subrata_modakbf831b52007-10-25 14:20:10 +0000283
284 /* Set the cache size */
285 cache_pages = 32;
subrata_modak56207ce2009-03-23 13:35:39 +0000286 cache_sz = cache_pages * page_sz;
Cyril Hrubisd218f342014-09-23 13:14:56 +0200287 cache_contents = malloc(cache_sz * sizeof(char));
subrata_modakbf831b52007-10-25 14:20:10 +0000288
289 for (i = 0; i < cache_pages; i++) {
subrata_modak56207ce2009-03-23 13:35:39 +0000290 char *page = cache_contents + i * page_sz;
subrata_modakbf831b52007-10-25 14:20:10 +0000291
292 for (j = 0; j < page_words; j++)
293 page[j] = i;
294 }
295
subrata_modak56207ce2009-03-23 13:35:39 +0000296 if ((fd = open("cache", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU)) < 0) {
subrata_modakbf831b52007-10-25 14:20:10 +0000297 tst_brkm(TBROK, cleanup,
subrata_modak56207ce2009-03-23 13:35:39 +0000298 "open(%s, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU) Failed, errno=%d : %s",
299 "cache", errno, strerror(errno));
subrata_modakbf831b52007-10-25 14:20:10 +0000300 }
301
302 if (write(fd, cache_contents, cache_sz) != cache_sz) {
subrata_modak56207ce2009-03-23 13:35:39 +0000303 tst_resm(TFAIL,
Markos Chandrasf4539c62012-01-03 09:41:10 +0000304 "Write Error for \"cache_contents\" to \"cache_sz\" of %zu (errno=%d : %s)",
subrata_modak56207ce2009-03-23 13:35:39 +0000305 cache_sz, errno, strerror(errno));
subrata_modakbf831b52007-10-25 14:20:10 +0000306 cleanup();
307 }
308
309 data = mmap((void *)WINDOW_START,
Wanlong Gao354ebb42012-12-07 10:10:04 +0800310 cache_sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
subrata_modakbf831b52007-10-25 14:20:10 +0000311
312 if (data == MAP_FAILED) {
subrata_modak56207ce2009-03-23 13:35:39 +0000313 tst_resm(TFAIL, "mmap Error, errno=%d : %s", errno,
314 strerror(errno));
subrata_modakbf831b52007-10-25 14:20:10 +0000315 cleanup();
316 }
317
Garrett Cooper2c282152010-12-16 00:55:50 -0800318}
subrata_modakbf831b52007-10-25 14:20:10 +0000319
320/*
321* cleanup() - Performs one time cleanup for this test at
322* completion or premature exit
323*/
Mike Frysingerc57fba52014-04-09 18:56:30 -0400324void cleanup(void)
subrata_modakbf831b52007-10-25 14:20:10 +0000325{
326 /* Close the file descriptor */
327 close(fd);
328
subrata_modak8b2171f2008-02-26 07:52:26 +0000329 if (data)
subrata_modak56207ce2009-03-23 13:35:39 +0000330 munmap(data, cache_sz);
subrata_modak8b2171f2008-02-26 07:52:26 +0000331 if (data01)
subrata_modak56207ce2009-03-23 13:35:39 +0000332 munmap(data01, cache_sz);
subrata_modak8b2171f2008-02-26 07:52:26 +0000333
subrata_modakbf831b52007-10-25 14:20:10 +0000334 tst_rmdir();
335
Markos Chandrasf4539c62012-01-03 09:41:10 +0000336}