1From 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
323