qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 3/3] m68k: fix usp processing on interrupt entry


From: Peter Crosthwaite
Subject: Re: [Qemu-devel] [PATCH 3/3] m68k: fix usp processing on interrupt entry and exception exit
Date: Thu, 18 Jun 2015 23:51:55 -0700

On Thu, Jun 18, 2015 at 11:49 PM, Greg Ungerer <address@hidden> wrote:
> Hi Peter,
>
> On 19/06/15 15:49, Peter Crosthwaite wrote:
>> On Mon, Aug 18, 2014 at 10:37 PM,  <address@hidden> wrote:
>>> From: Greg Ungerer <address@hidden>
>>>
>>> The action to potentially switch sp register is not occurring at the correct
>>> point in the interrupt entry or exception exit sequences.
>>>
>>> For the interrupt entry case the sp on entry is used to create the stack
>>> exception frame - but this may well be the user stack pointer, since we
>>> haven't done the switch yet. Re-order the flow to switch the sp regs then
>>> use the current sp to create the exception frame.
>>>
>>
>> So I see the bug. The existing code is definitely bogus, that in both
>> int and ret the, newly switched SP is overwitten by a stale one that
>> has just been used. The actual stack push and pop logic happens after
>> and before the switch for int and ret respectively so it is pretty
>> clear the author intended the stacking to happen on the supervisors
>> stack. Is this mandated by the spec one way or the other or is it up
>> to implementation which stack these values are stored on? I can see it
>> could work both ways.
>
> There is 2 cases to deal with.
>
> 1. Early ColdFire parts only had a single stack pointer (a7).
>    There is no notion of swapping to a supervisor stack in this case.
>    All ColdFire parts power up in this mode, only a single stack pointer.
>    This mode works with the existing qemu code.
>
> 2. Later model ColdFire's introduced the conventional m68k user and
>    supervisor stack pointers. It is enabled via a mode bit in the
>    CPU CACR register. Once the EUSP bit is enabled then on interrupt
>    and exception the ColdFire reference manual states that "The processor
>    saves the current context by creating an exception stack frame on the
>    system stack". So it must be on the supervisor stack, using the
>    supervisor stack pointer.
>
> Case 2 is what this patch fixes.
>
>
>>> For the return from exception case the code is unwinding the sp after
>>> switching sp registers. But it should always unwind the supervisor sp
>>> first, then carry out any required sp switch.
>>>
>>> Note that these problems don't effect operation unless the user sp bit is
>>> set in the CACR register. Only a single sp is used in the default power up
>>> state. Previously Linux only used this single sp mode. But modern versions
>>> of Linux use the user sp mode now, so we need correct behavior for Linux
>>> to work.
>>>
>>> Signed-off-by: Greg Ungerer <address@hidden>
>>> ---
>>>  target-m68k/op_helper.c | 7 +++----
>>>  1 file changed, 3 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
>>> index 9dd3e74..cd748b8 100644
>>> --- a/target-m68k/op_helper.c
>>> +++ b/target-m68k/op_helper.c
>>> @@ -63,8 +63,8 @@ static void do_rte(CPUM68KState *env)
>>>      env->pc = cpu_ldl_kernel(env, sp + 4);
>>>      sp |= (fmt >> 28) & 3;
>>>      env->sr = fmt & 0xffff;
>>> -    m68k_switch_sp(env);
>>>      env->aregs[7] = sp + 8;
>>> +    m68k_switch_sp(env);
>>>  }
>>>
>>>  static void do_interrupt_all(CPUM68KState *env, int is_hw)
>>> @@ -108,10 +108,7 @@ static void do_interrupt_all(CPUM68KState *env, int 
>>> is_hw)
>>>
>>>      vector = cs->exception_index << 2;
>>>
>>> -    sp = env->aregs[7];
>>> -
>>>      fmt |= 0x40000000;
>>> -    fmt |= (sp & 3) << 28;
>>>      fmt |= vector << 16;
>>>      fmt |= env->sr;
>>
>> You should move them all to keep them together.
>
> We need to get at least env->sr into fmt here, before we modify
> it in steps immediately after this. At least if we don't want
> to save env->sr locally to use later.
>

Ahh yes I see. No change needed then.

Regards,
Peter

>
>> Otherwise,
>>
>> Reviewed-by: Peter Crosthwaite <address@hidden>
>
> Thanks for the review.
>
> Regards
> Greg
>
>
>
>>> @@ -121,6 +118,8 @@ static void do_interrupt_all(CPUM68KState *env, int 
>>> is_hw)
>>>          env->sr &= ~SR_M;
>>>      }
>>>      m68k_switch_sp(env);
>>> +    sp = env->aregs[7];
>>> +    fmt |= (sp & 3) << 28;
>>>
>>>      /* ??? This could cause MMU faults.  */
>>>      sp &= ~3;
>>> --
>>> 1.9.1
>>>
>>>
>>
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]