aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2016-08-31 06:31:09 -0400
committerWill Deacon <will.deacon@arm.com>2016-08-31 08:48:15 -0400
commit6f2b7eeff9dbadeb7366d44086aa34792a996fc9 (patch)
treecd7233c0c346a9551beaf27b5f62533d56e00a6e
parent5e49d73c1d87de50353844d263c1c7664aefeec8 (diff)
arm64: cpufeature: constify arm64_ftr_regs array
Constify the arm64_ftr_regs array, by moving the mutable arm64_ftr_reg fields out of the array itself. This also streamlines the bsearch, since the entire array can be covered by fewer cachelines. Moving the payload out of the array also allows us to have special explicitly defined struct instance in case other code needs to refer to it directly. Note that this replaces the runtime sorting of the array with a runtime BUG() check whether the array is sorted correctly in the code. Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/include/asm/cpufeature.h1
-rw-r--r--arch/arm64/kernel/cpufeature.c46
2 files changed, 20 insertions, 27 deletions
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 7c0b7cff17df..8bb4f1527b26 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -72,7 +72,6 @@ struct arm64_ftr_bits {
72 * @sys_val Safe value across the CPUs (system view) 72 * @sys_val Safe value across the CPUs (system view)
73 */ 73 */
74struct arm64_ftr_reg { 74struct arm64_ftr_reg {
75 u32 sys_id;
76 const char *name; 75 const char *name;
77 u64 strict_mask; 76 u64 strict_mask;
78 u64 sys_val; 77 u64 sys_val;
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index eac76cb3a206..cc7451a27d94 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -265,14 +265,17 @@ static const struct arm64_ftr_bits ftr_aa64raz[] = {
265 ARM64_FTR_END, 265 ARM64_FTR_END,
266}; 266};
267 267
268#define ARM64_FTR_REG(id, table) \ 268#define ARM64_FTR_REG(id, table) { \
269 { \ 269 .sys_id = id, \
270 .sys_id = id, \ 270 .reg = &(struct arm64_ftr_reg){ \
271 .name = #id, \ 271 .name = #id, \
272 .ftr_bits = &((table)[0]), \ 272 .ftr_bits = &((table)[0]), \
273 } 273 }}
274 274
275static struct arm64_ftr_reg arm64_ftr_regs[] = { 275static const struct __ftr_reg_entry {
276 u32 sys_id;
277 struct arm64_ftr_reg *reg;
278} arm64_ftr_regs[] = {
276 279
277 /* Op1 = 0, CRn = 0, CRm = 1 */ 280 /* Op1 = 0, CRn = 0, CRm = 1 */
278 ARM64_FTR_REG(SYS_ID_PFR0_EL1, ftr_id_pfr0), 281 ARM64_FTR_REG(SYS_ID_PFR0_EL1, ftr_id_pfr0),
@@ -324,7 +327,7 @@ static struct arm64_ftr_reg arm64_ftr_regs[] = {
324 327
325static int search_cmp_ftr_reg(const void *id, const void *regp) 328static int search_cmp_ftr_reg(const void *id, const void *regp)
326{ 329{
327 return (int)(unsigned long)id - (int)((const struct arm64_ftr_reg *)regp)->sys_id; 330 return (int)(unsigned long)id - (int)((const struct __ftr_reg_entry *)regp)->sys_id;
328} 331}
329 332
330/* 333/*
@@ -339,11 +342,16 @@ static int search_cmp_ftr_reg(const void *id, const void *regp)
339 */ 342 */
340static struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id) 343static struct arm64_ftr_reg *get_arm64_ftr_reg(u32 sys_id)
341{ 344{
342 return bsearch((const void *)(unsigned long)sys_id, 345 const struct __ftr_reg_entry *ret;
346
347 ret = bsearch((const void *)(unsigned long)sys_id,
343 arm64_ftr_regs, 348 arm64_ftr_regs,
344 ARRAY_SIZE(arm64_ftr_regs), 349 ARRAY_SIZE(arm64_ftr_regs),
345 sizeof(arm64_ftr_regs[0]), 350 sizeof(arm64_ftr_regs[0]),
346 search_cmp_ftr_reg); 351 search_cmp_ftr_reg);
352 if (ret)
353 return ret->reg;
354 return NULL;
347} 355}
348 356
349static u64 arm64_ftr_set_value(const struct arm64_ftr_bits *ftrp, s64 reg, 357static u64 arm64_ftr_set_value(const struct arm64_ftr_bits *ftrp, s64 reg,
@@ -378,27 +386,13 @@ static s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new,
378 return ret; 386 return ret;
379} 387}
380 388
381static int __init sort_cmp_ftr_regs(const void *a, const void *b)
382{
383 return ((const struct arm64_ftr_reg *)a)->sys_id -
384 ((const struct arm64_ftr_reg *)b)->sys_id;
385}
386
387static void __init swap_ftr_regs(void *a, void *b, int size)
388{
389 struct arm64_ftr_reg tmp = *(struct arm64_ftr_reg *)a;
390 *(struct arm64_ftr_reg *)a = *(struct arm64_ftr_reg *)b;
391 *(struct arm64_ftr_reg *)b = tmp;
392}
393
394static void __init sort_ftr_regs(void) 389static void __init sort_ftr_regs(void)
395{ 390{
396 /* Keep the array sorted so that we can do the binary search */ 391 int i;
397 sort(arm64_ftr_regs, 392
398 ARRAY_SIZE(arm64_ftr_regs), 393 /* Check that the array is sorted so that we can do the binary search */
399 sizeof(arm64_ftr_regs[0]), 394 for (i = 1; i < ARRAY_SIZE(arm64_ftr_regs); i++)
400 sort_cmp_ftr_regs, 395 BUG_ON(arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id);
401 swap_ftr_regs);
402} 396}
403 397
404/* 398/*