aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBalbir Singh <bsingharora@gmail.com>2016-08-10 12:02:29 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2016-08-12 09:55:15 +1000
commit233c68b378342cbf3d26fe72f6fe1e48eb15b122 (patch)
tree259da95b38e8c09d3d21b3eead59b400dfbb9884 /include
parentf6df3f8ddabd3bc7859cf1ebd24a736223961446 (diff)
downloadskiboot-233c68b378342cbf3d26fe72f6fe1e48eb15b122.zip
skiboot-233c68b378342cbf3d26fe72f6fe1e48eb15b122.tar.gz
skiboot-233c68b378342cbf3d26fe72f6fe1e48eb15b122.tar.bz2
Add infrastructure for pointer validation.
If the kernel called an OPAL API with vmalloc'd address or any other address range in real mode, we would hit a problem with aliasing. Since the top 4 bits are ignored in real mode, pointers from 0xc.. and 0xd.. (and other ranges) could collide and lead to hard to solve bugs. This patch adds the infrastructure for pointer validation and a simple test case for testing the API Signed-off-by: Balbir Singh <bsingharora@gmail.com> [stewart@linux.vnet.ibm.com: move function to opal-internal.h rather than opal-api.h] Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'include')
-rw-r--r--include/opal-api.h3
-rw-r--r--include/opal-internal.h22
2 files changed, 25 insertions, 0 deletions
diff --git a/include/opal-api.h b/include/opal-api.h
index c86244b..7ba4e6d 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -213,6 +213,9 @@
#ifndef __ASSEMBLY__
+#include <stdbool.h>
+#include <types.h>
+
/* Other enums */
enum OpalVendorApiTokens {
OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999
diff --git a/include/opal-internal.h b/include/opal-internal.h
index 5e41e10..2faaa46 100644
--- a/include/opal-internal.h
+++ b/include/opal-internal.h
@@ -82,4 +82,26 @@ extern void opal_del_host_sync_notifier(bool (*notify)(void *data));
struct OpalHMIEvent;
extern int handle_hmi_exception(__be64 hmer, struct OpalHMIEvent *hmi_evt);
+extern unsigned long top_of_ram;
+
+/*
+ * Returns true if the address is valid, false otherwise
+ *
+ * Checks if the passed address belongs to real address space
+ * or 0xc000... kernel address space. It also checks that
+ * addr <= total physical memory. The magic value 60 comes
+ * from 60 bit real address mentioned in section 5.7 of the
+ * Power ISA (Book 3S).
+ */
+static inline bool opal_addr_valid(const void *addr)
+{
+ unsigned long val = (unsigned long)addr;
+ if ((val >> 60) != 0xc && (val >> 60) != 0x0)
+ return false;
+ val &= ~0xf000000000000000;
+ if (val > top_of_ram)
+ return false;
+ return true;
+}
+
#endif /* __OPAL_INTERNAL_H */