On 18 September 2015 at 16:25, Heyi Guo <heyi....@linaro.org> wrote:
> Hi Ard,
>
> Sorry for the late reply.
>
> However, it seems V7 may not have the some problem, with the reasons below:
>
> 1. It always restores the context and then increase SP (V8 code increases SP
> BEFORE restoring context);
> 2. It stores PC and CPSR to srsfd stack slot:
>   ldr       R1,[SP,#0x3c]           @ EFI_SYSTEM_CONTEXT_ARM.PC
>   str       R1,[SP,#0x58]           @ Store it back to srsfd stack slot so
> it can be restored
>
>   ldr       R1,[SP,#0x40]           @ EFI_SYSTEM_CONTEXT_ARM.CPSR
>   str       R1,[SP,#0x5c]           @ Store it back to srsfd stack slot so
> it can be restored
>
> 3. it restores PC and CPSR in the LAST ONE instruction (Is it atomic and not
> able to be interrupted?):
>   rfefd     SP!                     @ return from exception via srsfd stack
> slot
>
> So I think V7 does not have the same problem as V8. After all, I'm NOT
> familiar with V7 and not sure about it.
>
> Please let me know your comments.
>

As discussed, I think your analysis is correct. All manipulations of
the stack should be safe to interruptions, and the actual return is
done by a single instruction. IOW, the critical region is only one
instruction, which [hopefully] means we don't have to disable
interrupts when we execute it.

So I am happy with the patch, and if Leif agrees, I will go ahead and
apply it (I can fix up the comment myself)

Leif?

Thanks,
Ard.


> On 08/24/2015 07:05 PM, Ard Biesheuvel wrote:
>>
>> On 23 August 2015 at 17:59, Ard Biesheuvel <ard.biesheu...@linaro.org>
>> wrote:
>>>
>>> On 23 August 2015 at 15:39, Heyi Guo <heyi....@linaro.org> wrote:
>>>>
>>>>
>>>> On 08/17/2015 05:52 PM, Ard Biesheuvel wrote:
>>>>>
>>>>> On 13 August 2015 at 05:10, Heyi Guo<heyi....@linaro.org>  wrote:
>>>>>>
>>>>>> Interrupt must be disabled before we storing ELR and other system
>>>>>> registers, or else ELR will be overridden by interrupt reentrance.
>>>>>>
>>>>>> This bug is critical as we may get occasional exception or dead loop
>>>>>> when interrupt reentrance occurs:
>>>>>>
>>>>>>     After increasing SP ... Before popping out registers
>>>>>> Or
>>>>>>     After restoring ELR
>>>>>>
>>>>>> The 1st circumstance could also be resolved by optimizing SP operation
>>>>>> (Pop out registers before adding SP back), but the 2nd could not be
>>>>>> resolved by disabling interrupt.
>>>>>>
>>>>>> Contributed-under: TianoCore Contribution Agreement 1.0
>>>>>> Signed-off-by: Heyi Guo<heyi....@linaro.org>
>>>>>> Cc: Leif Lindholm<leif.lindh...@linaro.org>
>>>>>> Cc: Ard Biesheuvel<ard.biesheu...@linaro.org>
>>>>>> ---
>>>>>>    ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S | 8 ++++++++
>>>>>>    1 file changed, 8 insertions(+)
>>>>>>
>>>>>> diff --git a/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
>>>>>> b/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
>>>>>> index 2682f4f..ca6c9a1 100644
>>>>>> --- a/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
>>>>>> +++ b/ArmPkg/Drivers/CpuDxe/AArch64/ExceptionSupport.S
>>>>>> @@ -358,6 +358,14 @@ ASM_PFX(AsmCommonExceptionEntry):
>>>>>>    #define REG_PAIR(REG1, REG2, OFFSET, CONTEXT_SIZE)    ldp  REG1,
>>>>>> REG2,
>>>>>> [sp, #(OFFSET-CONTEXT_SIZE)]
>>>>>>    #define REG_ONE(REG1, OFFSET, CONTEXT_SIZE)           ldur REG1,
>>>>>> [sp,
>>>>>> #(OFFSET-CONTEXT_SIZE)]
>>>>>>
>>>>>> +  //
>>>>>> +  // Disable interrupt(IRQ and FIQ) before restoring context,
>>>>>> +  // or else the context will be corrupted by interrupt reentrance.
>>>>>> +  // Interrupt mask will be restored from spsr by hardware when we
>>>>>> call
>>>>>> eret
>>>>>> +  //
>>>>>> +  msr   daifset, #3
>>>>>> +  isb
>>>>>> +
>>>>>
>>>>> Are you sure this is necessary? According to the ARM ARM
>>>>>
>>>>> """
>>>>> On taking any exception to an Exception level using AArch64, all of
>>>>> PSTATE.{A, I, F} are set to 1, masking all
>>>>> interrupts that target that Exception level.
>>>>> """
>>>>
>>>> Yes. However, in timer interrupt handler, we will raise TPL to
>>>> HIGH_LEVEL
>>>> and then restore TPL, while restore TPL will enable interrupt.
>>>>
>>> Is that in the generic ARM timer code? Perhaps we should raise and
>>> lower the TPL in the common interrupt entry/exit path, since the
>>> architecture implicitly raises the TPL by entering the interrupt
>>> handler with interrupts disabled. In general, I don't think it is
>>> correct for TPL lowering code to enable interrupts if it did not find
>>> the enabled when it raised the TPL.
>>>
>>>> So I think we can't avoid interrupt reentering in UEFI architecture and
>>>> need
>>>> protection when restoring interrupt context.
>>>>
>> Yes, it seems you are right. Even though I am not happy with the idea
>> that we are supporting nested interrupts without exactly understanding
>> the implication and without there being a real need (since we use
>> interrupts for the timer tick only), the core does not really allow us
>> to change that for AARCH64 only.
>>
>> So I think your patch is correct. There are still two issues to resolve,
>> though:
>>
>> 1. Could you update the comment in the code to mention that interrupts
>> have been re-enabled by the TPL lowering code, and that we need to
>> disable them again only to protect the critical section that restores
>> the interrupted context from the stack?
>> 2. The 32-bit ARM code appears to suffer from the same problem, so we
>> should fix that as well.
>>
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to