1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines  Corp., 2004
4f08c3bdfSopenharmony_ci * Copyright (c) Linux Test Project, 2004-2017
5f08c3bdfSopenharmony_ci *
6f08c3bdfSopenharmony_ci * Test Name: hugemmap01
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * Test Description:
9f08c3bdfSopenharmony_ci *  Verify that, mmap() succeeds when used to map a file in a hugetlbfs.
10f08c3bdfSopenharmony_ci *
11f08c3bdfSopenharmony_ci * Expected Result:
12f08c3bdfSopenharmony_ci *  mmap() should succeed returning the address of the hugetlb mapped region.
13f08c3bdfSopenharmony_ci *  The number of free huge pages should decrease.
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci * Test:
16f08c3bdfSopenharmony_ci *  Loop if the proper options are given.
17f08c3bdfSopenharmony_ci *  Execute system call
18f08c3bdfSopenharmony_ci *  Check return code, if system call failed (return=-1)
19f08c3bdfSopenharmony_ci *  Log the errno and Issue a FAIL message.
20f08c3bdfSopenharmony_ci *
21f08c3bdfSopenharmony_ci * HISTORY
22f08c3bdfSopenharmony_ci *  04/2004 Written by Robbie Williamson
23f08c3bdfSopenharmony_ci */
24f08c3bdfSopenharmony_ci
25f08c3bdfSopenharmony_ci#include <stdio.h>
26f08c3bdfSopenharmony_ci#include <sys/mount.h>
27f08c3bdfSopenharmony_ci#include <limits.h>
28f08c3bdfSopenharmony_ci#include <sys/param.h>
29f08c3bdfSopenharmony_ci#include "hugetlb.h"
30f08c3bdfSopenharmony_ci
31f08c3bdfSopenharmony_cistatic long *addr;
32f08c3bdfSopenharmony_cistatic int  fildes;
33f08c3bdfSopenharmony_cistatic long beforetest;
34f08c3bdfSopenharmony_cistatic long aftertest;
35f08c3bdfSopenharmony_cistatic long hugepagesmapped;
36f08c3bdfSopenharmony_cistatic char TEMPFILE[MAXPATHLEN];
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_cistatic void test_hugemmap(void)
39f08c3bdfSopenharmony_ci{
40f08c3bdfSopenharmony_ci	long page_sz = 0;
41f08c3bdfSopenharmony_ci
42f08c3bdfSopenharmony_ci	fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	beforetest = SAFE_READ_MEMINFO("HugePages_Free:");
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci	page_sz = SAFE_READ_MEMINFO("Hugepagesize:") * 1024;
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci	addr = mmap(NULL, page_sz, PROT_READ | PROT_WRITE,
49f08c3bdfSopenharmony_ci			MAP_SHARED, fildes, 0);
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ci	if (addr == MAP_FAILED) {
52f08c3bdfSopenharmony_ci		tst_res(TFAIL | TERRNO, "mmap() Failed on %s",
53f08c3bdfSopenharmony_ci				TEMPFILE);
54f08c3bdfSopenharmony_ci	} else {
55f08c3bdfSopenharmony_ci		tst_res(TPASS, "call succeeded");
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ci		/* force to allocate page and change HugePages_Free */
58f08c3bdfSopenharmony_ci		*(int *)addr = 0;
59f08c3bdfSopenharmony_ci		/* Make sure the number of free huge pages AFTER testing decreased */
60f08c3bdfSopenharmony_ci		aftertest = SAFE_READ_MEMINFO("HugePages_Free:");
61f08c3bdfSopenharmony_ci		hugepagesmapped = beforetest - aftertest;
62f08c3bdfSopenharmony_ci		if (hugepagesmapped < 1)
63f08c3bdfSopenharmony_ci			tst_res(TWARN, "Number of HUGEPAGES_FREE stayed the"
64f08c3bdfSopenharmony_ci					" same. Okay if multiple copies running due"
65f08c3bdfSopenharmony_ci					" to test collision.");
66f08c3bdfSopenharmony_ci		munmap(addr, page_sz);
67f08c3bdfSopenharmony_ci	}
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_ci	close(fildes);
70f08c3bdfSopenharmony_ci}
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_civoid setup(void)
73f08c3bdfSopenharmony_ci{
74f08c3bdfSopenharmony_ci	if (tst_hugepages == 0)
75f08c3bdfSopenharmony_ci		tst_brk(TCONF, "Not enough hugepages for testing.");
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci	if (!Hopt)
78f08c3bdfSopenharmony_ci		Hopt = tst_get_tmpdir();
79f08c3bdfSopenharmony_ci	SAFE_MOUNT("none", Hopt, "hugetlbfs", 0, NULL);
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_ci	snprintf(TEMPFILE, sizeof(TEMPFILE), "%s/mmapfile%d", Hopt, getpid());
82f08c3bdfSopenharmony_ci}
83f08c3bdfSopenharmony_ci
84f08c3bdfSopenharmony_civoid cleanup(void)
85f08c3bdfSopenharmony_ci{
86f08c3bdfSopenharmony_ci	unlink(TEMPFILE);
87f08c3bdfSopenharmony_ci	umount(Hopt);
88f08c3bdfSopenharmony_ci}
89f08c3bdfSopenharmony_ci
90f08c3bdfSopenharmony_cistatic struct tst_test test = {
91f08c3bdfSopenharmony_ci	.needs_root = 1,
92f08c3bdfSopenharmony_ci	.needs_tmpdir = 1,
93f08c3bdfSopenharmony_ci	.options = (struct tst_option[]) {
94f08c3bdfSopenharmony_ci		{"H:", &Hopt,   "Location of hugetlbfs, i.e.  -H /var/hugetlbfs"},
95f08c3bdfSopenharmony_ci		{"s:", &nr_opt, "Set the number of the been allocated hugepages"},
96f08c3bdfSopenharmony_ci		{}
97f08c3bdfSopenharmony_ci	},
98f08c3bdfSopenharmony_ci	.setup = setup,
99f08c3bdfSopenharmony_ci	.cleanup = cleanup,
100f08c3bdfSopenharmony_ci	.test_all = test_hugemmap,
101f08c3bdfSopenharmony_ci	.hugepages = {128, TST_REQUEST},
102f08c3bdfSopenharmony_ci};
103