diff options
-rw-r--r-- | arch/arm64/include/asm/app_api.h | 7 | ||||
-rw-r--r-- | arch/arm64/kernel/app_api.c | 35 | ||||
-rw-r--r-- | arch/arm64/kernel/app_setting.c | 15 | ||||
-rw-r--r-- | kernel/sched/core.c | 3 |
4 files changed, 60 insertions, 0 deletions
diff --git a/arch/arm64/include/asm/app_api.h b/arch/arm64/include/asm/app_api.h index 2162400fde13..7032d636dab6 100644 --- a/arch/arm64/include/asm/app_api.h +++ b/arch/arm64/include/asm/app_api.h @@ -27,16 +27,23 @@ #ifdef CONFIG_MSM_APP_API extern void set_app_setting_bit(uint32_t bit); extern void clear_app_setting_bit(uint32_t bit); +extern void set_app_setting_bit_for_32bit_apps(void); +extern void clear_app_setting_bit_for_32bit_apps(void); #else static inline void set_app_setting_bit(uint32_t bit) {} static inline void clear_app_setting_bit(uint32_t bit) {} +static inline void set_app_setting_bit_for_32bit_apps(void) {} +static inline void clear_app_setting_bit_for_32bit_apps(void) {} #endif #ifdef CONFIG_MSM_APP_SETTINGS extern void switch_app_setting_bit(struct task_struct *prev, struct task_struct *next); +extern void switch_32bit_app_setting_bit(struct task_struct *prev, + struct task_struct *next); extern void apply_app_setting_bit(struct file *file); extern bool use_app_setting; +extern bool use_32bit_app_setting; #endif #endif 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; diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 699008696da8..d6e7a1d7168d 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2729,6 +2729,9 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev, #ifdef CONFIG_MSM_APP_SETTINGS if (use_app_setting) switch_app_setting_bit(prev, next); + + if (use_32bit_app_setting) + switch_32bit_app_setting_bit(prev, next); #endif } |