blob: bed20510e8b30e171919066ec21559dfb5a4d0b5 [file] [log] [blame]
Brad Bishop1a4b7ee2018-12-16 17:11:34 -08001From c7b375747cffb627d02543d946b28525455d7d46 Mon Sep 17 00:00:00 2001
2From: "Hongzhi.Song" <hongzhi.song@windriver.com>
3Date: Fri, 13 Jul 2018 06:06:19 -0700
4Subject: [PATCH] vm: add some funtions to support musl libc
5
6Signed-off-by: Hongzhi.Song <hongzhi.song@windriver.com>
7---
8 tools/testing/selftests/vm/userfaultfd.c | 298 +++++++++++++++++++++++++++++++
9 1 file changed, 298 insertions(+)
10
11diff --git a/tools/testing/selftests/vm/userfaultfd.c b/tools/testing/selftests/vm/userfaultfd.c
12index de2f9ec..dc73021 100644
13--- a/tools/testing/selftests/vm/userfaultfd.c
14+++ b/tools/testing/selftests/vm/userfaultfd.c
15@@ -71,6 +71,304 @@
16
17 #ifdef __NR_userfaultfd
18
19+/* Linear congruential. */
20+#define TYPE_0 0
21+#define BREAK_0 8
22+#define DEG_0 0
23+#define SEP_0 0
24+
25+/* x**7 + x**3 + 1. */
26+#define TYPE_1 1
27+#define BREAK_1 32
28+#define DEG_1 7
29+#define SEP_1 3
30+
31+/* x**15 + x + 1. */
32+#define TYPE_2 2
33+#define BREAK_2 64
34+#define DEG_2 15
35+#define SEP_2 1
36+
37+/* x**31 + x**3 + 1. */
38+#define TYPE_3 3
39+#define BREAK_3 128
40+#define DEG_3 31
41+#define SEP_3 3
42+
43+/* x**63 + x + 1. */
44+#define TYPE_4 4
45+#define BREAK_4 256
46+#define DEG_4 63
47+#define SEP_4 1
48+
49+/* Array versions of the above information to make code run faster.
50+ Relies on fact that TYPE_i == i. */
51+
52+#define MAX_TYPES 5 /* Max number of types above. */
53+
54+#define __set_errno(val) (errno = (val))
55+
56+struct random_data
57+ {
58+ int32_t *fptr; /* Front pointer. */
59+ int32_t *rptr; /* Rear pointer. */
60+ int32_t *state; /* Array of state values. */
61+ int rand_type; /* Type of random number generator. */
62+ int rand_deg; /* Degree of random number generator. */
63+ int rand_sep; /* Distance between front and rear. */
64+ int32_t *end_ptr; /* Pointer behind state table. */
65+ };
66+
67+struct random_poly_info
68+{
69+ int seps[MAX_TYPES];
70+ int degrees[MAX_TYPES];
71+};
72+
73+static const struct random_poly_info random_poly_info =
74+{
75+ { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
76+ { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
77+};
78+
79+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
80+ congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
81+ same in all the other cases due to all the global variables that have been
82+ set up. The basic operation is to add the number at the rear pointer into
83+ the one at the front pointer. Then both pointers are advanced to the next
84+ location cyclically in the table. The value returned is the sum generated,
85+ reduced to 31 bits by throwing away the "least random" low bit.
86+ Note: The code takes advantage of the fact that both the front and
87+ rear pointers can't wrap on the same call by not testing the rear
88+ pointer if the front one has wrapped. Returns a 31-bit random number. */
89+
90+int random_r (struct random_data *buf, int32_t *result)
91+{
92+ int32_t *state;
93+
94+ if (buf == NULL || result == NULL)
95+ goto fail;
96+
97+ state = buf->state;
98+
99+ if (buf->rand_type == TYPE_0)
100+ {
101+ int32_t val = ((state[0] * 1103515245U) + 12345U) & 0x7fffffff;
102+ state[0] = val;
103+ *result = val;
104+ }
105+ else
106+ {
107+ int32_t *fptr = buf->fptr;
108+ int32_t *rptr = buf->rptr;
109+ int32_t *end_ptr = buf->end_ptr;
110+ uint32_t val;
111+
112+ val = *fptr += (uint32_t) *rptr;
113+ /* Chucking least random bit. */
114+ *result = val >> 1;
115+ ++fptr;
116+ if (fptr >= end_ptr)
117+ {
118+ fptr = state;
119+ ++rptr;
120+ }
121+ else
122+ {
123+ ++rptr;
124+ if (rptr >= end_ptr)
125+ rptr = state;
126+ }
127+ buf->fptr = fptr;
128+ buf->rptr = rptr;
129+ }
130+ return 0;
131+
132+ fail:
133+ __set_errno (EINVAL);
134+ return -1;
135+}
136+
137+/* Initialize the random number generator based on the given seed. If the
138+ type is the trivial no-state-information type, just remember the seed.
139+ Otherwise, initializes state[] based on the given "seed" via a linear
140+ congruential generator. Then, the pointers are set to known locations
141+ that are exactly rand_sep places apart. Lastly, it cycles the state
142+ information a given number of times to get rid of any initial dependencies
143+ introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
144+ for default usage relies on values produced by this routine. */
145+int srandom_r (unsigned int seed, struct random_data *buf)
146+{
147+ int type;
148+ int32_t *state;
149+ long int i;
150+ int32_t word;
151+ int32_t *dst;
152+ int kc;
153+
154+ if (buf == NULL)
155+ goto fail;
156+ type = buf->rand_type;
157+ if ((unsigned int) type >= MAX_TYPES)
158+ goto fail;
159+
160+ state = buf->state;
161+ /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
162+ if (seed == 0)
163+ seed = 1;
164+ state[0] = seed;
165+ if (type == TYPE_0)
166+ goto done;
167+
168+ dst = state;
169+ word = seed;
170+ kc = buf->rand_deg;
171+ for (i = 1; i < kc; ++i)
172+ {
173+ /* This does:
174+ state[i] = (16807 * state[i - 1]) % 2147483647;
175+ but avoids overflowing 31 bits. */
176+ long int hi = word / 127773;
177+ long int lo = word % 127773;
178+ word = 16807 * lo - 2836 * hi;
179+ if (word < 0)
180+ word += 2147483647;
181+ *++dst = word;
182+ }
183+
184+ buf->fptr = &state[buf->rand_sep];
185+ buf->rptr = &state[0];
186+ kc *= 10;
187+ while (--kc >= 0)
188+ {
189+ int32_t discard;
190+ (void) random_r (buf, &discard);
191+ }
192+
193+ done:
194+ return 0;
195+
196+ fail:
197+ return -1;
198+}
199+
200+/* Initialize the state information in the given array of N bytes for
201+ future random number generation. Based on the number of bytes we
202+ are given, and the break values for the different R.N.G.'s, we choose
203+ the best (largest) one we can and set things up for it. srandom is
204+ then called to initialize the state information. Note that on return
205+ from srandom, we set state[-1] to be the type multiplexed with the current
206+ value of the rear pointer; this is so successive calls to initstate won't
207+ lose this information and will be able to restart with setstate.
208+ Note: The first thing we do is save the current state, if any, just like
209+ setstate so that it doesn't matter when initstate is called.
210+ Returns 0 on success, non-zero on failure. */
211+int initstate_r (unsigned int seed, char *arg_state, size_t n,
212+ struct random_data *buf)
213+{
214+ if (buf == NULL)
215+ goto fail;
216+
217+ int32_t *old_state = buf->state;
218+ if (old_state != NULL)
219+ {
220+ int old_type = buf->rand_type;
221+ if (old_type == TYPE_0)
222+ old_state[-1] = TYPE_0;
223+ else
224+ old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
225+ }
226+
227+ int type;
228+ if (n >= BREAK_3)
229+ type = n < BREAK_4 ? TYPE_3 : TYPE_4;
230+ else if (n < BREAK_1)
231+ {
232+ if (n < BREAK_0)
233+ goto fail;
234+
235+ type = TYPE_0;
236+ }
237+ else
238+ type = n < BREAK_2 ? TYPE_1 : TYPE_2;
239+
240+ int degree = random_poly_info.degrees[type];
241+ int separation = random_poly_info.seps[type];
242+
243+ buf->rand_type = type;
244+ buf->rand_sep = separation;
245+ buf->rand_deg = degree;
246+ int32_t *state = &((int32_t *) arg_state)[1]; /* First location. */
247+ /* Must set END_PTR before srandom. */
248+ buf->end_ptr = &state[degree];
249+
250+ buf->state = state;
251+
252+ srandom_r (seed, buf);
253+
254+ state[-1] = TYPE_0;
255+ if (type != TYPE_0)
256+ state[-1] = (buf->rptr - state) * MAX_TYPES + type;
257+
258+ return 0;
259+
260+ fail:
261+ __set_errno (EINVAL);
262+ return -1;
263+}
264+
265+/* Restore the state from the given state array.
266+ Note: It is important that we also remember the locations of the pointers
267+ in the current state information, and restore the locations of the pointers
268+ from the old state information. This is done by multiplexing the pointer
269+ location into the zeroth word of the state information. Note that due
270+ to the order in which things are done, it is OK to call setstate with the
271+ same state as the current state
272+ Returns 0 on success, non-zero on failure. */
273+int setstate_r (char *arg_state, struct random_data *buf)
274+{
275+ int32_t *new_state = 1 + (int32_t *) arg_state;
276+ int type;
277+ int old_type;
278+ int32_t *old_state;
279+ int degree;
280+ int separation;
281+
282+ if (arg_state == NULL || buf == NULL)
283+ goto fail;
284+
285+ old_type = buf->rand_type;
286+ old_state = buf->state;
287+ if (old_type == TYPE_0)
288+ old_state[-1] = TYPE_0;
289+ else
290+ old_state[-1] = (MAX_TYPES * (buf->rptr - old_state)) + old_type;
291+
292+ type = new_state[-1] % MAX_TYPES;
293+ if (type < TYPE_0 || type > TYPE_4)
294+ goto fail;
295+
296+ buf->rand_deg = degree = random_poly_info.degrees[type];
297+ buf->rand_sep = separation = random_poly_info.seps[type];
298+ buf->rand_type = type;
299+
300+ if (type != TYPE_0)
301+ {
302+ int rear = new_state[-1] / MAX_TYPES;
303+ buf->rptr = &new_state[rear];
304+ buf->fptr = &new_state[(rear + separation) % degree];
305+ }
306+ buf->state = new_state;
307+ /* Set end_ptr too. */
308+ buf->end_ptr = &new_state[degree];
309+
310+ return 0;
311+
312+ fail:
313+ __set_errno (EINVAL);
314+ return -1;
315+}
316+
317 static unsigned long nr_cpus, nr_pages, nr_pages_per_cpu, page_size;
318
319 #define BOUNCE_RANDOM (1<<0)
320--
3212.11.0
322