Skip to content

Commit 29ae8a6

Browse files
committed
Merge tag 'xtensa-next-20140721' of git://github.com/czankel/xtensa-linux
Pull Xtensa fixes from Chris Zankel: - resolve FIXMEs in double exception handler for window overflow. This fix makes native building of linux on xtensa host possible; - fix sysmem region removal issue introduced in 3.15. * tag 'xtensa-next-20140721' of git://github.com/czankel/xtensa-linux: xtensa: fix sysmem reservation at the end of existing block xtensa: add fixup for double exception raised in window overflow
2 parents 02ec474 + 4ed2ad3 commit 29ae8a6

File tree

3 files changed

+139
-25
lines changed

3 files changed

+139
-25
lines changed

arch/xtensa/kernel/vectors.S

Lines changed: 136 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -376,38 +376,42 @@ _DoubleExceptionVector_WindowOverflow:
376376
beqz a2, 1f # if at start of vector, don't restore
377377

378378
addi a0, a0, -128
379-
bbsi a0, 8, 1f # don't restore except for overflow 8 and 12
380-
bbsi a0, 7, 2f
379+
bbsi.l a0, 8, 1f # don't restore except for overflow 8 and 12
380+
381+
/*
382+
* This fixup handler is for the extremely unlikely case where the
383+
* overflow handler's reference thru a0 gets a hardware TLB refill
384+
* that bumps out the (distinct, aliasing) TLB entry that mapped its
385+
* prior references thru a9/a13, and where our reference now thru
386+
* a9/a13 gets a 2nd-level miss exception (not hardware TLB refill).
387+
*/
388+
movi a2, window_overflow_restore_a0_fixup
389+
s32i a2, a3, EXC_TABLE_FIXUP
390+
l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
391+
xsr a3, excsave1
392+
393+
bbsi.l a0, 7, 2f
381394

382395
/*
383396
* Restore a0 as saved by _WindowOverflow8().
384-
*
385-
* FIXME: we really need a fixup handler for this L32E,
386-
* for the extremely unlikely case where the overflow handler's
387-
* reference thru a0 gets a hardware TLB refill that bumps out
388-
* the (distinct, aliasing) TLB entry that mapped its prior
389-
* references thru a9, and where our reference now thru a9
390-
* gets a 2nd-level miss exception (not hardware TLB refill).
391397
*/
392398

393-
l32e a2, a9, -16
394-
wsr a2, depc # replace the saved a0
395-
j 1f
399+
l32e a0, a9, -16
400+
wsr a0, depc # replace the saved a0
401+
j 3f
396402

397403
2:
398404
/*
399405
* Restore a0 as saved by _WindowOverflow12().
400-
*
401-
* FIXME: we really need a fixup handler for this L32E,
402-
* for the extremely unlikely case where the overflow handler's
403-
* reference thru a0 gets a hardware TLB refill that bumps out
404-
* the (distinct, aliasing) TLB entry that mapped its prior
405-
* references thru a13, and where our reference now thru a13
406-
* gets a 2nd-level miss exception (not hardware TLB refill).
407406
*/
408407

