All of lore.kernel.org
 help / color / mirror / Atom feed
From: Colin Cross <ccross@android.com>
To: Russell King - ARM Linux <linux@arm.linux.org.uk>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH] ARM: vfp: Fix up exception location in Thumb mode
Date: Wed, 26 Jan 2011 22:35:03 -0800	[thread overview]
Message-ID: <AANLkTindtGzxnCRK7XZW1jtXRAeBz9cTshqCtTr3qnL7@mail.gmail.com> (raw)
In-Reply-To: <AANLkTim2fPySEMFn+ckrVAvJj8ZXEvBoZpgmZAKOWf=9@mail.gmail.com>

On Wed, Jan 26, 2011 at 10:11 PM, Colin Cross <ccross@android.com> wrote:
> On Wed, Jan 26, 2011 at 3:26 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>> On Tue, Jan 25, 2011 at 03:33:24PM -0800, Colin Cross wrote:
>>> I think there is an additional change needed to
>>> __und_usr_unknown/do_undefinstr.  do_undefinstr, which gets called
>>> directly in __und_usr as well as by mov pc, lr, expects regs->ARM_pc
>>> to be the fault address, and not the next PC, and gets called for 2 or
>>> 4 byte instructions.
>>
>> It expects it to be the next PC:
>>
>> asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
>> {
>>        unsigned int correction = thumb_mode(regs) ? 2 : 4;
>>        unsigned int instr;
>>        siginfo_t info;
>>        void __user *pc;
>>
>>        /*
>>         * According to the ARM ARM, PC is 2 or 4 bytes ahead,
>>         * depending whether we're in Thumb mode or not.
>>         * Correct this offset.
>>         */
>>        regs->ARM_pc -= correction;
>>
>> We expect the PC to be pointing at the next instruction to be executed.
>> This is the value of the PC saved by the CPU when entering the exception.
>> We correct the PC by four bytes for ARM mode to point at the previously
>> executed instruction.
>>
>> For 16-bit Thumb mode, the PC is again pointing at the next instruction
>> to be executed, and this is the value saved by the CPU.  So we correct
>> the PC by two bytes as that is the Thumb instruction size.
>>
>> The problem comes with T2, where we advance the saved PC by two bytes
>> if the instruction was 32-bit such that it again points at the next
>> instruction to be executed.  This is where the problem comes in because
>> we have two different chunks of code with completely different
>> expectations.
>
> All do_undefinstr will do with the correction is subtract it off so
> that pc points to the faulting instruction instead of the next
> instruction, and calls any registered handlers.  VFP_bounce sometimes
> subtracts off 4 (it doesn't care about T2 mode there, because T2 VFP
> instructions are all 32 bit), and sometimes leaves pc pointing at the
> next instruction.  If both were modified to expect the faulting
> instruction's pc, do_undefinstr would leave pc unmodified, and
> VFP_bounce would add 4 in the opposite cases from where it subtracts 4
> now.
>
> iwmmxt_task_enable and crunch_task_enable can also get called from __und_usr.
>
> Currently, iwmmxt_task_enable will either end up in do_undefinstr
> through mov pc, lr, or it will subtract 4 from the pc register value
> and return through ret_from_exception.  With the change above, it
> would not need to modify the pc value at all.
>
> crunch_task_enable is based on iwmmxt_task_enable, and works exactly the same.
>
>> Maybe we need to pass in the correction factor to do_undefinstr instead.
>>
>
> That just makes it even more complicated, the correction factor has to
> be tracked through every code path.
>
> RFC patch to follow.
>

Missed one case.  do_fpe calls into nwfpe_enter (I don't see any other
users of fp_enter), which assumes the PC in the registers on the stack
is faulting PC + 4, ignores r2, and uses r0 as the first instruction
to emulate.  It will need to be slightly modified in my patch.

WARNING: multiple messages have this Message-ID (diff)
From: ccross@android.com (Colin Cross)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] ARM: vfp: Fix up exception location in Thumb mode
Date: Wed, 26 Jan 2011 22:35:03 -0800	[thread overview]
Message-ID: <AANLkTindtGzxnCRK7XZW1jtXRAeBz9cTshqCtTr3qnL7@mail.gmail.com> (raw)
In-Reply-To: <AANLkTim2fPySEMFn+ckrVAvJj8ZXEvBoZpgmZAKOWf=9@mail.gmail.com>

