diff options
author | Balbir Singh <bsingharora@gmail.com> | 2016-08-10 12:02:29 +1000 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2016-08-12 09:55:15 +1000 |
commit | 233c68b378342cbf3d26fe72f6fe1e48eb15b122 (patch) | |
tree | 259da95b38e8c09d3d21b3eead59b400dfbb9884 /include | |
parent | f6df3f8ddabd3bc7859cf1ebd24a736223961446 (diff) | |
download | skiboot-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.h | 3 | ||||
-rw-r--r-- | include/opal-internal.h | 22 |
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 */ |