• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 /*
3  * Copyright (C) 2008 David Gibson, IBM Corporation.
4  * Author: David Gibson
5  */
6 
7 /*\
8  * [Description]
9  *
10  * This checks copy-on-write semantics, specifically the semantics of a
11  * MAP_PRIVATE mapping across a fork().  Some versions of the powerpc
12  * kernel had a bug in huge_ptep_set_wrprotect() which would fail to
13  * flush the hash table after setting the write protect bit in the parent's
14  * page tables, thus allowing the parent to pollute the child's mapping.
15  *
16  */
17 
18 #include <sys/wait.h>
19 #include <sys/mman.h>
20 #include <stdlib.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 
24 #include "hugetlb.h"
25 
26 #define C1		0x1234ABCD
27 #define C2		~0x1234ABCD
28 #define C3		0xfeef5678
29 #define MNTPOINT "hugetlbfs/"
30 static int  fd = -1;
31 static long hpage_size;
32 
run_test(void)33 static void run_test(void)
34 {
35 	volatile unsigned int *p;
36 	int parent_readback;
37 	pid_t pid;
38 
39 	p = SAFE_MMAP(NULL, hpage_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
40 	*p = C1;
41 
42 	pid = SAFE_FORK();
43 	if (pid != 0) {
44 		*p = C2;
45 		TST_CHECKPOINT_WAKE_AND_WAIT(0);
46 		parent_readback = *p;
47 		TST_CHECKPOINT_WAKE(0);
48 	} else {
49 		unsigned int child_readback = 0;
50 
51 		TST_CHECKPOINT_WAIT(0);
52 		child_readback = *p;
53 		*p = C3;
54 		TST_CHECKPOINT_WAKE_AND_WAIT(0);
55 		TST_EXP_EXPR(child_readback == C1, "0x%x == child_readback (0x%x)",
56 				C1, child_readback);
57 		exit(0);
58 	}
59 	tst_reap_children();
60 	TST_EXP_EXPR(parent_readback == C2, "0x%x == parent_readback (0x%x)",
61 			C2, parent_readback);
62 
63 	SAFE_MUNMAP((void *)p, hpage_size);
64 }
65 
setup(void)66 static void setup(void)
67 {
68 	hpage_size = SAFE_READ_MEMINFO("Hugepagesize:")*1024;
69 	fd = tst_creat_unlinked(MNTPOINT, 0);
70 }
71 
cleanup(void)72 static void cleanup(void)
73 {
74 	if (fd > 0)
75 		SAFE_CLOSE(fd);
76 }
77 
78 static struct tst_test test = {
79 	.tags = (struct tst_tag[]) {
80 		{"linux-git", "86df86424939"},
81 		{}
82 	},
83 	.needs_root = 1,
84 	.needs_checkpoints = 1,
85 	.mntpoint = MNTPOINT,
86 	.needs_hugetlbfs = 1,
87 	.forks_child = 1,
88 	.setup = setup,
89 	.cleanup = cleanup,
90 	.test_all = run_test,
91 	.hugepages = {2, TST_NEEDS},
92 };
93