On Wed, Jan 26, 2011 at 10:11 PM, Colin Cross <ccross@android.com> wrote:
> On Wed, Jan 26, 2011 at 3:26 AM, Russell King - ARM Linux
> <linux@arm.linux.org.uk> wrote:
>> On Tue, Jan 25, 2011 at 03:33:24PM -0800, Colin Cross wrote:
>>> I think there is an additional change needed to
>>> __und_usr_unknown/do_undefinstr. ?do_undefinstr, which gets called
>>> directly in __und_usr as well as by mov pc, lr, expects regs->ARM_pc
>>> to be the fault address, and not the next PC, and gets called for 2 or
>>> 4 byte instructions.
>>
>> It expects it to be the next PC:
>>
>> asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
>> {
>> ? ? ? ?unsigned int correction = thumb_mode(regs) ? 2 : 4;
>> ? ? ? ?unsigned int instr;
>> ? ? ? ?siginfo_t info;
>> ? ? ? ?void __user *pc;
>>
>> ? ? ? ?/*
>> ? ? ? ? * According to the ARM ARM, PC is 2 or 4 bytes ahead,
>> ? ? ? ? * depending whether we're in Thumb mode or not.
>> ? ? ? ? * Correct this offset.
>> ? ? ? ? */
>> ? ? ? ?regs->ARM_pc -= correction;
>>
>> We expect the PC to be pointing at the next instruction to be executed.
>> This is the value of the PC saved by the CPU when entering the exception.
>> We correct the PC by four bytes for ARM mode to point at the previously
>> executed instruction.
>>
>> For 16-bit Thumb mode, the PC is again pointing at the next instruction
>> to be executed, and this is the value saved by the CPU. ?So we correct
>> the PC by two bytes as that is the Thumb instruction size.
>>
>> The problem comes with T2, where we advance the saved PC by two bytes
>> if the instruction was 32-bit such that it again points at the next
>> instruction to be executed. ?This is where the problem comes in because
>> we have two different chunks of code with completely different
>> expectations.
>
> All do_undefinstr will do with the correction is subtract it off so
> that pc points to the faulting instruction instead of the next
> instruction, and calls any registered handlers. ?VFP_bounce sometimes
> subtracts off 4 (it doesn't care about T2 mode there, because T2 VFP
> instructions are all 32 bit), and sometimes leaves pc pointing at the
> next instruction. ?If both were modified to expect the faulting
> instruction's pc, do_undefinstr would leave pc unmodified, and
> VFP_bounce would add 4 in the opposite cases from where it subtracts 4
> now.
>
> iwmmxt_task_enable and crunch_task_enable can also get called from __und_usr.
>
> Currently, iwmmxt_task_enable will either end up in do_undefinstr
> through mov pc, lr, or it will subtract 4 from the pc register value
> and return through ret_from_exception. ?With the change above, it
> would not need to modify the pc value at all.
>
> crunch_task_enable is based on iwmmxt_task_enable, and works exactly the same.
>
>> Maybe we need to pass in the correction factor to do_undefinstr instead.
>>
>
> That just makes it even more complicated, the correction factor has to
> be tracked through every code path.
>
> RFC patch to follow.
>

Missed one case.  do_fpe calls into nwfpe_enter (I don't see any other
users of fp_enter), which assumes the PC in the registers on the stack
is faulting PC + 4, ignores r2, and uses r0 as the first instruction
to emulate.  It will need to be slightly modified in my patch.

  reply	other threads:[~2011-01-27  6:35 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-14  7:42 [PATCH] ARM: vfp: Fix up exception location in Thumb mode Colin Cross
2011-01-14  7:42 ` Colin Cross
2011-01-14 11:43 ` Catalin Marinas
2011-01-14 11:43   ` Catalin Marinas
2011-01-14 12:02   ` Russell King - ARM Linux
2011-01-14 12:02     ` Russell King - ARM Linux
2011-01-14 14:10     ` Catalin Marinas
2011-01-14 14:10       ` Catalin Marinas
2011-01-14 15:49       ` Russell King - ARM Linux
2011-01-14 15:49         ` Russell King - ARM Linux
2011-01-14 16:23         ` Catalin Marinas
2011-01-14 16:23           ` Catalin Marinas
2011-01-14 16:35           ` Russell King - ARM Linux
2011-01-14 16:35             ` Russell King - ARM Linux
2011-01-14 16:58             ` Catalin Marinas
2011-01-14 16:58               ` Catalin Marinas
2011-01-14 17:30               ` Russell King - ARM Linux
2011-01-14 17:30                 ` Russell King - ARM Linux
2011-01-14 18:47                 ` Russell King - ARM Linux
2011-01-14 18:47                   ` Russell King - ARM Linux
2011-01-14 19:23                   ` Colin Cross
2011-01-14 19:23                     ` Colin Cross
2011-01-14 19:51                     ` Colin Cross
2011-01-14 19:51                       ` Colin Cross
2011-01-14 21:24                       ` Russell King - ARM Linux
2011-01-14 21:24                         ` Russell King - ARM Linux
2011-01-25 23:33                       ` Colin Cross
2011-01-25 23:33                         ` Colin Cross
2011-01-26 11:26                         ` Russell King - ARM Linux
2011-01-26 11:26                           ` Russell King - ARM Linux
2011-01-27  6:11                           ` Colin Cross
2011-01-27  6:11                             ` Colin Cross
2011-01-27  6:35                             ` Colin Cross [this message]
2011-01-27  6:35                               ` Colin Cross
2011-01-27  7:30                               ` Colin Cross
2011-01-27  7:30                                 ` Colin Cross
2011-02-09 18:12                                 ` Colin Cross
2011-02-09 18:12                                   ` Colin Cross
2011-01-15 15:38                   ` Catalin Marinas
2011-01-15 15:38                     ` Catalin Marinas
2011-01-15 15:43                     ` Russell King - ARM Linux
2011-01-15 15:43                       ` Russell King - ARM Linux
2011-01-16 11:51                       ` Catalin Marinas
2011-01-16 11:51                         ` Catalin Marinas
2011-01-15 15:31                 ` Catalin Marinas
2011-01-15 15:31                   ` Catalin Marinas
2011-01-15 15:40                   ` Russell King - ARM Linux
2011-01-15 15:40                     ` Russell King - ARM Linux
2011-01-16 11:49                     ` Catalin Marinas
2011-01-16 11:49                       ` Catalin Marinas
2011-01-23 15:51                       ` Russell King - ARM Linux
2011-01-23 15:51                         ` Russell King - ARM Linux
2011-01-25 13:19                         ` Catalin Marinas
2011-01-25 13:19                           ` Catalin Marinas
2011-01-16 21:25                     ` Catalin Marinas
2011-01-16 21:25                       ` Catalin Marinas
2011-01-23 15:46                       ` Russell King - ARM Linux
2011-01-23 15:46                         ` Russell King - ARM Linux
2011-01-25 13:45                         ` Catalin Marinas
2011-01-25 13:45                           ` Catalin Marinas
2011-01-14 16:24       ` Dave Martin
2011-01-14 16:24         ` Dave Martin
2011-01-14 16:52         ` Russell King - ARM Linux
2011-01-14 16:52           ` Russell King - ARM Linux

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AANLkTindtGzxnCRK7XZW1jtXRAeBz9cTshqCtTr3qnL7@mail.gmail.com \
    --to=ccross@android.com \
    --cc=catalin.marinas@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.