2016-07-23 17:12:40 +08:00
|
|
|
#ifndef __ASM_POWERPC_CPUFEATURES_H
|
|
|
|
#define __ASM_POWERPC_CPUFEATURES_H
|
|
|
|
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
|
2016-07-23 17:12:42 +08:00
|
|
|
#include <linux/bug.h>
|
2016-07-23 17:12:40 +08:00
|
|
|
#include <asm/cputable.h>
|
|
|
|
|
|
|
|
static inline bool early_cpu_has_feature(unsigned long feature)
|
|
|
|
{
|
|
|
|
return !!((CPU_FTRS_ALWAYS & feature) ||
|
|
|
|
(CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature));
|
|
|
|
}
|
|
|
|
|
powerpc: Add option to use jump label for cpu_has_feature()
We do binary patching of asm code using CPU features, which is a
one-time operation, done during early boot. However checks of CPU
features in C code are currently done at run time, even though the set
of CPU features can never change after boot.
We can optimise this by using jump labels to implement cpu_has_feature(),
meaning checks in C code are binary patched into a single nop or branch.
For a C sequence along the lines of:
if (cpu_has_feature(FOO))
return 2;
The generated code before is roughly:
ld r9,-27640(r2)
ld r9,0(r9)
lwz r9,32(r9)
cmpwi cr7,r9,0
bge cr7, 1f
li r3,2
blr
1: ...
After (true):
nop
li r3,2
blr
After (false):
b 1f
li r3,2
blr
1: ...
mpe: Rename MAX_CPU_FEATURES as we already have a #define with that
name, and define it simply as a constant, rather than doing tricks with
sizeof and NULL pointers. Rename the array to cpu_feature_keys. Use the
kconfig we added to guard it. Add BUILD_BUG_ON() if the feature is not a
compile time constant. Rewrite the change log.
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2016-07-23 17:12:41 +08:00
|
|
|
#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS
|
|
|
|
#include <linux/jump_label.h>
|
|
|
|
|
2016-09-12 10:48:28 +08:00
|
|
|
#define NUM_CPU_FTR_KEYS BITS_PER_LONG
|
powerpc: Add option to use jump label for cpu_has_feature()
We do binary patching of asm code using CPU features, which is a
one-time operation, done during early boot. However checks of CPU
features in C code are currently done at run time, even though the set
of CPU features can never change after boot.
We can optimise this by using jump labels to implement cpu_has_feature(),
meaning checks in C code are binary patched into a single nop or branch.
For a C sequence along the lines of:
if (cpu_has_feature(FOO))
return 2;
The generated code before is roughly:
ld r9,-27640(r2)
ld r9,0(r9)
lwz r9,32(r9)
cmpwi cr7,r9,0
bge cr7, 1f
li r3,2
blr
1: ...
After (true):
nop
li r3,2
blr
After (false):
b 1f
li r3,2
blr
1: ...
mpe: Rename MAX_CPU_FEATURES as we already have a #define with that
name, and define it simply as a constant, rather than doing tricks with
sizeof and NULL pointers. Rename the array to cpu_feature_keys. Use the
kconfig we added to guard it. Add BUILD_BUG_ON() if the feature is not a
compile time constant. Rewrite the change log.
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2016-07-23 17:12:41 +08:00
|
|
|
|
|
|
|
extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS];
|
|
|
|
|
|
|
|
static __always_inline bool cpu_has_feature(unsigned long feature)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
BUILD_BUG_ON(!__builtin_constant_p(feature));
|
|
|
|
|
2016-07-23 17:12:43 +08:00
|
|
|
#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
|
|
|
|
if (!static_key_initialized) {
|
|
|
|
printk("Warning! cpu_has_feature() used prior to jump label init!\n");
|
|
|
|
dump_stack();
|
|
|
|
return early_cpu_has_feature(feature);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
powerpc: Add option to use jump label for cpu_has_feature()
We do binary patching of asm code using CPU features, which is a
one-time operation, done during early boot. However checks of CPU
features in C code are currently done at run time, even though the set
of CPU features can never change after boot.
We can optimise this by using jump labels to implement cpu_has_feature(),
meaning checks in C code are binary patched into a single nop or branch.
For a C sequence along the lines of:
if (cpu_has_feature(FOO))
return 2;
The generated code before is roughly:
ld r9,-27640(r2)
ld r9,0(r9)
lwz r9,32(r9)
cmpwi cr7,r9,0
bge cr7, 1f
li r3,2
blr
1: ...
After (true):
nop
li r3,2
blr
After (false):
b 1f
li r3,2
blr
1: ...
mpe: Rename MAX_CPU_FEATURES as we already have a #define with that
name, and define it simply as a constant, rather than doing tricks with
sizeof and NULL pointers. Rename the array to cpu_feature_keys. Use the
kconfig we added to guard it. Add BUILD_BUG_ON() if the feature is not a
compile time constant. Rewrite the change log.
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2016-07-23 17:12:41 +08:00
|
|
|
if (CPU_FTRS_ALWAYS & feature)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!(CPU_FTRS_POSSIBLE & feature))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
i = __builtin_ctzl(feature);
|
|
|
|
return static_branch_likely(&cpu_feature_keys[i]);
|
|
|
|
}
|
|
|
|
#else
|
2016-07-23 17:12:40 +08:00
|
|
|
static inline bool cpu_has_feature(unsigned long feature)
|
|
|
|
{
|
|
|
|
return early_cpu_has_feature(feature);
|
|
|
|
}
|
powerpc: Add option to use jump label for cpu_has_feature()
We do binary patching of asm code using CPU features, which is a
one-time operation, done during early boot. However checks of CPU
features in C code are currently done at run time, even though the set
of CPU features can never change after boot.
We can optimise this by using jump labels to implement cpu_has_feature(),
meaning checks in C code are binary patched into a single nop or branch.
For a C sequence along the lines of:
if (cpu_has_feature(FOO))
return 2;
The generated code before is roughly:
ld r9,-27640(r2)
ld r9,0(r9)
lwz r9,32(r9)
cmpwi cr7,r9,0
bge cr7, 1f
li r3,2
blr
1: ...
After (true):
nop
li r3,2
blr
After (false):
b 1f
li r3,2
blr
1: ...
mpe: Rename MAX_CPU_FEATURES as we already have a #define with that
name, and define it simply as a constant, rather than doing tricks with
sizeof and NULL pointers. Rename the array to cpu_feature_keys. Use the
kconfig we added to guard it. Add BUILD_BUG_ON() if the feature is not a
compile time constant. Rewrite the change log.
Signed-off-by: Kevin Hao <haokexin@gmail.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2016-07-23 17:12:41 +08:00
|
|
|
#endif
|
2016-07-23 17:12:40 +08:00
|
|
|
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#endif /* __ASM_POWERPC_CPUFEATURE_H */
|