Merge "Revert "arm64: fpsimd: Enable FP(floating-point) settings for msm8996""

This commit is contained in:
Linux Build Service Account 2016-08-16 16:34:58 -07:00 committed by Gerrit - the friendly Code Review server
commit 1c37e5b693
15 changed files with 4 additions and 384 deletions

View file

@ -513,37 +513,6 @@ config ARM64_64K_PAGES
endchoice endchoice
config MSM_APP_API
bool "API support to enable / disable app settings for MSM8996"
depends on ARCH_MSM8996 && (ENABLE_FP_SIMD_SETTINGS || MSM_APP_SETTINGS)
help
Add API support to enable / disable the app settings to be used
at runtime. These APIs are used to enable / disable app setting
when specific aarch32 or aarch64 processes are running.
If you are not sure what to do, select 'N' here.
config ENABLE_FP_SIMD_SETTINGS
bool "Enable FP(Floating Point) Settings for Qualcomm MSM8996"
depends on ARCH_MSM8996
select MSM_APP_API
help
Enable FP(Floating Point) and SIMD settings for the MSM8996 during
the execution of the aarch32 processes and disable these settings
when you switch to the aarch64 processes.
If you are not sure what to do, select 'N' here.
config MSM_APP_SETTINGS
bool "Support to enable / disable app settings for MSM8996"
depends on ARCH_MSM8996
select MSM_APP_API
help
Expose an interface used by the userspace at runtime to
enable / disable the app specific settings.
If you are not sure what to do, select 'N' here.
choice choice
prompt "Virtual address space size" prompt "Virtual address space size"
default ARM64_VA_BITS_39 if ARM64_4K_PAGES default ARM64_VA_BITS_39 if ARM64_4K_PAGES

View file

@ -44,8 +44,6 @@ CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8996=y CONFIG_ARCH_MSM8996=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_PCI_MSM=y CONFIG_PCI_MSM=y
CONFIG_ENABLE_FP_SIMD_SETTINGS=y
CONFIG_MSM_APP_SETTINGS=y
CONFIG_SCHED_MC=y CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8 CONFIG_NR_CPUS=8
CONFIG_PREEMPT=y CONFIG_PREEMPT=y

View file

@ -41,8 +41,6 @@ CONFIG_ARCH_QCOM=y
CONFIG_ARCH_MSM8996=y CONFIG_ARCH_MSM8996=y
CONFIG_PCI=y CONFIG_PCI=y
CONFIG_PCI_MSM=y CONFIG_PCI_MSM=y
CONFIG_ENABLE_FP_SIMD_SETTINGS=y
CONFIG_MSM_APP_SETTINGS=y
CONFIG_SCHED_MC=y CONFIG_SCHED_MC=y
CONFIG_NR_CPUS=8 CONFIG_NR_CPUS=8
CONFIG_PREEMPT=y CONFIG_PREEMPT=y

View file

@ -1,42 +0,0 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __ASM_APP_API_H
#define __ASM_APP_API_H
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/fs.h>
#define APP_SETTING_BIT 30
#define MAX_ENTRIES 10
/*
* APIs to set / clear the app setting bits
* in the register.
*/
#ifdef CONFIG_MSM_APP_API
extern void set_app_setting_bit(uint32_t bit);
extern void clear_app_setting_bit(uint32_t bit);
#else
static inline void set_app_setting_bit(uint32_t bit) {}
static inline void clear_app_setting_bit(uint32_t bit) {}
#endif
#ifdef CONFIG_MSM_APP_SETTINGS
extern void switch_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;
#endif
#endif

View file

@ -23,7 +23,6 @@
*/ */
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/user.h> #include <asm/user.h>
#include <asm/fpsimd.h>
typedef unsigned long elf_greg_t; typedef unsigned long elf_greg_t;
@ -178,11 +177,7 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
((x)->e_flags & EF_ARM_EABI_MASK)) ((x)->e_flags & EF_ARM_EABI_MASK))
#define compat_start_thread compat_start_thread #define compat_start_thread compat_start_thread
#define COMPAT_SET_PERSONALITY(ex) \ #define COMPAT_SET_PERSONALITY(ex) set_thread_flag(TIF_32BIT);
do { \
set_thread_flag(TIF_32BIT); \
} while (0)
#define COMPAT_ARCH_DLINFO #define COMPAT_ARCH_DLINFO
extern int aarch32_setup_vectors_page(struct linux_binprm *bprm, extern int aarch32_setup_vectors_page(struct linux_binprm *bprm,
int uses_interp); int uses_interp);

View file

