summaryrefslogtreecommitdiff
path: root/arch/arm64/kernel
diff options
context:
space:
mode:
authorImran Khan <kimran@codeaurora.org>2016-08-17 21:18:14 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-03-27 03:07:55 -0700
commit9d7f377c60108b2bec037de6dc3bc3d195bb66b2 (patch)
tree2dfbd116135b0d8eff5cfc5d371f3278c3be8a0a /arch/arm64/kernel
parentbff1ef9f135ce782fe59a3596fa80e4cccdadb9c (diff)
arm64: Add support for 32 bit app specific settings
Add support to enable app specific settings, whenever a 32 bit application is running. Change-Id: I0cf40e8ea6e3f9e62258a44ccdd959e9eae09d88 Signed-off-by: Imran Khan <kimran@codeaurora.org>
Diffstat (limited to 'arch/arm64/kernel')
-rw-r--r--arch/arm64/kernel/app_api.c35
-rw-r--r--arch/arm64/kernel/app_setting.c15
2 files changed, 50 insertions, 0 deletions
diff --git a/arch/arm64/kernel/app_api.c b/arch/arm64/kernel/app_api.c
index 39eeee1a9029..1b3732accd4b 100644
--- a/arch/arm64/kernel/app_api.c
+++ b/arch/arm64/kernel/app_api.c
@@ -18,6 +18,7 @@
#include <asm/app_api.h>
static spinlock_t spinlock;
+static spinlock_t spinlock_32bit_app;
static DEFINE_PER_CPU(int, app_config_applied);
static unsigned long app_config_set[NR_CPUS];
static unsigned long app_config_clear[NR_CPUS];
@@ -67,9 +68,43 @@ void clear_app_setting_bit(uint32_t bit)
}
EXPORT_SYMBOL(clear_app_setting_bit);
+void set_app_setting_bit_for_32bit_apps(void)
+{
+ unsigned long flags;
+ uint64_t reg;
+
+ spin_lock_irqsave(&spinlock_32bit_app, flags);
+ asm volatile("mrs %0, S3_0_c15_c15_1 " : "=r" (reg));
+ reg = reg | BIT(18);
+ reg = reg & ~BIT(2);
+ reg = reg | 0x3;
+ isb();
+ asm volatile("msr S3_0_c15_c15_1, %0" : : "r" (reg));
+ isb();
+ spin_unlock_irqrestore(&spinlock_32bit_app, flags);
+}
+EXPORT_SYMBOL(set_app_setting_bit_for_32bit_apps);
+
+void clear_app_setting_bit_for_32bit_apps(void)
+{
+ unsigned long flags;
+ uint64_t reg;
+
+ spin_lock_irqsave(&spinlock_32bit_app, flags);
+ asm volatile("mrs %0, S3_0_c15_c15_1 " : "=r" (reg));
+ reg = reg & ~BIT(18);
+ reg = reg & ~0x3;
+ isb();
+ asm volatile("msr S3_0_c15_c15_1, %0" : : "r" (reg));
+ isb();
+ spin_unlock_irqrestore(&spinlock_32bit_app, flags);
+}
+EXPORT_SYMBOL(clear_app_setting_bit_for_32bit_apps);
+
static int __init init_app_api(void)
{
spin_lock_init(&spinlock);
+ spin_lock_init(&spinlock_32bit_app);
return 0;
}
early_initcall(init_app_api);
diff --git a/arch/arm64/kernel/app_setting.c b/arch/arm64/kernel/app_setting.c
index 6b4eb28d0e24..8e7aeab39edd 100644
--- a/arch/arm64/kernel/app_setting.c
+++ b/arch/arm64/kernel/app_setting.c
@@ -35,6 +35,10 @@ bool use_app_setting = true;
module_param(use_app_setting, bool, 0644);
MODULE_PARM_DESC(use_app_setting, "control use of app specific settings");
+bool use_32bit_app_setting = true;
+module_param(use_32bit_app_setting, bool, 0644);
+MODULE_PARM_DESC(use_32bit_app_setting, "control use of 32 bit app specific settings");
+
static int set_name(const char *str, struct kernel_param *kp)
{
int len = strlen(str);
@@ -87,6 +91,17 @@ void switch_app_setting_bit(struct task_struct *prev, struct task_struct *next)
}
EXPORT_SYMBOL(switch_app_setting_bit);
+void switch_32bit_app_setting_bit(struct task_struct *prev,
+ struct task_struct *next)
+{
+ if (prev->mm && unlikely(is_compat_thread(task_thread_info(prev))))
+ clear_app_setting_bit_for_32bit_apps();
+
+ if (next->mm && unlikely(is_compat_thread(task_thread_info(next))))
+ set_app_setting_bit_for_32bit_apps();
+}
+EXPORT_SYMBOL(switch_32bit_app_setting_bit);
+
void apply_app_setting_bit(struct file *file)
{
bool found = false;