aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2019-01-16 11:28:49 -0800
committerSami Tolvanen <samitolvanen@google.com>2019-01-23 15:06:27 -0800
commit046daa57dd626d70a334e3210566c0eb6b515176 (patch)
tree05052f5c419e8d0b47d782f050e1def7f504d374
parentf9b2849005dae73b1814ffdecdb9af792c83af59 (diff)
ANDROID: cfi: fix shadow rebasing
If the module area base address changes when loading a new module, the new CFI shadow will only cover the first allocated page for each existing module. This will cause cross-DSO look-ups to functions elsewhere in the module to fall back to a red-black tree, which may be slower. Bug: 122963951 Change-Id: I9262034d39351afcd42590ead8d6384fc30a8ce8 Reported-by: Wu,Le <wule01@baidu.com> Signed-off-by: Sami Tolvanen <samitolvanen@google.com>
-rw-r--r--kernel/cfi.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/kernel/cfi.c b/kernel/cfi.c
index 6951c25d311b..b29bdaf8c566 100644
--- a/kernel/cfi.c
+++ b/kernel/cfi.c
@@ -87,6 +87,14 @@ static inline unsigned long shadow_to_ptr(const struct cfi_shadow *s,
return (s->r.min_page + s->shadow[index]) << PAGE_SHIFT;
}
+static inline unsigned long shadow_to_page(const struct cfi_shadow *s,
+ int index)
+{
+ BUG_ON(index < 0 || index >= SHADOW_SIZE);
+
+ return (s->r.min_page + index) << PAGE_SHIFT;
+}
+
static void prepare_next_shadow(const struct cfi_shadow __rcu *prev,
struct cfi_shadow *next)
{
@@ -109,7 +117,7 @@ static void prepare_next_shadow(const struct cfi_shadow __rcu *prev,
if (prev->shadow[i] == SHADOW_INVALID)
continue;
- index = ptr_to_shadow(next, shadow_to_ptr(prev, i));
+ index = ptr_to_shadow(next, shadow_to_page(prev, i));
if (index < 0)
continue;