* [PATCH 1/3] arm64: Track system support for mixed endian EL0
2015-01-15 12:36 [PATCHv2 " Suzuki K. Poulose
@ 2015-01-15 12:36 ` Suzuki K. Poulose
2015-01-16 15:53 ` Will Deacon
0 siblings, 1 reply; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-15 12:36 UTC (permalink / raw)
To: linux-arm-kernel
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 10 ++++++++++
arch/arm64/kernel/cpuinfo.c | 22 ++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 07547cc..c7f68d1 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -26,6 +26,9 @@
#define ARM64_NCAPS 2
+#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL << 16)
+#define ID_AA64MMFR0_EL1_BigEnd (0x1UL << 8)
+
#ifndef __ASSEMBLY__
extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
@@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
__set_bit(num, cpu_hwcaps);
}
+static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
+{
+ return !!(mmfr0 & (ID_AA64MMFR0_EL1_BigEndEL0 | ID_AA64MMFR0_EL1_BigEnd));
+}
+
void check_local_cpu_errata(void);
+bool system_supports_mixed_endian_el0(void);
+bool cpu_supports_mixed_endian_el0(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 07d435c..b6d1135 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,6 +35,7 @@
*/
DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
static struct cpuinfo_arm64 boot_cpu_data;
+static bool mixed_endian_el0 = true;
static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
@@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
}
+bool cpu_supports_mixed_endian_el0(void)
+{
+ return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}
+
+bool system_supports_mixed_endian_el0(void)
+{
+ return mixed_endian_el0;
+}
+
+static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+{
+ mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
+}
+
+static void update_cpu_features(struct cpuinfo_arm64 *info)
+{
+ update_mixed_endian_el0_support(info);
+}
+
static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
{
if ((boot & mask) == (cur & mask))
@@ -215,6 +236,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
cpuinfo_detect_icache_policy(info);
check_local_cpu_errata();
+ update_cpu_features(info);
}
void cpuinfo_store_cpu(void)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 1/3] arm64: Track system support for mixed endian EL0
2015-01-15 12:36 ` [PATCH 1/3] arm64: Track system support for mixed endian EL0 Suzuki K. Poulose
@ 2015-01-16 15:53 ` Will Deacon
2015-01-16 16:15 ` Suzuki K. Poulose
0 siblings, 1 reply; 10+ messages in thread
From: Will Deacon @ 2015-01-16 15:53 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Jan 15, 2015 at 12:36:04PM +0000, Suzuki K. Poulose wrote:
> From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
>
> This patch keeps track of the mixed endian EL0 support across
> the system and provides helper functions to export it. The status
> is a boolean indicating whether all the CPUs on the system supports
> mixed endian at EL0.
>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> ---
> arch/arm64/include/asm/cpufeature.h | 10 ++++++++++
> arch/arm64/kernel/cpuinfo.c | 22 ++++++++++++++++++++++
> 2 files changed, 32 insertions(+)
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 07547cc..c7f68d1 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -26,6 +26,9 @@
>
> #define ARM64_NCAPS 2
>
> +#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL << 16)
> +#define ID_AA64MMFR0_EL1_BigEnd (0x1UL << 8)
I don't like the CaMeLcAsE. Also, perhaps these definitions should be
somewhere like cputype.h?
> +
> #ifndef __ASSEMBLY__
>
> extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
> @@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
> __set_bit(num, cpu_hwcaps);
> }
>
> +static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
> +{
> + return !!(mmfr0 & (ID_AA64MMFR0_EL1_BigEndEL0 | ID_AA64MMFR0_EL1_BigEnd));
> +}
These are 4-bit fields and I think you think you should be treating them
as such.
> +
> void check_local_cpu_errata(void);
> +bool system_supports_mixed_endian_el0(void);
> +bool cpu_supports_mixed_endian_el0(void);
>
> #endif /* __ASSEMBLY__ */
>
> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
> index 07d435c..b6d1135 100644
> --- a/arch/arm64/kernel/cpuinfo.c
> +++ b/arch/arm64/kernel/cpuinfo.c
> @@ -35,6 +35,7 @@
> */
> DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
> static struct cpuinfo_arm64 boot_cpu_data;
> +static bool mixed_endian_el0 = true;
>
> static char *icache_policy_str[] = {
> [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
> @@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
> pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
> }
>
> +bool cpu_supports_mixed_endian_el0(void)
> +{
> + return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
> +}
Can we not just define a mask/value pair and have code do the MMFR0 access
inline? It also feels a bit over-engineered like this.
Will
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] arm64: Track system support for mixed endian EL0
2015-01-16 15:53 ` Will Deacon
@ 2015-01-16 16:15 ` Suzuki K. Poulose
2015-01-19 9:41 ` Suzuki K. Poulose
0 siblings, 1 reply; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-16 16:15 UTC (permalink / raw)
To: linux-arm-kernel
On 16/01/15 15:53, Will Deacon wrote:
> On Thu, Jan 15, 2015 at 12:36:04PM +0000, Suzuki K. Poulose wrote:
>> From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
>>
>> This patch keeps track of the mixed endian EL0 support across
>> the system and provides helper functions to export it. The status
>> is a boolean indicating whether all the CPUs on the system supports
>> mixed endian at EL0.
>>
>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>> ---
>> arch/arm64/include/asm/cpufeature.h | 10 ++++++++++
>> arch/arm64/kernel/cpuinfo.c | 22 ++++++++++++++++++++++
>> 2 files changed, 32 insertions(+)
>>
>> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
>> index 07547cc..c7f68d1 100644
>> --- a/arch/arm64/include/asm/cpufeature.h
>> +++ b/arch/arm64/include/asm/cpufeature.h
>> @@ -26,6 +26,9 @@
>>
>> #define ARM64_NCAPS 2
>>
>> +#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL << 16)
>> +#define ID_AA64MMFR0_EL1_BigEnd (0x1UL << 8)
>
> I don't like the CaMeLcAsE. Also, perhaps these definitions should be
> somewhere like cputype.h?
Yeah, I tried to keep it aligned withe ARMv8 architecture definition of
those bits. Will change it.
Things are a bit messy w.r.t the definitions. We have cpu.h,
cpufeature.h and cputype.h. I could move it to cputype.h, where we
already have MIDR_ defintions.
>
>> +
>> #ifndef __ASSEMBLY__
>>
>> extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
>> @@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
>> __set_bit(num, cpu_hwcaps);
>> }
>>
>> +static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
>> +{
>> + return !!(mmfr0 & (ID_AA64MMFR0_EL1_BigEndEL0 | ID_AA64MMFR0_EL1_BigEnd));
>> +}
>
> These are 4-bit fields and I think you think you should be treating them
> as such.
OK
>
>> +
>> void check_local_cpu_errata(void);
>> +bool system_supports_mixed_endian_el0(void);
>> +bool cpu_supports_mixed_endian_el0(void);
>>
>> #endif /* __ASSEMBLY__ */
>>
>> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
>> index 07d435c..b6d1135 100644
>> --- a/arch/arm64/kernel/cpuinfo.c
>> +++ b/arch/arm64/kernel/cpuinfo.c
>> @@ -35,6 +35,7 @@
>> */
>> DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
>> static struct cpuinfo_arm64 boot_cpu_data;
>> +static bool mixed_endian_el0 = true;
>>
>> static char *icache_policy_str[] = {
>> [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
>> @@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
>> pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
>> }
>>
>> +bool cpu_supports_mixed_endian_el0(void)
>> +{
>> + return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
>> +}
>
> Can we not just define a mask/value pair and have code do the MMFR0 access
> inline? It also feels a bit over-engineered like this.
Sure, will change this.
Thanks
Suzuki
>
> Will
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] arm64: Track system support for mixed endian EL0
2015-01-16 16:15 ` Suzuki K. Poulose
@ 2015-01-19 9:41 ` Suzuki K. Poulose
0 siblings, 0 replies; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-19 9:41 UTC (permalink / raw)
To: linux-arm-kernel
On 16/01/15 16:15, Suzuki K. Poulose wrote:
> On 16/01/15 15:53, Will Deacon wrote:
>> On Thu, Jan 15, 2015 at 12:36:04PM +0000, Suzuki K. Poulose wrote:
>>> From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
>>>
>>> This patch keeps track of the mixed endian EL0 support across
>>> the system and provides helper functions to export it. The status
>>> is a boolean indicating whether all the CPUs on the system supports
>>> mixed endian at EL0.
>>>
>>> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
>>> ---
>>> arch/arm64/include/asm/cpufeature.h | 10 ++++++++++
>>> arch/arm64/kernel/cpuinfo.c | 22 ++++++++++++++++++++++
>>> 2 files changed, 32 insertions(+)
>>>
>>> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
>>> index 07547cc..c7f68d1 100644
>>> --- a/arch/arm64/include/asm/cpufeature.h
>>> +++ b/arch/arm64/include/asm/cpufeature.h
>>> @@ -26,6 +26,9 @@
>>>
>>> #define ARM64_NCAPS 2
>>>
>>> +#define ID_AA64MMFR0_EL1_BigEndEL0 (0x1UL << 16)
>>> +#define ID_AA64MMFR0_EL1_BigEnd (0x1UL << 8)
>>
>> I don't like the CaMeLcAsE. Also, perhaps these definitions should be
>> somewhere like cputype.h?
> Yeah, I tried to keep it aligned withe ARMv8 architecture definition of
> those bits. Will change it.
> Things are a bit messy w.r.t the definitions. We have cpu.h,
> cpufeature.h and cputype.h. I could move it to cputype.h, where we
> already have MIDR_ defintions.
>
>>
>>> +
>>> #ifndef __ASSEMBLY__
>>>
>>> extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
>>> @@ -51,7 +54,14 @@ static inline void cpus_set_cap(unsigned int num)
>>> __set_bit(num, cpu_hwcaps);
>>> }
>>>
>>> +static inline bool id_aa64mmfr0_mixed_endian_el0(unsigned long mmfr0)
>>> +{
>>> + return !!(mmfr0 & (ID_AA64MMFR0_EL1_BigEndEL0 | ID_AA64MMFR0_EL1_BigEnd));
>>> +}
>>
>> These are 4-bit fields and I think you think you should be treating them
>> as such.
> OK
>
>>
>>> +
>>> void check_local_cpu_errata(void);
>>> +bool system_supports_mixed_endian_el0(void);
>>> +bool cpu_supports_mixed_endian_el0(void);
>>>
>>> #endif /* __ASSEMBLY__ */
>>>
>>> diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
>>> index 07d435c..b6d1135 100644
>>> --- a/arch/arm64/kernel/cpuinfo.c
>>> +++ b/arch/arm64/kernel/cpuinfo.c
>>> @@ -35,6 +35,7 @@
>>> */
>>> DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
>>> static struct cpuinfo_arm64 boot_cpu_data;
>>> +static bool mixed_endian_el0 = true;
>>>
>>> static char *icache_policy_str[] = {
>>> [ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
>>> @@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
>>> pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
>>> }
>>>
>>> +bool cpu_supports_mixed_endian_el0(void)
>>> +{
>>> + return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
>>> +}
>>
>> Can we not just define a mask/value pair and have code do the MMFR0 access
>> inline? It also feels a bit over-engineered like this.
> Sure, will change this.
On a second thought, we need the id_aa64mmfr0_mixed_endian_el0() for
another code path. For a new CPU detected at boot time via
cpuinfo_store_cpu(), where we get the 'filled' cpuinfo_arm64 which
already has the id_aa64mmfr0. So we do:
+
+static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+{
+ mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
+}
So, having a helper to extract the support from the id_aa64mmfr0 makes
it a bit more ordered.
But yes, we could switch to mask/value pair.
Thanks
Suzuki
>
> Thanks
> Suzuki
>>
>> Will
>>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv3 0/3] Handle SETEND for AArch32 tasks
@ 2015-01-21 12:43 Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 1/3] arm64: Track system support for mixed endian EL0 Suzuki K. Poulose
2015-01-23 17:16 ` [PATCHv3 0/3] Handle SETEND for AArch32 tasks Catalin Marinas
0 siblings, 2 replies; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-21 12:43 UTC (permalink / raw)
To: linux-arm-kernel
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
This series add support for controlling the 'setend' instruction,
which is deprecated in ARMv8, using the legacy instruction emulation
framework, introduced by Punit Agrawal.
Changes since V2:
- Move ID_AA64MMFR0_EL1 bit definitions to asm/cputype.h
- Use mask/value pair for the features in ID_AA64MMFR0_EL1
- Better documentation about the hardware support limitaion under
Documentation and the Kconfig help
- Restore the original 'set_hw_mode' API, with wrappers to invoke
the set_hw_mode for on_each_cpu() variants.
- Print a warning when we detect an incompatibility for a registered
insn_emulation hook on a hotplugged CPU.
Changes since V1:
- Added a patch to keep track of the mixed endian support and register
the setend emulation only if all the active CPUs supports mixed endian.
- Fail hotplug operation if the CPU doesn't support a feature
required by insn_emulation.
- Signal handler runs in native endian
Testing :
$ cat setend_sig.c
#include <stdio.h>
#include <signal.h>
#define setend_be(a) asm __volatile__ ( "setend be" ::: "memory" )
#define setend_le(a) asm __volatile__ ( "setend le" ::: "memory" )
volatile int flag = 1;
void sigint(int sig)
{
printf("in sighandler %d\n", sig);
flag = 0;
return;
}
main()
{
volatile int a = 0x0;
(void)signal(SIGINT, sigint);
printf("Press Ctrl+C to continue\n");
setend_be();
a ++;
while (flag);
setend_le();
a ++;
printf("a: 0x%x\n", a);
return 0;
}
$ cat /proc/sys/abi/setend
1
$ echo 1 > /sys/kernel/debug/tracing/events/emulation/instruction_emulation/enable
$ echo 1 > /sys/kernel/debug/tracing/tracing_on
$ ./setend_sig_a32
Press Ctrl+C to continue
^Cin sighandler 2
a: 0x1000001
$ cat /sys/kernel/debug/tracing/trace
# tracer: nop
#
# entries-in-buffer/entries-written: 2/2 #P:2
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
setend_sig_a32-1373 [000] ...1 491.554499: instruction_emulation: instr="setend be" addr=0x8460
setend_sig_a32-1373 [000] ...1 492.833056: instruction_emulation: instr="setend le" addr=0x8488
$ dmesg | tail
[ 491.554807] "setend_sig_a32" (1373) uses deprecated setend instruction at 0x8460
[ 492.833285] "setend_sig_a32" (1373) uses deprecated setend instruction at 0x8488
$ echo 2 > /proc/sys/abi/setend
$ ./setend_sig_t16
Press Ctrl+C to continue
^Cin sighandler 2
a: 0x1000001
$ dmesg | tail
[ 491.554807] "setend_sig_a32" (1373) uses deprecated setend instruction at 0x8460
[ 492.833285] "setend_sig_a32" (1373) uses deprecated setend instruction at 0x8488
[ 537.426216] Removed setend emulation handler
[ 537.426624] Enabled setend support
Suzuki K. Poulose (3):
arm64: Track system support for mixed endian EL0
arm64: Consolidate hotplug notifier for instruction emulation
arm64: Emulate SETEND for AArch32 tasks
Documentation/arm64/legacy_instructions.txt | 12 ++
arch/arm64/Kconfig | 15 ++
arch/arm64/include/asm/cpufeature.h | 2 +
arch/arm64/include/asm/cputype.h | 17 +++
arch/arm64/include/asm/ptrace.h | 7 +
arch/arm64/kernel/armv8_deprecated.c | 205 ++++++++++++++++++++-------
arch/arm64/kernel/cpuinfo.c | 22 +++
arch/arm64/kernel/signal32.c | 5 +-
8 files changed, 236 insertions(+), 49 deletions(-)
--
1.7.9.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/3] arm64: Track system support for mixed endian EL0
2015-01-21 12:43 [PATCHv3 0/3] Handle SETEND for AArch32 tasks Suzuki K. Poulose
@ 2015-01-21 12:43 ` Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Suzuki K. Poulose
2015-01-23 17:16 ` [PATCHv3 0/3] Handle SETEND for AArch32 tasks Catalin Marinas
1 sibling, 1 reply; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-21 12:43 UTC (permalink / raw)
To: linux-arm-kernel
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
This patch keeps track of the mixed endian EL0 support across
the system and provides helper functions to export it. The status
is a boolean indicating whether all the CPUs on the system supports
mixed endian at EL0.
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 2 ++
arch/arm64/include/asm/cputype.h | 14 ++++++++++++++
arch/arm64/kernel/cpuinfo.c | 22 ++++++++++++++++++++++
3 files changed, 38 insertions(+)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 07547cc..b6c16d5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -52,6 +52,8 @@ static inline void cpus_set_cap(unsigned int num)
}
void check_local_cpu_errata(void);
+bool cpu_supports_mixed_endian_el0(void);
+bool system_supports_mixed_endian_el0(void);
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 53d59b0..44e578d 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -73,6 +73,15 @@
#define APM_CPU_PART_POTENZA 0x000
+#define ID_AA64MMFR0_BIGENDEL0_SHIFT 16
+#define ID_AA64MMFR0_BIGENDEL0_MASK (0xf << ID_AA64MMFR0_BIGENDEL0_SHIFT)
+#define ID_AA64MMFR0_BIGENDEL0(mmfr0) \
+ (((mmfr0) & ID_AA64MMFR0_BIGENDEL0_MASK) >> ID_AA64MMFR0_BIGENDEL0_SHIFT)
+#define ID_AA64MMFR0_BIGEND_SHIFT 8
+#define ID_AA64MMFR0_BIGEND_MASK (0xf << ID_AA64MMFR0_BIGEND_SHIFT)
+#define ID_AA64MMFR0_BIGEND(mmfr0) \
+ (((mmfr0) & ID_AA64MMFR0_BIGEND_MASK) >> ID_AA64MMFR0_BIGEND_SHIFT)
+
#ifndef __ASSEMBLY__
/*
@@ -105,6 +114,11 @@ static inline u32 __attribute_const__ read_cpuid_cachetype(void)
return read_cpuid(CTR_EL0);
}
+static inline bool id_aa64mmfr0_mixed_endian_el0(u64 mmfr0)
+{
+ return (ID_AA64MMFR0_BIGEND(mmfr0) == 0x1) ||
+ (ID_AA64MMFR0_BIGENDEL0(mmfr0) == 0x1);
+}
#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 07d435c..b6d1135 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -35,6 +35,7 @@
*/
DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
static struct cpuinfo_arm64 boot_cpu_data;
+static bool mixed_endian_el0 = true;
static char *icache_policy_str[] = {
[ICACHE_POLICY_RESERVED] = "RESERVED/UNKNOWN",
@@ -68,6 +69,26 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
pr_info("Detected %s I-cache on CPU%d\n", icache_policy_str[l1ip], cpu);
}
+bool cpu_supports_mixed_endian_el0(void)
+{
+ return id_aa64mmfr0_mixed_endian_el0(read_cpuid(ID_AA64MMFR0_EL1));
+}
+
+bool system_supports_mixed_endian_el0(void)
+{
+ return mixed_endian_el0;
+}
+
+static void update_mixed_endian_el0_support(struct cpuinfo_arm64 *info)
+{
+ mixed_endian_el0 &= id_aa64mmfr0_mixed_endian_el0(info->reg_id_aa64mmfr0);
+}
+
+static void update_cpu_features(struct cpuinfo_arm64 *info)
+{
+ update_mixed_endian_el0_support(info);
+}
+
static int check_reg_mask(char *name, u64 mask, u64 boot, u64 cur, int cpu)
{
if ((boot & mask) == (cur & mask))
@@ -215,6 +236,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
cpuinfo_detect_icache_policy(info);
check_local_cpu_errata();
+ update_cpu_features(info);
}
void cpuinfo_store_cpu(void)
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation
2015-01-21 12:43 ` [PATCH 1/3] arm64: Track system support for mixed endian EL0 Suzuki K. Poulose
@ 2015-01-21 12:43 ` Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 3/3] arm64: Emulate SETEND for AArch32 tasks Suzuki K. Poulose
2015-01-23 12:31 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Punit Agrawal
0 siblings, 2 replies; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-21 12:43 UTC (permalink / raw)
To: linux-arm-kernel
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
As of now each insn_emulation has a cpu hotplug notifier that
enables/disables the CPU feature bit for the functionality. This
patch re-arranges the code, such that there is only one notifier
that runs through the list of registered emulation hooks and runs
their corresponding set_hw_mode.
We do nothing when a CPU is dying as we will set the appropriate bits
as it comes back online based on the state of the hooks.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Punit Agrawal <punit.agrawal@arm.com>
---
arch/arm64/include/asm/cputype.h | 2 +
arch/arm64/kernel/armv8_deprecated.c | 125 +++++++++++++++++++++-------------
2 files changed, 79 insertions(+), 48 deletions(-)
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 44e578d..2c4c852 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -82,6 +82,8 @@
#define ID_AA64MMFR0_BIGEND(mmfr0) \
(((mmfr0) & ID_AA64MMFR0_BIGEND_MASK) >> ID_AA64MMFR0_BIGEND_SHIFT)
+#define SCTLR_EL1_CP15BEN (0x1 << 5)
+
#ifndef __ASSEMBLY__
/*
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index c363671..2c991f1 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -19,6 +19,7 @@
#include <asm/system_misc.h>
#include <asm/traps.h>
#include <asm/uaccess.h>
+#include <asm/cpufeature.h>
#define CREATE_TRACE_POINTS
#include "trace-events-emulation.h"
@@ -85,6 +86,57 @@ static void remove_emulation_hooks(struct insn_emulation_ops *ops)
pr_notice("Removed %s emulation handler\n", ops->name);
}
+static void enable_insn_hw_mode(void *data)
+{
+ struct insn_emulation *insn = (struct insn_emulation *)data;
+ if (insn && insn->ops->set_hw_mode)
+ insn->ops->set_hw_mode(true);
+}
+
+static void disable_insn_hw_mode(void *data)
+{
+ struct insn_emulation *insn = (struct insn_emulation *)data;
+ if (insn && insn->ops->set_hw_mode)
+ insn->ops->set_hw_mode(false);
+}
+
+/* Run set_hw_mode(mode) on all active CPUs */
+static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
+{
+ if (!insn->ops->set_hw_mode)
+ return -EINVAL;
+ if (enable)
+ on_each_cpu(enable_insn_hw_mode, (void *)insn, true);
+ else
+ on_each_cpu(disable_insn_hw_mode, (void *)insn, true);
+ return 0;
+}
+
+/*
+ * Run set_hw_mode for all insns on a starting CPU.
+ * Returns:
+ * 0 - If all the hooks ran successfully.
+ * -EINVAL - At least one hook is not supported by the CPU.
+ */
+static int run_all_insn_set_hw_mode(unsigned long cpu)
+{
+ int rc = 0;
+ unsigned long flags;
+ struct insn_emulation *insn;
+
+ raw_spin_lock_irqsave(&insn_emulation_lock, flags);
+ list_for_each_entry(insn, &insn_emulation, node) {
+ bool enable = (insn->current_mode == INSN_HW);
+ if (insn->ops->set_hw_mode && insn->ops->set_hw_mode(enable)) {
+ pr_warn(enable, "CPU[%ld] cannot support the emulation of %s",
+ cpu, insn->ops->name);
+ rc = -EINVAL;
+ }
+ }
+ raw_spin_unlock_irqrestore(&insn_emulation_lock, flags);
+ return rc;
+}
+
static int update_insn_emulation_mode(struct insn_emulation *insn,
enum insn_emulation_mode prev)
{
@@ -97,10 +149,8 @@ static int update_insn_emulation_mode(struct insn_emulation *insn,
remove_emulation_hooks(insn->ops);
break;
case INSN_HW:
- if (insn->ops->set_hw_mode) {
- insn->ops->set_hw_mode(false);
+ if (!run_all_cpu_set_hw_mode(insn, false))
pr_notice("Disabled %s support\n", insn->ops->name);
- }
break;
}
@@ -111,10 +161,9 @@ static int update_insn_emulation_mode(struct insn_emulation *insn,
register_emulation_hooks(insn->ops);
break;
case INSN_HW:
- if (insn->ops->set_hw_mode && insn->ops->set_hw_mode(true))
+ ret = run_all_cpu_set_hw_mode(insn, true);
+ if (!ret)
pr_notice("Enabled %s support\n", insn->ops->name);
- else
- ret = -EINVAL;
break;
}
@@ -133,6 +182,8 @@ static void register_insn_emulation(struct insn_emulation_ops *ops)
switch (ops->status) {
case INSN_DEPRECATED:
insn->current_mode = INSN_EMULATE;
+ /* Disable the HW mode if it was turned on at early boot time */
+ run_all_cpu_set_hw_mode(insn, false);
insn->max = INSN_HW;
break;
case INSN_OBSOLETE:
@@ -453,8 +504,6 @@ ret:
return 0;
}
-#define SCTLR_EL1_CP15BEN (1 << 5)
-
static inline void config_sctlr_el1(u32 clear, u32 set)
{
u32 val;
@@ -465,48 +514,13 @@ static inline void config_sctlr_el1(u32 clear, u32 set)
asm volatile("msr sctlr_el1, %0" : : "r" (val));
}
-static void enable_cp15_ben(void *info)
-{
- config_sctlr_el1(0, SCTLR_EL1_CP15BEN);
-}
-
-static void disable_cp15_ben(void *info)
-{
- config_sctlr_el1(SCTLR_EL1_CP15BEN, 0);
-}
-
-static int cpu_hotplug_notify(struct notifier_block *b,
- unsigned long action, void *hcpu)
-{
- switch (action) {
- case CPU_STARTING:
- case CPU_STARTING_FROZEN:
- enable_cp15_ben(NULL);
- return NOTIFY_DONE;
- case CPU_DYING:
- case CPU_DYING_FROZEN:
- disable_cp15_ben(NULL);
- return NOTIFY_DONE;
- }
-
- return NOTIFY_OK;
-}
-
-static struct notifier_block cpu_hotplug_notifier = {
- .notifier_call = cpu_hotplug_notify,
-};
-
static int cp15_barrier_set_hw_mode(bool enable)
{
- if (enable) {
- register_cpu_notifier(&cpu_hotplug_notifier);
- on_each_cpu(enable_cp15_ben, NULL, true);
- } else {
- unregister_cpu_notifier(&cpu_hotplug_notifier);
- on_each_cpu(disable_cp15_ben, NULL, true);
- }
-
- return true;
+ if (enable)
+ config_sctlr_el1(0, SCTLR_EL1_CP15BEN);
+ else
+ config_sctlr_el1(SCTLR_EL1_CP15BEN, 0);
+ return 0;
}
static struct undef_hook cp15_barrier_hooks[] = {
@@ -534,6 +548,20 @@ static struct insn_emulation_ops cp15_barrier_ops = {
.set_hw_mode = cp15_barrier_set_hw_mode,
};
+static int insn_cpu_hotplug_notify(struct notifier_block *b,
+ unsigned long action, void *hcpu)
+{
+ int rc = 0;
+ if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING)
+ rc = run_all_insn_set_hw_mode((unsigned long)hcpu);
+
+ return notifier_from_errno(rc);
+}
+
+static struct notifier_block insn_cpu_hotplug_notifier = {
+ .notifier_call = insn_cpu_hotplug_notify,
+};
+
/*
* Invoked as late_initcall, since not needed before init spawned.
*/
@@ -545,6 +573,7 @@ static int __init armv8_deprecated_init(void)
if (IS_ENABLED(CONFIG_CP15_BARRIER_EMULATION))
register_insn_emulation(&cp15_barrier_ops);
+ register_cpu_notifier(&insn_cpu_hotplug_notifier);
register_insn_emulation_sysctl(ctl_abi);
return 0;
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/3] arm64: Emulate SETEND for AArch32 tasks
2015-01-21 12:43 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Suzuki K. Poulose
@ 2015-01-21 12:43 ` Suzuki K. Poulose
2015-01-23 12:31 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Punit Agrawal
1 sibling, 0 replies; 10+ messages in thread
From: Suzuki K. Poulose @ 2015-01-21 12:43 UTC (permalink / raw)
To: linux-arm-kernel
From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
Emulate deprecated 'setend' instruction for AArch32 bit tasks.
setend [le/be] - Sets the endianness of EL0
On systems with CPUs which support mixed endian at EL0, the hardware
support for the instruction can be enabled by setting the SCTLR_EL1.SED
bit. Like the other emulated instructions it is controlled by an entry in
/proc/sys/abi/. For more information see :
Documentation/arm64/legacy_instructions.txt
The instruction is emulated by setting/clearing the SPSR_EL1.E bit, which
will be reflected in the PSTATE.E in AArch32 context.
This patch also restores the native endianness for the execution of signal
handlers, since the process could have changed the endianness.
Note: All CPUs on the system must have mixed endian support at EL0. Once the
handler is registered, hotplugging a CPU which doesn't support mixed endian,
could lead to unexpected results/behavior in applications.
Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Punit Agrawal <punit.agrawal@arm.com>
---
Documentation/arm64/legacy_instructions.txt | 12 ++++
arch/arm64/Kconfig | 15 +++++
arch/arm64/include/asm/cputype.h | 1 +
arch/arm64/include/asm/ptrace.h | 7 +++
arch/arm64/kernel/armv8_deprecated.c | 80 +++++++++++++++++++++++++++
arch/arm64/kernel/signal32.c | 5 +-
6 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/Documentation/arm64/legacy_instructions.txt b/Documentation/arm64/legacy_instructions.txt
index a3b3da2..01bf3d9 100644
--- a/Documentation/arm64/legacy_instructions.txt
+++ b/Documentation/arm64/legacy_instructions.txt
@@ -32,6 +32,9 @@ The default mode depends on the status of the instruction in the
architecture. Deprecated instructions should default to emulation
while obsolete instructions must be undefined by default.
+Note: Instruction emulation may not be possible in all cases. See
+individual instruction notes for further information.
+
Supported legacy instructions
-----------------------------
* SWP{B}
@@ -43,3 +46,12 @@ Default: Undef (0)
Node: /proc/sys/abi/cp15_barrier
Status: Deprecated
Default: Emulate (1)
+
+* SETEND
+Node: /proc/sys/abi/setend
+Status: Deprecated
+Default: Emulate (1)*
+Note: All the cpus on the system must have mixed endian support at EL0
+for this feature to be enabled. If a new CPU - which doesn't support mixed
+endian - is hotplugged in after this feature has been enabled, there could
+be unexpected results in the application.
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index b1f9a20..21a59bf 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -540,6 +540,21 @@ config CP15_BARRIER_EMULATION
If unsure, say Y
+config SETEND_EMULATION
+ bool "Emulate SETEND instruction"
+ help
+ The SETEND instruction alters the data-endianness of the
+ AArch32 EL0, and is deprecated in ARMv8.
+
+ Say Y here to enable software emulation of the instruction
+ for AArch32 userspace code.
+
+ Note: All the cpus on the system must have mixed endian support at EL0
+ for this feature to be enabled. If a new CPU - which doesn't support mixed
+ endian - is hotplugged in after this feature has been enabled, there could
+ be unexpected results in the applications.
+
+ If unsure, say Y
endif
endmenu
diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h
index 2c4c852..241dd2f 100644
--- a/arch/arm64/include/asm/cputype.h
+++ b/arch/arm64/include/asm/cputype.h
@@ -83,6 +83,7 @@
(((mmfr0) & ID_AA64MMFR0_BIGEND_MASK) >> ID_AA64MMFR0_BIGEND_SHIFT)
#define SCTLR_EL1_CP15BEN (0x1 << 5)
+#define SCTLR_EL1_SED (0x1 << 8)
#ifndef __ASSEMBLY__
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
index 41ed9e1..d6dd9fd 100644
--- a/arch/arm64/include/asm/ptrace.h
+++ b/arch/arm64/include/asm/ptrace.h
@@ -58,6 +58,13 @@
#define COMPAT_PSR_Z_BIT 0x40000000
#define COMPAT_PSR_N_BIT 0x80000000
#define COMPAT_PSR_IT_MASK 0x0600fc00 /* If-Then execution state mask */
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define COMPAT_PSR_ENDSTATE COMPAT_PSR_E_BIT
+#else
+#define COMPAT_PSR_ENDSTATE 0
+#endif
+
/*
* These are 'magic' values for PTRACE_PEEKUSR that return info about where a
* process is located in memory.
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 2c991f1..dea6f59 100644
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -548,6 +548,79 @@ static struct insn_emulation_ops cp15_barrier_ops = {
.set_hw_mode = cp15_barrier_set_hw_mode,
};
+static int setend_set_hw_mode(bool enable)
+{
+ if (!cpu_supports_mixed_endian_el0())
+ return -EINVAL;
+
+ if (enable)
+ config_sctlr_el1(SCTLR_EL1_SED, 0);
+ else
+ config_sctlr_el1(0, SCTLR_EL1_SED);
+ return 0;
+}
+
+static int compat_setend_handler(struct pt_regs *regs, u32 big_endian)
+{
+ char *insn;
+
+ perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, regs->pc);
+
+ if (big_endian) {
+ insn = "setend be";
+ regs->pstate |= COMPAT_PSR_E_BIT;
+ } else {
+ insn = "setend le";
+ regs->pstate &= ~COMPAT_PSR_E_BIT;
+ }
+
+ trace_instruction_emulation(insn, regs->pc);
+ pr_warn_ratelimited("\"%s\" (%ld) uses deprecated setend instruction at 0x%llx\n",
+ current->comm, (unsigned long)current->pid, regs->pc);
+
+ return 0;
+}
+
+static int a32_setend_handler(struct pt_regs *regs, u32 instr)
+{
+ int rc = compat_setend_handler(regs, (instr >> 9) & 1);
+ regs->pc += 4;
+ return rc;
+}
+
+static int t16_setend_handler(struct pt_regs *regs, u32 instr)
+{
+ int rc = compat_setend_handler(regs, (instr >> 3) & 1);
+ regs->pc += 2;
+ return rc;
+}
+
+static struct undef_hook setend_hooks[] = {
+ {
+ .instr_mask = 0xfffffdff,
+ .instr_val = 0xf1010000,
+ .pstate_mask = COMPAT_PSR_MODE_MASK,
+ .pstate_val = COMPAT_PSR_MODE_USR,
+ .fn = a32_setend_handler,
+ },
+ {
+ /* Thumb mode */
+ .instr_mask = 0x0000fff7,
+ .instr_val = 0x0000b650,
+ .pstate_mask = (COMPAT_PSR_T_BIT | COMPAT_PSR_MODE_MASK),
+ .pstate_val = (COMPAT_PSR_T_BIT | COMPAT_PSR_MODE_USR),
+ .fn = t16_setend_handler,
+ },
+ {}
+};
+
+static struct insn_emulation_ops setend_ops = {
+ .name = "setend",
+ .status = INSN_DEPRECATED,
+ .hooks = setend_hooks,
+ .set_hw_mode = setend_set_hw_mode,
+};
+
static int insn_cpu_hotplug_notify(struct notifier_block *b,
unsigned long action, void *hcpu)
{
@@ -573,6 +646,13 @@ static int __init armv8_deprecated_init(void)
if (IS_ENABLED(CONFIG_CP15_BARRIER_EMULATION))
register_insn_emulation(&cp15_barrier_ops);
+ if (IS_ENABLED(CONFIG_SETEND_EMULATION)) {
+ if(system_supports_mixed_endian_el0())
+ register_insn_emulation(&setend_ops);
+ else
+ pr_info("setend instruction emulation is not supported on the system");
+ }
+
register_cpu_notifier(&insn_cpu_hotplug_notifier);
register_insn_emulation_sysctl(ctl_abi);
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 5a1ba6e..aa763a5 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -440,7 +440,7 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
{
compat_ulong_t handler = ptr_to_compat(ka->sa.sa_handler);
compat_ulong_t retcode;
- compat_ulong_t spsr = regs->pstate & ~PSR_f;
+ compat_ulong_t spsr = regs->pstate & ~(PSR_f | COMPAT_PSR_E_BIT);
int thumb;
/* Check if the handler is written for ARM or Thumb */
@@ -454,6 +454,9 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
/* The IT state must be cleared for both ARM and Thumb-2 */
spsr &= ~COMPAT_PSR_IT_MASK;
+ /* Restore the original endianness */
+ spsr |= COMPAT_PSR_ENDSTATE;
+
if (ka->sa.sa_flags & SA_RESTORER) {
retcode = ptr_to_compat(ka->sa.sa_restorer);
} else {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation
2015-01-21 12:43 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 3/3] arm64: Emulate SETEND for AArch32 tasks Suzuki K. Poulose
@ 2015-01-23 12:31 ` Punit Agrawal
1 sibling, 0 replies; 10+ messages in thread
From: Punit Agrawal @ 2015-01-23 12:31 UTC (permalink / raw)
To: linux-arm-kernel
Hi Suzuki,
A possible simplification below.
"Suzuki K. Poulose" <suzuki.poulose@arm.com> writes:
> From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
>
> As of now each insn_emulation has a cpu hotplug notifier that
> enables/disables the CPU feature bit for the functionality. This
> patch re-arranges the code, such that there is only one notifier
> that runs through the list of registered emulation hooks and runs
> their corresponding set_hw_mode.
>
> We do nothing when a CPU is dying as we will set the appropriate bits
> as it comes back online based on the state of the hooks.
>
> Signed-off-by: Mark Rutland <mark.rutland@arm.com>
> Signed-off-by: Suzuki K. Poulose <suzuki.poulose@arm.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Punit Agrawal <punit.agrawal@arm.com>
> ---
> arch/arm64/include/asm/cputype.h | 2 +
> arch/arm64/kernel/armv8_deprecated.c | 125 +++++++++++++++++++++-------------
> 2 files changed, 79 insertions(+), 48 deletions(-)
>
[...]
> diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
> index c363671..2c991f1 100644
> --- a/arch/arm64/kernel/armv8_deprecated.c
> +++ b/arch/arm64/kernel/armv8_deprecated.c
> @@ -19,6 +19,7 @@
> #include <asm/system_misc.h>
> #include <asm/traps.h>
> #include <asm/uaccess.h>
> +#include <asm/cpufeature.h>
>
> #define CREATE_TRACE_POINTS
> #include "trace-events-emulation.h"
> @@ -85,6 +86,57 @@ static void remove_emulation_hooks(struct insn_emulation_ops *ops)
> pr_notice("Removed %s emulation handler\n", ops->name);
> }
>
> +static void enable_insn_hw_mode(void *data)
> +{
> + struct insn_emulation *insn = (struct insn_emulation *)data;
> + if (insn && insn->ops->set_hw_mode)
You can simplify (drop?) this...
> + insn->ops->set_hw_mode(true);
> +}
> +
> +static void disable_insn_hw_mode(void *data)
> +{
> + struct insn_emulation *insn = (struct insn_emulation *)data;
> + if (insn && insn->ops->set_hw_mode)
and this check since...
> + insn->ops->set_hw_mode(false);
> +}
> +
> +/* Run set_hw_mode(mode) on all active CPUs */
> +static int run_all_cpu_set_hw_mode(struct insn_emulation *insn, bool enable)
> +{
> + if (!insn->ops->set_hw_mode)
> + return -EINVAL;
insn->ops->set_hw_mode is already checked here.
> + if (enable)
> + on_each_cpu(enable_insn_hw_mode, (void *)insn, true);
> + else
> + on_each_cpu(disable_insn_hw_mode, (void *)insn, true);
> + return 0;
> +}
> +
> +/*
> + * Run set_hw_mode for all insns on a starting CPU.
> + * Returns:
> + * 0 - If all the hooks ran successfully.
> + * -EINVAL - At least one hook is not supported by the CPU.
> + */
> +static int run_all_insn_set_hw_mode(unsigned long cpu)
> +{
> + int rc = 0;
> + unsigned long flags;
> + struct insn_emulation *insn;
> +
> + raw_spin_lock_irqsave(&insn_emulation_lock, flags);
> + list_for_each_entry(insn, &insn_emulation, node) {
> + bool enable = (insn->current_mode == INSN_HW);
> + if (insn->ops->set_hw_mode && insn->ops->set_hw_mode(enable)) {
> + pr_warn(enable, "CPU[%ld] cannot support the emulation of %s",
> + cpu, insn->ops->name);
> + rc = -EINVAL;
> + }
> + }
> + raw_spin_unlock_irqrestore(&insn_emulation_lock, flags);
> + return rc;
> +}
> +
> static int update_insn_emulation_mode(struct insn_emulation *insn,
> enum insn_emulation_mode prev)
> {
[...]
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCHv3 0/3] Handle SETEND for AArch32 tasks
2015-01-21 12:43 [PATCHv3 0/3] Handle SETEND for AArch32 tasks Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 1/3] arm64: Track system support for mixed endian EL0 Suzuki K. Poulose
@ 2015-01-23 17:16 ` Catalin Marinas
1 sibling, 0 replies; 10+ messages in thread
From: Catalin Marinas @ 2015-01-23 17:16 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Jan 21, 2015 at 12:43:08PM +0000, Suzuki K. Poulose wrote:
> From: "Suzuki K. Poulose" <suzuki.poulose@arm.com>
>
> This series add support for controlling the 'setend' instruction,
> which is deprecated in ARMv8, using the legacy instruction emulation
> framework, introduced by Punit Agrawal.
>
> Changes since V2:
> - Move ID_AA64MMFR0_EL1 bit definitions to asm/cputype.h
> - Use mask/value pair for the features in ID_AA64MMFR0_EL1
> - Better documentation about the hardware support limitaion under
> Documentation and the Kconfig help
> - Restore the original 'set_hw_mode' API, with wrappers to invoke
> the set_hw_mode for on_each_cpu() variants.
> - Print a warning when we detect an incompatibility for a registered
> insn_emulation hook on a hotplugged CPU.
>
> Changes since V1:
> - Added a patch to keep track of the mixed endian support and register
> the setend emulation only if all the active CPUs supports mixed endian.
> - Fail hotplug operation if the CPU doesn't support a feature
> required by insn_emulation.
> - Signal handler runs in native endian
I queued these patches for 3.20 (and included Punit's suggestion as
well). They should appear in linux-next later today.
Cc'ing Greg H @ Google since they are the main users of the emulation
code. If you see any problem, please let us know.
Thanks.
--
Catalin
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-01-23 17:16 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-21 12:43 [PATCHv3 0/3] Handle SETEND for AArch32 tasks Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 1/3] arm64: Track system support for mixed endian EL0 Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Suzuki K. Poulose
2015-01-21 12:43 ` [PATCH 3/3] arm64: Emulate SETEND for AArch32 tasks Suzuki K. Poulose
2015-01-23 12:31 ` [PATCH 2/3] arm64: Consolidate hotplug notifier for instruction emulation Punit Agrawal
2015-01-23 17:16 ` [PATCHv3 0/3] Handle SETEND for AArch32 tasks Catalin Marinas
-- strict thread matches above, loose matches on Subject: below --
2015-01-15 12:36 [PATCHv2 " Suzuki K. Poulose
2015-01-15 12:36 ` [PATCH 1/3] arm64: Track system support for mixed endian EL0 Suzuki K. Poulose
2015-01-16 15:53 ` Will Deacon
2015-01-16 16:15 ` Suzuki K. Poulose
2015-01-19 9:41 ` Suzuki K. Poulose
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).