409-
l32e a2, a13, -16
410-
wsr a2, depc # replace the saved a0
408+
l32e a0, a13, -16
409+
wsr a0, depc # replace the saved a0
410+
3:
411+
xsr a3, excsave1
412+
movi a0, 0
413+
s32i a0, a3, EXC_TABLE_FIXUP
414+
s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
411415
1:
412416
/*
413417
* Restore WindowBase while leaving all address registers restored.
@@ -449,6 +453,7 @@ _DoubleExceptionVector_WindowOverflow:
449453

450454
s32i a0, a2, PT_DEPC
451455

456+
_DoubleExceptionVector_handle_exception:
452457
addx4 a0, a0, a3
453458
l32i a0, a0, EXC_TABLE_FAST_USER
454459
xsr a3, excsave1
@@ -464,10 +469,119 @@ _DoubleExceptionVector_WindowOverflow:
464469
rotw -3
465470
j 1b
466471

467-
.end literal_prefix
468472

469473
ENDPROC(_DoubleExceptionVector)
470474

475+
/*
476+
* Fixup handler for TLB miss in double exception handler for window owerflow.
477+
* We get here with windowbase set to the window that was being spilled and
478+
* a0 trashed. a0 bit 7 determines if this is a call8 (bit clear) or call12
479+
* (bit set) window.
480+
*
481+
* We do the following here:
482+
* - go to the original window retaining a0 value;
483+
* - set up exception stack to return back to appropriate a0 restore code
484+
* (we'll need to rotate window back and there's no place to save this
485+
* information, use different return address for that);
486+
* - handle the exception;
487+
* - go to the window that was being spilled;
488+
* - set up window_overflow_restore_a0_fixup as a fixup routine;
489+
* - reload a0;
490+
* - restore the original window;
491+
* - reset the default fixup routine;
492+
* - return to user. By the time we get to this fixup handler all information
493+
* about the conditions of the original double exception that happened in
494+
* the window overflow handler is lost, so we just return to userspace to
495+
* retry overflow from start.
496+
*
497+
* a0: value of depc, original value in depc
498+
* a2: trashed, original value in EXC_TABLE_DOUBLE_SAVE
499+
* a3: exctable, original value in excsave1
500+
*/
501+
502+
ENTRY(window_overflow_restore_a0_fixup)
503+
504+
rsr a0, ps
505+
extui a0, a0, PS_OWB_SHIFT, PS_OWB_WIDTH
506+
rsr a2, windowbase
507+
sub a0, a2, a0
508+
extui a0, a0, 0, 3
509+
l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
510+
xsr a3, excsave1
511+
512+
_beqi a0, 1, .Lhandle_1
513+
_beqi a0, 3, .Lhandle_3
514+
515+
.macro overflow_fixup_handle_exception_pane n
516+
517+
rsr a0, depc
518+
rotw -\n
519+
520+
xsr a3, excsave1
521+
wsr a2, depc
522+
l32i a2, a3, EXC_TABLE_KSTK
523+
s32i a0, a2, PT_AREG0
524+
525+
movi a0, .Lrestore_\n
526+
s32i a0, a2, PT_DEPC
527+
rsr a0, exccause
528+
j _DoubleExceptionVector_handle_exception
529+
530+
.endm
531+
532+
overflow_fixup_handle_exception_pane 2
533+
.Lhandle_1:
534+
overflow_fixup_handle_exception_pane 1
535+
.Lhandle_3:
536+
overflow_fixup_handle_exception_pane 3
537+
538+
.macro overflow_fixup_restore_a0_pane n
539+
540+
rotw \n
541+
/* Need to preserve a0 value here to be able to handle exception
542+
* that may occur on a0 reload from stack. It may occur because
543+
* TLB miss handler may not be atomic and pointer to page table
544+
* may be lost before we get here. There are no free registers,
545+
* so we need to use EXC_TABLE_DOUBLE_SAVE area.
546+
*/
547+
xsr a3, excsave1
548+
s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
549+
movi a2, window_overflow_restore_a0_fixup
550+
s32i a2, a3, EXC_TABLE_FIXUP
551+
l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
552+
xsr a3, excsave1
553+
bbsi.l a0, 7, 1f
554+
l32e a0, a9, -16
555+
j 2f
556+
1:
557+
l32e a0, a13, -16
558+
2:
559+
rotw -\n
560+
561+
.endm
562+
563+
.Lrestore_2:
564+
overflow_fixup_restore_a0_pane 2
565+
566+
.Lset_default_fixup:
567+
xsr a3, excsave1
568+
s32i a2, a3, EXC_TABLE_DOUBLE_SAVE
569+
movi a2, 0
570+
s32i a2, a3, EXC_TABLE_FIXUP
571+
l32i a2, a3, EXC_TABLE_DOUBLE_SAVE
572+
xsr a3, excsave1
573+
rfe
574+
575+
.Lrestore_1:
576+
overflow_fixup_restore_a0_pane 1
577+
j .Lset_default_fixup
578+
.Lrestore_3:
579+
overflow_fixup_restore_a0_pane 3
580+
j .Lset_default_fixup
581+
582+
ENDPROC(window_overflow_restore_a0_fixup)
583+
584+
.end literal_prefix
471585
/*
472586
* Debug interrupt vector
473587
*

arch/xtensa/kernel/vmlinux.lds.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,13 @@ SECTIONS
269269
.UserExceptionVector.literal)
270270
SECTION_VECTOR (_DoubleExceptionVector_literal,
271271
.DoubleExceptionVector.literal,
272-
DOUBLEEXC_VECTOR_VADDR - 16,
272+
DOUBLEEXC_VECTOR_VADDR - 40,
273273
SIZEOF(.UserExceptionVector.text),
274274
.UserExceptionVector.text)
275275
SECTION_VECTOR (_DoubleExceptionVector_text,
276276
.DoubleExceptionVector.text,
277277
DOUBLEEXC_VECTOR_VADDR,
278-
32,
278+
40,
279279
.DoubleExceptionVector.literal)
280280

281281
. = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;

arch/xtensa/mm/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
191191
return -EINVAL;
192192
}
193193

194-
if (it && start - it->start < bank_sz) {
194+
if (it && start - it->start <= bank_sz) {
195195
if (start == it->start) {
196196
if (end - it->start < bank_sz) {
197197
it->start = end;

0 commit comments

Comments
 (0)