Added address range library utility to be able to express whitelists
authorDavide Libenzi <dlibenzi@google.com>
Mon, 9 Nov 2015 23:10:44 +0000 (15:10 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 24 Nov 2015 20:39:04 +0000 (15:39 -0500)
Added address range library utility to be able to express whitelists for
MSR code, and potentially anything which can be expressed as address
range (ie, PCI, DMA, ...).

Signed-off-by: Davide Libenzi <dlibenzi@google.com>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/address_range.h [new file with mode: 0644]
kern/lib/Kbuild
kern/lib/address_range.c [new file with mode: 0644]

diff --git a/kern/include/address_range.h b/kern/include/address_range.h
new file mode 100644 (file)
index 0000000..c1ef3e4
--- /dev/null
@@ -0,0 +1,21 @@
+/* Copyright (c) 2015 Google Inc
+ * Davide Libenzi <dlibenzi@google.com>
+ * See LICENSE for details.
+ */
+
+#pragma once
+
+#include <sys/types.h>
+#include <stdio.h>
+
+#define ADDRESS_RANGE(s, e) { .start = (s), .end = (e) }
+
+struct address_range {
+       uintptr_t start;
+       uintptr_t end;
+};
+
+int address_range_validate(const struct address_range *ars, size_t count);
+int address_range_init(struct address_range *ars, size_t count);
+const struct address_range *address_range_find(const struct address_range *ars,
+                                                                                          size_t count, uintptr_t addr);
index 07bf43d..1e3281b 100644 (file)
@@ -1,3 +1,4 @@
+obj-y                                          += address_range.o
 obj-y                                          += sort.o
 obj-y                                          += zlib_deflate/
 obj-y                                          += zlib_inflate/
diff --git a/kern/lib/address_range.c b/kern/lib/address_range.c
new file mode 100644 (file)
index 0000000..6e63589
--- /dev/null
@@ -0,0 +1,55 @@
+/* Copyright (c) 2015 Google Inc
+ * Davide Libenzi <dlibenzi@google.com>
+ * See LICENSE for details.
+ */
+
+#include <ros/errno.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <sort.h>
+#include <address_range.h>
+
+static int address_range_cmp(const void *f1, const void *f2)
+{
+       return ((const struct address_range *) f1)->start <
+               ((const struct address_range *) f2)->start ? -1 : 1;
+}
+
+int address_range_validate(const struct address_range *ars, size_t count)
+{
+       for (size_t i = 0; i < count; i++) {
+               if (ars[i].start > ars[i].end)
+                       return -EINVAL;
+               if ((i > 0) && (ars[i - 1].end >= ars[i].start))
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+int address_range_init(struct address_range *ars, size_t count)
+{
+       sort(ars, count, sizeof(*ars), address_range_cmp);
+
+       return address_range_validate(ars, count);
+}
+
+const struct address_range *address_range_find(const struct address_range *ars,
+                                                                                          size_t count, uintptr_t addr)
+{
+       ssize_t l = 0, r = count - 1;
+
+       while (l <= r) {
+               ssize_t x = l + (r - l) / 2;
+               const struct address_range *car = ars + x;
+
+               if (car->end < addr)
+                       l = x + 1;
+               else if (car->start > addr)
+                       r = x - 1;
+               else
+                       return car;
+       }
+
+       return NULL;
+}