aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2015-10-16 10:01:04 -0400
committerMax Filippov <jcmvbkbc@gmail.com>2015-11-03 09:19:38 -0500
commitab45fb145096799dabd18afc58bb5f97171017cd (patch)
treec2aacf7f7c4a8961a239cb4ee215610b3eeb0d51
parenta9df9338c1a32e7cdc8c6c6fa7c73f0a63a1ca56 (diff)
xtensa: fix secondary core boot in SMP
There are multiple factors adding to the issue in different configurations: - commit 17290231df16eeee ("xtensa: add fixup for double exception raised in window overflow") added function window_overflow_restore_a0_fixup to double exception vector overlapping reset vector location of secondary processor cores. - on MMUv2 cores RESET_VECTOR1_VADDR may point to uncached kernel memory making code overlapping depend on cache type and size, so that without cache or with WT cache reset vector code overwrites double exception code, making issue even harder to detect. - on MMUv3 cores RESET_VECTOR1_VADDR may point to unmapped area, as MMUv3 cores change virtual address map to match MMUv2 layout, but reset vector virtual address is given for the original MMUv3 mapping. - physical memory region of the secondary reset vector is not reserved in the physical memory map, and thus may be allocated and overwritten at arbitrary moment. Fix it as follows: - move window_overflow_restore_a0_fixup code to .text section. - define RESET_VECTOR1_VADDR so that it points to reset vector in the cacheable MMUv2 map for cores with MMU. - reserve reset vector region in the physical memory map. Drop separate literal section and build mxhead.S with text section literals. Cc: <stable@vger.kernel.org> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r--arch/xtensa/include/asm/vectors.h9
-rw-r--r--arch/xtensa/kernel/Makefile1
-rw-r--r--arch/xtensa/kernel/setup.c9
-rw-r--r--arch/xtensa/kernel/vectors.S4
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S12
5 files changed, 19 insertions, 16 deletions
diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h
index e34eaecc9f3d..d3e6d2eff783 100644
--- a/arch/xtensa/include/asm/vectors.h
+++ b/arch/xtensa/include/asm/vectors.h
@@ -61,6 +61,9 @@ static inline unsigned long xtensa_get_kio_paddr(void)
61 #define LOAD_MEMORY_ADDRESS 0xD0003000 61 #define LOAD_MEMORY_ADDRESS 0xD0003000
62#endif 62#endif
63 63
64#define RESET_VECTOR1_VADDR (VIRTUAL_MEMORY_ADDRESS + \
65 XCHAL_RESET_VECTOR1_PADDR)
66
64#else /* !defined(CONFIG_MMU) */ 67#else /* !defined(CONFIG_MMU) */
65 /* MMU Not being used - Virtual == Physical */ 68 /* MMU Not being used - Virtual == Physical */
66 69
@@ -73,6 +76,8 @@ static inline unsigned long xtensa_get_kio_paddr(void)
73 /* Loaded just above possibly live vectors */ 76 /* Loaded just above possibly live vectors */
74 #define LOAD_MEMORY_ADDRESS (PLATFORM_DEFAULT_MEM_START + 0x3000) 77 #define LOAD_MEMORY_ADDRESS (PLATFORM_DEFAULT_MEM_START + 0x3000)
75 78
79#define RESET_VECTOR1_VADDR (XCHAL_RESET_VECTOR1_VADDR)
80
76#endif /* CONFIG_MMU */ 81#endif /* CONFIG_MMU */
77 82
78#define XC_VADDR(offset) (VIRTUAL_MEMORY_ADDRESS + offset) 83#define XC_VADDR(offset) (VIRTUAL_MEMORY_ADDRESS + offset)
@@ -84,10 +89,6 @@ static inline unsigned long xtensa_get_kio_paddr(void)
84 VECBASE_RESET_VADDR) 89 VECBASE_RESET_VADDR)
85#define RESET_VECTOR_VADDR XC_VADDR(RESET_VECTOR_VECOFS) 90#define RESET_VECTOR_VADDR XC_VADDR(RESET_VECTOR_VECOFS)
86 91
87#define RESET_VECTOR1_VECOFS (XCHAL_RESET_VECTOR1_VADDR - \
88 VECBASE_RESET_VADDR)
89#define RESET_VECTOR1_VADDR XC_VADDR(RESET_VECTOR1_VECOFS)
90
91#if defined(XCHAL_HAVE_VECBASE) && XCHAL_HAVE_VECBASE 92#if defined(XCHAL_HAVE_VECBASE) && XCHAL_HAVE_VECBASE
92 93
93#define USER_VECTOR_VADDR XC_VADDR(XCHAL_USER_VECOFS) 94#define USER_VECTOR_VADDR XC_VADDR(XCHAL_USER_VECOFS)
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 50137bc9e150..4db730290d2d 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_SMP) += smp.o mxhead.o
16obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o 16obj-$(CONFIG_XTENSA_VARIANT_HAVE_PERF_EVENTS) += perf_event.o
17 17
18AFLAGS_head.o += -mtext-section-literals 18AFLAGS_head.o += -mtext-section-literals
19AFLAGS_mxhead.o += -mtext-section-literals
19 20
20# In the Xtensa architecture, assembly generates literals which must always 21# In the Xtensa architecture, assembly generates literals which must always
21# precede the L32R instruction with a relative offset less than 256 kB. 22# precede the L32R instruction with a relative offset less than 256 kB.
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 149d372a9350..9735691f37f1 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -334,7 +334,10 @@ extern char _Level5InterruptVector_text_end;
334extern char _Level6InterruptVector_text_start; 334extern char _Level6InterruptVector_text_start;
335extern char _Level6InterruptVector_text_end; 335extern char _Level6InterruptVector_text_end;
336#endif 336#endif
337 337#ifdef CONFIG_SMP
338extern char _SecondaryResetVector_text_start;
339extern char _SecondaryResetVector_text_end;
340#endif
338 341
339 342
340#ifdef CONFIG_S32C1I_SELFTEST 343#ifdef CONFIG_S32C1I_SELFTEST
@@ -506,6 +509,10 @@ void __init setup_arch(char **cmdline_p)
506 __pa(&_Level6InterruptVector_text_end), 0); 509 __pa(&_Level6InterruptVector_text_end), 0);
507#endif 510#endif
508 511
512#ifdef CONFIG_SMP
513 mem_reserve(__pa(&_SecondaryResetVector_text_start),
514 __pa(&_SecondaryResetVector_text_end), 0);
515#endif
509 parse_early_param(); 516 parse_early_param();
510 bootmem_init(); 517 bootmem_init();
511 518
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index abcdb527f18a..fc25318e75ad 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -478,6 +478,9 @@ _DoubleExceptionVector_handle_exception:
478 478
479ENDPROC(_DoubleExceptionVector) 479ENDPROC(_DoubleExceptionVector)
480 480
481 .end literal_prefix
482
483 .text
481/* 484/*
482 * Fixup handler for TLB miss in double exception handler for window owerflow. 485 * Fixup handler for TLB miss in double exception handler for window owerflow.
483 * We get here with windowbase set to the window that was being spilled and 486 * We get here with windowbase set to the window that was being spilled and
@@ -587,7 +590,6 @@ ENTRY(window_overflow_restore_a0_fixup)
587 590
588ENDPROC(window_overflow_restore_a0_fixup) 591ENDPROC(window_overflow_restore_a0_fixup)
589 592
590 .end literal_prefix
591/* 593/*
592 * Debug interrupt vector 594 * Debug interrupt vector
593 * 595 *
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index fc1bc2ba8d5d..d66cd408be13 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -166,8 +166,6 @@ SECTIONS
166 RELOCATE_ENTRY(_DebugInterruptVector_text, 166 RELOCATE_ENTRY(_DebugInterruptVector_text,
167 .DebugInterruptVector.text); 167 .DebugInterruptVector.text);
168#if defined(CONFIG_SMP) 168#if defined(CONFIG_SMP)
169 RELOCATE_ENTRY(_SecondaryResetVector_literal,
170 .SecondaryResetVector.literal);
171 RELOCATE_ENTRY(_SecondaryResetVector_text, 169 RELOCATE_ENTRY(_SecondaryResetVector_text,
172 .SecondaryResetVector.text); 170 .SecondaryResetVector.text);
173#endif 171#endif
@@ -282,17 +280,11 @@ SECTIONS
282 280
283#if defined(CONFIG_SMP) 281#if defined(CONFIG_SMP)
284 282
285 SECTION_VECTOR (_SecondaryResetVector_literal,
286 .SecondaryResetVector.literal,
287 RESET_VECTOR1_VADDR - 4,
288 SIZEOF(.DoubleExceptionVector.text),
289 .DoubleExceptionVector.text)
290
291 SECTION_VECTOR (_SecondaryResetVector_text, 283 SECTION_VECTOR (_SecondaryResetVector_text,
292 .SecondaryResetVector.text, 284 .SecondaryResetVector.text,
293 RESET_VECTOR1_VADDR, 285 RESET_VECTOR1_VADDR,
294 4, 286 SIZEOF(.DoubleExceptionVector.text),
295 .SecondaryResetVector.literal) 287 .DoubleExceptionVector.text)
296 288
297 . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text); 289 . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
298 290