@ -81,14 +81,6 @@ extern void fpsimd_save_partial_state(struct fpsimd_partial_state *state,
u32 num_regs); u32 num_regs);
extern void fpsimd_load_partial_state(struct fpsimd_partial_state *state); extern void fpsimd_load_partial_state(struct fpsimd_partial_state *state);
#ifdef CONFIG_ENABLE_FP_SIMD_SETTINGS
extern void fpsimd_disable_trap(void);
extern void fpsimd_enable_trap(void);
#else
static inline void fpsimd_disable_trap(void) {}
static inline void fpsimd_enable_trap(void) {}
#endif
#endif #endif
#endif #endif

View file

@ -43,8 +43,6 @@ arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o
arm64-obj-$(CONFIG_PCI) += pci.o arm64-obj-$(CONFIG_PCI) += pci.o
arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
arm64-obj-$(CONFIG_ACPI) += acpi.o arm64-obj-$(CONFIG_ACPI) += acpi.o
arm64-obj-$(CONFIG_MSM_APP_API) += app_api.o
arm64-obj-$(CONFIG_MSM_APP_SETTINGS) += app_setting.o
obj-y += $(arm64-obj-y) vdso/ obj-y += $(arm64-obj-y) vdso/
obj-m += $(arm64-obj-m) obj-m += $(arm64-obj-m)

View file

@ -1,75 +0,0 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/bitops.h>
#include <linux/spinlock.h>
#include <linux/cpu.h>
#include <linux/export.h>
#include <asm/app_api.h>
static spinlock_t spinlock;
static DEFINE_PER_CPU(int, app_config_applied);
static unsigned long app_config_set[NR_CPUS];
static unsigned long app_config_clear[NR_CPUS];
void set_app_setting_bit(uint32_t bit)
{
unsigned long flags;
uint64_t reg;
int cpu;
spin_lock_irqsave(&spinlock, flags);
asm volatile("mrs %0, S3_1_C15_C15_0" : "=r" (reg));
reg = reg | BIT(bit);
isb();
asm volatile("msr S3_1_C15_C15_0, %0" : : "r" (reg));
isb();
if (bit == APP_SETTING_BIT) {
cpu = raw_smp_processor_id();
app_config_set[cpu]++;
this_cpu_write(app_config_applied, 1);
}
spin_unlock_irqrestore(&spinlock, flags);
}
EXPORT_SYMBOL(set_app_setting_bit);
void clear_app_setting_bit(uint32_t bit)
{
unsigned long flags;
uint64_t reg;
int cpu;
spin_lock_irqsave(&spinlock, flags);
asm volatile("mrs %0, S3_1_C15_C15_0" : "=r" (reg));
reg = reg & ~BIT(bit);
isb();
asm volatile("msr S3_1_C15_C15_0, %0" : : "r" (reg));
isb();
if (bit == APP_SETTING_BIT) {
cpu = raw_smp_processor_id();
app_config_clear[cpu]++;
this_cpu_write(app_config_applied, 0);
}
spin_unlock_irqrestore(&spinlock, flags);
}
EXPORT_SYMBOL(clear_app_setting_bit);
static int __init init_app_api(void)
{
spin_lock_init(&spinlock);
return 0;
}
early_initcall(init_app_api);

View file

@ -1,120 +0,0 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/notifier.h>
#include <asm/app_api.h>
#define MAX_LEN 100
static char *lib_names[MAX_ENTRIES];
static unsigned int count;
static struct mutex mutex;
static char lib_str[MAX_LEN] = "";
static struct kparam_string kps = {
.string = lib_str,
.maxlen = MAX_LEN,
};
static int set_name(const char *str, struct kernel_param *kp);
module_param_call(lib_name, set_name, param_get_string, &kps, S_IWUSR);
bool use_app_setting = true;
module_param(use_app_setting, bool, 0644);
MODULE_PARM_DESC(use_app_setting, "control use of app specific settings");
static int set_name(const char *str, struct kernel_param *kp)
{
int len = strlen(str);
char *name;
if (len >= MAX_LEN) {
pr_err("app_setting: name string too long\n");
return -ENOSPC;
}
/*
* echo adds '\n' which we need to chop off later
*/
name = kzalloc(len + 1, GFP_KERNEL);
if (!name)
return -ENOMEM;
strlcpy(name, str, len + 1);
if (name[len - 1] == '\n')
name[len - 1] = '\0';
mutex_lock(&mutex);
if (count < MAX_ENTRIES) {
lib_names[count] = name;
/*
* mb to ensure that the new lib_names entry is present
* before updating the view presented by get_lib_names
*/
mb();
count++;
} else {
pr_err("app_setting: set name failed. Max entries reached\n");
kfree(name);
mutex_unlock(&mutex);
return -EPERM;
}
mutex_unlock(&mutex);
return 0;
}
void switch_app_setting_bit(struct task_struct *prev, struct task_struct *next)
{
if (prev->mm && unlikely(prev->mm->app_setting))
clear_app_setting_bit(APP_SETTING_BIT);
if (next->mm && unlikely(next->mm->app_setting))
set_app_setting_bit(APP_SETTING_BIT);
}
EXPORT_SYMBOL(switch_app_setting_bit);
void apply_app_setting_bit(struct file *file)
{
bool found = false;
int i;
if (file && file->f_path.dentry) {
const char *name = file->f_path.dentry->d_name.name;
for (i = 0; i < count; i++) {
if (unlikely(!strcmp(name, lib_names[i]))) {
found = true;
break;
}
}
if (found) {
preempt_disable();
set_app_setting_bit(APP_SETTING_BIT);
/* This will take care of child processes as well */
current->mm->app_setting = 1;
preempt_enable();
}
}
}
EXPORT_SYMBOL(apply_app_setting_bit);
static int __init app_setting_init(void)
{
mutex_init(&mutex);
return 0;
}
module_init(app_setting_init);

