summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2014-09-10 22:03:35 +0200
committerRichard Braun <rbraun@sceen.net>2014-09-10 22:03:35 +0200
commitc1e776e211b9f365c2f7eb66614a00621ba36dfb (patch)
treeb1f39379112cfc6d58867d87acd37c97c4567f4b
parent6afbd6025745415fa984906291d7d2ed1f9f2f9b (diff)
x86/pmap: fix initialization of percpu variables
Application processors should never initialize data that are shared with other processors. In this case, it leaded to a race which could make pmap_update access uninitialized percpu data. But, since percpu areas are initially copies of the percpu section (which is the percpu area of the main processor), uninitialized percpu variables would actually have valid values, those inherited from the main processor. This would result in hard-to-debug data corruption.
-rw-r--r--arch/x86/machine/pmap.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/x86/machine/pmap.c b/arch/x86/machine/pmap.c
index f840f0b2..de9eb537 100644
--- a/arch/x86/machine/pmap.c
+++ b/arch/x86/machine/pmap.c
@@ -788,11 +788,6 @@ pmap_ap_bootstrap(void)
{
cpu_local_assign(pmap_current_ptr, kernel_pmap);
- pmap_tmp_mapping_init(cpu_local_ptr(pmap_zero_mapping), pmap_zero_va);
- pmap_tmp_mapping_init(cpu_local_ptr(pmap_ptp_mapping), pmap_ptp_va);
- pmap_update_request_array_init(cpu_local_ptr(pmap_update_request_array));
- pmap_syncer_init(cpu_local_ptr(pmap_syncer), cpu_id());
-
if (cpu_has_global_pages())
cpu_enable_global_pages();
else
@@ -1112,7 +1107,16 @@ pmap_mp_setup(void)
if (error)
panic("pmap: unable to create syncer cpumap");
+ for (cpu = 1; cpu < cpu_count(); cpu++) {
+ pmap_tmp_mapping_init(percpu_ptr(pmap_zero_mapping, cpu), pmap_zero_va);
+ pmap_tmp_mapping_init(percpu_ptr(pmap_ptp_mapping, cpu), pmap_ptp_va);
+ pmap_update_request_array_init(percpu_ptr(pmap_update_request_array,
+ cpu));
+ pmap_syncer_init(percpu_ptr(pmap_syncer, cpu), cpu);
+ }
+
for (cpu = 0; cpu < cpu_count(); cpu++) {
+
syncer = percpu_ptr(pmap_syncer, cpu);
snprintf(name, sizeof(name), "x15_pmap_sync/%u", cpu);
cpumap_zero(cpumap);