|
@@ -2119,6 +2119,39 @@ randomize_range(unsigned long start, unsigned long end, unsigned long len)
|
|
|
return PAGE_ALIGN(get_random_int() % range + start);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * randomize_page - Generate a random, page aligned address
|
|
|
+ * @start: The smallest acceptable address the caller will take.
|
|
|
+ * @range: The size of the area, starting at @start, within which the
|
|
|
+ * random address must fall.
|
|
|
+ *
|
|
|
+ * If @start + @range would overflow, @range is capped.
|
|
|
+ *
|
|
|
+ * NOTE: Historical use of randomize_range, which this replaces, presumed that
|
|
|
+ * @start was already page aligned. We now align it regardless.
|
|
|
+ *
|
|
|
+ * Return: A page aligned address within [start, start + range). On error,
|
|
|
+ * @start is returned.
|
|
|
+ */
|
|
|
+unsigned long
|
|
|
+randomize_page(unsigned long start, unsigned long range)
|
|
|
+{
|
|
|
+ if (!PAGE_ALIGNED(start)) {
|
|
|
+ range -= PAGE_ALIGN(start) - start;
|
|
|
+ start = PAGE_ALIGN(start);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (start > ULONG_MAX - range)
|
|
|
+ range = ULONG_MAX - start;
|
|
|
+
|
|
|
+ range >>= PAGE_SHIFT;
|
|
|
+
|
|
|
+ if (range == 0)
|
|
|
+ return start;
|
|
|
+
|
|
|
+ return start + (get_random_long() % range << PAGE_SHIFT);
|
|
|
+}
|
|
|
+
|
|
|
/* Interface for in-kernel drivers of true hardware RNGs.
|
|
|
* Those devices may produce endless random bits and will be throttled
|
|
|
* when our pool is full.
|