View file

@ -64,20 +64,4 @@ ENTRY(fpsimd_load_partial_state)
ret ret
ENDPROC(fpsimd_load_partial_state) ENDPROC(fpsimd_load_partial_state)
#ifdef CONFIG_ENABLE_FP_SIMD_SETTINGS
ENTRY(fpsimd_enable_trap)
mrs x0, cpacr_el1
bic x0, x0, #(3 << 20)
orr x0, x0, #(1 << 20)
msr cpacr_el1, x0
ret
ENDPROC(fpsimd_enable_trap)
ENTRY(fpsimd_disable_trap)
mrs x0, cpacr_el1
orr x0, x0, #(3 << 20)
msr cpacr_el1, x0
ret
ENDPROC(fpsimd_disable_trap)
#endif
#endif #endif

View file

@ -427,7 +427,7 @@ el0_sync_compat:
cmp x24, #ESR_ELx_EC_IABT_LOW // instruction abort in EL0 cmp x24, #ESR_ELx_EC_IABT_LOW // instruction abort in EL0
b.eq el0_ia b.eq el0_ia
cmp x24, #ESR_ELx_EC_FP_ASIMD // FP/ASIMD access cmp x24, #ESR_ELx_EC_FP_ASIMD // FP/ASIMD access
b.eq el0_fpsimd_acc_compat b.eq el0_fpsimd_acc
cmp x24, #ESR_ELx_EC_FP_EXC32 // FP/ASIMD exception cmp x24, #ESR_ELx_EC_FP_EXC32 // FP/ASIMD exception
b.eq el0_fpsimd_exc b.eq el0_fpsimd_exc
cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception cmp x24, #ESR_ELx_EC_PC_ALIGN // pc alignment exception
@ -498,17 +498,6 @@ el0_fpsimd_acc:
mov x1, sp mov x1, sp
bl do_fpsimd_acc bl do_fpsimd_acc
b ret_to_user b ret_to_user
el0_fpsimd_acc_compat:
/*
* Floating Point or Advanced SIMD access
*/
enable_dbg
ct_user_exit
mov x0, x25
mov x1, sp
bl do_fpsimd_acc_compat
b ret_to_user
el0_fpsimd_exc: el0_fpsimd_exc:
/* /*
* Floating Point or Advanced SIMD exception * Floating Point or Advanced SIMD exception

View file

@ -20,7 +20,6 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpu_pm.h> #include <linux/cpu_pm.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/signal.h> #include <linux/signal.h>
@ -28,7 +27,6 @@
#include <asm/fpsimd.h> #include <asm/fpsimd.h>
#include <asm/cputype.h> #include <asm/cputype.h>
#include <asm/app_api.h>
#define FPEXC_IOF (1 << 0) #define FPEXC_IOF (1 << 0)
#define FPEXC_DZF (1 << 1) #define FPEXC_DZF (1 << 1)
@ -37,8 +35,6 @@
#define FPEXC_IXF (1 << 4) #define FPEXC_IXF (1 << 4)
#define FPEXC_IDF (1 << 7) #define FPEXC_IDF (1 << 7)
#define FP_SIMD_BIT 31
/* /*
* In order to reduce the number of times the FPSIMD state is needlessly saved * In order to reduce the number of times the FPSIMD state is needlessly saved
* and restored, we need to keep track of two things: * and restored, we need to keep track of two things:
@ -92,42 +88,14 @@
* whatever is in the FPSIMD registers is not saved to memory, but discarded. * whatever is in the FPSIMD registers is not saved to memory, but discarded.
*/ */
static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state); static DEFINE_PER_CPU(struct fpsimd_state *, fpsimd_last_state);
static DEFINE_PER_CPU(int, fpsimd_stg_enable);
static int fpsimd_settings = 0x1; /* default = 0x1 */
module_param(fpsimd_settings, int, 0644);
void fpsimd_settings_enable(void)
{
set_app_setting_bit(FP_SIMD_BIT);
}
void fpsimd_settings_disable(void)
{
clear_app_setting_bit(FP_SIMD_BIT);
}
/* /*
* Trapped FP/ASIMD access. * Trapped FP/ASIMD access.
*/ */
void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs) void do_fpsimd_acc(unsigned int esr, struct pt_regs *regs)
{ {
if (!fpsimd_settings) /* TODO: implement lazy context saving/restoring */
return; WARN_ON(1);
fpsimd_disable_trap();
fpsimd_settings_disable();
this_cpu_write(fpsimd_stg_enable, 0);
}
void do_fpsimd_acc_compat(unsigned int esr, struct pt_regs *regs)
{
if (!fpsimd_settings)
return;
fpsimd_disable_trap();
fpsimd_settings_enable();
this_cpu_write(fpsimd_stg_enable, 1);
} }
/* /*
@ -167,11 +135,6 @@ void fpsimd_thread_switch(struct task_struct *next)
if (current->mm && !test_thread_flag(TIF_FOREIGN_FPSTATE)) if (current->mm && !test_thread_flag(TIF_FOREIGN_FPSTATE))
fpsimd_save_state(&current->thread.fpsimd_state); fpsimd_save_state(&current->thread.fpsimd_state);
if (fpsimd_settings && __this_cpu_read(fpsimd_stg_enable)) {
fpsimd_settings_disable();
this_cpu_write(fpsimd_stg_enable, 0);
}
if (next->mm) { if (next->mm) {
/* /*
* If we are switching to a task whose most recent userland * If we are switching to a task whose most recent userland
@ -189,14 +152,6 @@ void fpsimd_thread_switch(struct task_struct *next)
else else
set_ti_thread_flag(task_thread_info(next), set_ti_thread_flag(task_thread_info(next),
TIF_FOREIGN_FPSTATE); TIF_FOREIGN_FPSTATE);
if (!fpsimd_settings)
return;
if (test_ti_thread_flag(task_thread_info(next), TIF_32BIT))
fpsimd_enable_trap();
else
fpsimd_disable_trap();
} }
} }

View file

@ -522,10 +522,6 @@ struct mm_struct {
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
atomic_long_t hugetlb_usage; atomic_long_t hugetlb_usage;
#endif #endif
#ifdef CONFIG_MSM_APP_SETTINGS
int app_setting;
#endif
}; };
static inline void mm_init_cpumask(struct mm_struct *mm) static inline void mm_init_cpumask(struct mm_struct *mm)

View file

@ -85,9 +85,6 @@
#ifdef CONFIG_PARAVIRT #ifdef CONFIG_PARAVIRT
#include <asm/paravirt.h> #include <asm/paravirt.h>
#endif #endif
#ifdef CONFIG_MSM_APP_SETTINGS
#include <asm/app_api.h>
#endif
#include "sched.h" #include "sched.h"
#include "../workqueue_internal.h" #include "../workqueue_internal.h"
@ -5895,11 +5892,6 @@ prepare_task_switch(struct rq *rq, struct task_struct *prev,
fire_sched_out_preempt_notifiers(prev, next); fire_sched_out_preempt_notifiers(prev, next);
prepare_lock_switch(rq, next); prepare_lock_switch(rq, next);
prepare_arch_switch(next); prepare_arch_switch(next);
#ifdef CONFIG_MSM_APP_SETTINGS
if (use_app_setting)
switch_app_setting_bit(prev, next);
#endif
} }
/** /**

View file

@ -48,10 +48,6 @@
#include <asm/tlb.h> #include <asm/tlb.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#ifdef CONFIG_MSM_APP_SETTINGS
#include <asm/app_api.h>
#endif
#include "internal.h" #include "internal.h"
#ifndef arch_mmap_check #ifndef arch_mmap_check
@ -1301,11 +1297,6 @@ unsigned long do_mmap(struct file *file, unsigned long addr,
if (!len) if (!len)
return -EINVAL; return -EINVAL;
#ifdef CONFIG_MSM_APP_SETTINGS
if (use_app_setting)
apply_app_setting_bit(file);
#endif
/* /*
* Does the application expect PROT_READ to imply PROT_EXEC? * Does the application expect PROT_READ to imply PROT_EXEC?
* *