diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-22 14:11:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-04-22 14:11:15 -0400 |
commit | ddce192106e4f984123884f8e878f66ace94b573 (patch) | |
tree | 429046f933703c2b950f5a37ad9b954d03fb00c7 | |
parent | ff061624e1afad3b556fcc8df23898014b47bc7e (diff) | |
parent | 882416c1e4d1c9d4c7b50e0f5c3fa9ef043cd710 (diff) |
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 fixes from Catalin Marinas:
- Cache invalidation fix for early CPU boot status update (incorrect
cacheline)
- of_put_node() missing in the spin_table code
- EL1/El2 early init inconsistency when Virtualisation Host Extensions
are present
- RCU warning fix in the arm_pmu.c driver
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: Fix EL1/EL2 early init inconsistencies with VHE
drivers/perf: arm-pmu: fix RCU usage on pmu resume from low-power
arm64: spin-table: add missing of_node_put()
arm64: fix invalidation of wrong __early_cpu_boot_status cacheline
-rw-r--r-- | arch/arm64/kernel/head.S | 13 | ||||
-rw-r--r-- | arch/arm64/kernel/smp_spin_table.c | 11 | ||||
-rw-r--r-- | drivers/perf/arm_pmu.c | 15 |
3 files changed, 31 insertions, 8 deletions
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index 4203d5f257bc..85da0f599cd6 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S | |||
@@ -588,6 +588,15 @@ set_hcr: | |||
588 | msr vpidr_el2, x0 | 588 | msr vpidr_el2, x0 |
589 | msr vmpidr_el2, x1 | 589 | msr vmpidr_el2, x1 |
590 | 590 | ||
591 | /* | ||
592 | * When VHE is not in use, early init of EL2 and EL1 needs to be | ||
593 | * done here. | ||
594 | * When VHE _is_ in use, EL1 will not be used in the host and | ||
595 | * requires no configuration, and all non-hyp-specific EL2 setup | ||
596 | * will be done via the _EL1 system register aliases in __cpu_setup. | ||
597 | */ | ||
598 | cbnz x2, 1f | ||
599 | |||
591 | /* sctlr_el1 */ | 600 | /* sctlr_el1 */ |
592 | mov x0, #0x0800 // Set/clear RES{1,0} bits | 601 | mov x0, #0x0800 // Set/clear RES{1,0} bits |
593 | CPU_BE( movk x0, #0x33d0, lsl #16 ) // Set EE and E0E on BE systems | 602 | CPU_BE( movk x0, #0x33d0, lsl #16 ) // Set EE and E0E on BE systems |
@@ -597,6 +606,7 @@ CPU_LE( movk x0, #0x30d0, lsl #16 ) // Clear EE and E0E on LE systems | |||
597 | /* Coprocessor traps. */ | 606 | /* Coprocessor traps. */ |
598 | mov x0, #0x33ff | 607 | mov x0, #0x33ff |
599 | msr cptr_el2, x0 // Disable copro. traps to EL2 | 608 | msr cptr_el2, x0 // Disable copro. traps to EL2 |
609 | 1: | ||
600 | 610 | ||
601 | #ifdef CONFIG_COMPAT | 611 | #ifdef CONFIG_COMPAT |
602 | msr hstr_el2, xzr // Disable CP15 traps to EL2 | 612 | msr hstr_el2, xzr // Disable CP15 traps to EL2 |
@@ -734,7 +744,8 @@ ENDPROC(__secondary_switched) | |||
734 | 744 | ||
735 | .macro update_early_cpu_boot_status status, tmp1, tmp2 | 745 | .macro update_early_cpu_boot_status status, tmp1, tmp2 |
736 | mov \tmp2, #\status | 746 | mov \tmp2, #\status |
737 | str_l \tmp2, __early_cpu_boot_status, \tmp1 | 747 | adr_l \tmp1, __early_cpu_boot_status |
748 | str \tmp2, [\tmp1] | ||
738 | dmb sy | 749 | dmb sy |
739 | dc ivac, \tmp1 // Invalidate potentially stale cache line | 750 | dc ivac, \tmp1 // Invalidate potentially stale cache line |
740 | .endm | 751 | .endm |
diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c index aef3605a8c47..18a71bcd26ee 100644 --- a/arch/arm64/kernel/smp_spin_table.c +++ b/arch/arm64/kernel/smp_spin_table.c | |||
@@ -52,6 +52,7 @@ static void write_pen_release(u64 val) | |||
52 | static int smp_spin_table_cpu_init(unsigned int cpu) | 52 | static int smp_spin_table_cpu_init(unsigned int cpu) |
53 | { | 53 | { |
54 | struct device_node *dn; | 54 | struct device_node *dn; |
55 | int ret; | ||
55 | 56 | ||
56 | dn = of_get_cpu_node(cpu, NULL); | 57 | dn = of_get_cpu_node(cpu, NULL); |
57 | if (!dn) | 58 | if (!dn) |
@@ -60,15 +61,15 @@ static int smp_spin_table_cpu_init(unsigned int cpu) | |||
60 | /* | 61 | /* |
61 | * Determine the address from which the CPU is polling. | 62 | * Determine the address from which the CPU is polling. |
62 | */ | 63 | */ |
63 | if (of_property_read_u64(dn, "cpu-release-addr", | 64 | ret = of_property_read_u64(dn, "cpu-release-addr", |
64 | &cpu_release_addr[cpu])) { | 65 | &cpu_release_addr[cpu]); |
66 | if (ret) | ||
65 | pr_err("CPU %d: missing or invalid cpu-release-addr property\n", | 67 | pr_err("CPU %d: missing or invalid cpu-release-addr property\n", |
66 | cpu); | 68 | cpu); |
67 | 69 | ||
68 | return -1; | 70 | of_node_put(dn); |
69 | } | ||
70 | 71 | ||
71 | return 0; | 72 | return ret; |
72 | } | 73 | } |
73 | 74 | ||
74 | static int smp_spin_table_cpu_prepare(unsigned int cpu) | 75 | static int smp_spin_table_cpu_prepare(unsigned int cpu) |
diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 32346b5a8a11..f70090897fdf 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c | |||
@@ -737,8 +737,19 @@ static void cpu_pm_pmu_setup(struct arm_pmu *armpmu, unsigned long cmd) | |||
737 | break; | 737 | break; |
738 | case CPU_PM_EXIT: | 738 | case CPU_PM_EXIT: |
739 | case CPU_PM_ENTER_FAILED: | 739 | case CPU_PM_ENTER_FAILED: |
740 | /* Restore and enable the counter */ | 740 | /* |
741 | armpmu_start(event, PERF_EF_RELOAD); | 741 | * Restore and enable the counter. |
742 | * armpmu_start() indirectly calls | ||
743 | * | ||
744 | * perf_event_update_userpage() | ||
745 | * | ||
746 | * that requires RCU read locking to be functional, | ||
747 | * wrap the call within RCU_NONIDLE to make the | ||
748 | * RCU subsystem aware this cpu is not idle from | ||
749 | * an RCU perspective for the armpmu_start() call | ||
750 | * duration. | ||
751 | */ | ||
752 | RCU_NONIDLE(armpmu_start(event, PERF_EF_RELOAD)); | ||
742 | break; | 753 | break; |
743 | default: | 754 | default: |
744 | break; | 755 | break; |