lowlevel-z80: set insys when pre-empting, fix a scribble in some modes
authorAlan Cox <alan@linux.intel.com>
Fri, 17 Jul 2015 22:27:53 +0000 (23:27 +0100)
committerAlan Cox <alan@linux.intel.com>
Fri, 17 Jul 2015 22:27:53 +0000 (23:27 +0100)
We must update the udata before mapping process memory as we are not
guaranteed that won't vanish the udata.

Set u_insys so that the following case cannot occur once we begin loosening
irq disabled areas

IRQ
pre-empt
ei
swapper()

IRQ
pre-empt
*boom*

Kernel/lowlevel-z80-banked.s
Kernel/lowlevel-z80.s

index 95c72ed..a323d34 100644 (file)
@@ -516,6 +516,14 @@ preemption:
 
        ;
 intret2:call map_kernel
+
+       ;
+       ; Semantically we are doing a null syscall for pre-empt. We need
+       ; to record ourselves as in a syscall so we can't be recursively
+       ; pre-empted when switchout re-enables interrupts.
+       ;
+       ld a, #1
+       ld (U_DATA__U_INSYS), a
        ;
        ; Process status is offset 0
        ;
@@ -523,15 +531,17 @@ intret2:call map_kernel
        ld (hl), #P_READY
        call _switchout
        ;
+       ; We are no longer in an interrupt or a syscall
+       ;
+       xor a
+       ld (U_DATA__U_ININTERRUPT), a
+       ld (U_DATA__U_INSYS), a
+       ;
        ; We have been rescheduled, remap ourself and go back to user
        ; space via signal handling
        ;
        call map_process_always ; Get our user mapping back
 
-       ; We are no longer in an interrupt
-       xor a
-       ld (U_DATA__U_ININTERRUPT), a
-
        ; We were pre-empted but have now been rescheduled
        ; User stack
        ld sp, (U_DATA__U_SYSCALL_SP)
index f8499bf..094787e 100644 (file)
@@ -508,6 +508,14 @@ preemption:
 
        ;
 intret2:call map_kernel
+
+       ;
+       ; Semantically we are doing a null syscall for pre-empt. We need
+       ; to record ourselves as in a syscall so we can't be recursively
+       ; pre-empted when switchout re-enables interrupts.
+       ;
+       ld a, #1
+       ld (U_DATA__U_INSYS), a
        ;
        ; Process status is offset 0
        ;
@@ -515,14 +523,17 @@ intret2:call map_kernel
        ld (hl), #P_READY
        call _switchout
        ;
+       ; We are no longer in an interrupt or a syscall
+       ;
+       xor a
+       ld (U_DATA__U_ININTERRUPT), a
+       ld (U_DATA__U_INSYS), a
+       ;
        ; We have been rescheduled, remap ourself and go back to user
        ; space via signal handling
        ;
        call map_process_always ; Get our user mapping back
 
-       ; We are no longer in an interrupt
-       xor a
-       ld (U_DATA__U_ININTERRUPT), a
 
        ; We were pre-empted but have now been rescheduled
        ; User stack