Re: [RFC PATCH] arm: Don't trap conditional UDF instructions

2020-05-13 Thread Robin Murphy

On 2020-05-13 7:56 pm, Fredrik Strupe wrote:

On 13.05.2020 20:12, Russell King - ARM Linux admin wrote:

On Wed, May 13, 2020 at 05:41:58PM +0200, Fredrik Strupe wrote:

Hi,

This is more of a question than a patch, but I hope the attached patch makes
the issue a bit clearer.

The arm port of Linux supports hooking/trapping of undefined instructions. Some
parts of the code use this to trap UDF instructions with certain immediates in
order to use them for other purposes, like 'UDF #16' which is equivalent to a
BKPT instruction in A32.

Moreover, most of the undef hooks on UDF instructions assume that UDF is
conditional and mask out the condition prefix during matching. The attached
patch shows the locations where this happens. However, the Arm architecture
reference manual explicitly states that UDF is *not* conditional, making
any instruction encoding with a condition prefix other than 0xe (always
execute) unallocated.


The latest version of the ARM architecture reference manual may say
that, but earlier versions say different things. The latest reference
manual does not apply to earlier architectures, so if you're writing
code to cover multiple different architectures, you must have an
understanding of each of those architectures.

So, from the code:

ARM:    0111      

 From DDI0100E:

3.13.1 Undefined instruction space
Instructions with the following opcodes are undefined
instruction space:

opcode[27:25] = 0b011
opcode[4] = 1

31 28 27 26 25 24 5 4 3 0
cond  0  1  1  x  x x x x x x x x x x x x x x x x x x x 1 x x x x

So, in this version of the architecture, undefined instructions may
be conditional - and indeed that used to be the case.  The condition
code was always respected, and cond= meant "never" (NV).

Hence, trapping them if the condition code is not 1110 (AL) is
entirely reasonable, legal and safe.  If an ARM CPU defines an
instruction coding that matches the above, then it won't take the
undefined instruction trap, and we'll never see it.

Now, as for UDF usage in the kernel, it may be quite correct that we
always use the AL condition code for them, but it would be very odd
for there to be an instruction implemented with a different (non-NV)
condition code that can't also have it's AL condition code encoding.
You could never execute such an instruction unconditionally.



That makes sense. Thank you very much for a great answer!


The other subtlety is that UDF is a *mnemonic* for a specific encoding 
with cond=0b1110, thus "conditional UDF" is an oxymoron. You can still 
have a conditional instruction from the "permanently undefined" space 
(although on Armv7-A it's implementation-defined whether it causes an 
exception regardless of the condition), it's just not a UDF.


Robin.


Re: [RFC PATCH] arm: Don't trap conditional UDF instructions

2020-05-13 Thread Fredrik Strupe
On 13.05.2020 20:12, Russell King - ARM Linux admin wrote:
> On Wed, May 13, 2020 at 05:41:58PM +0200, Fredrik Strupe wrote:
>> Hi,
>>
>> This is more of a question than a patch, but I hope the attached patch makes
>> the issue a bit clearer.
>>
>> The arm port of Linux supports hooking/trapping of undefined instructions. 
>> Some
>> parts of the code use this to trap UDF instructions with certain immediates 
>> in
>> order to use them for other purposes, like 'UDF #16' which is equivalent to a
>> BKPT instruction in A32.
>>
>> Moreover, most of the undef hooks on UDF instructions assume that UDF is
>> conditional and mask out the condition prefix during matching. The attached
>> patch shows the locations where this happens. However, the Arm architecture
>> reference manual explicitly states that UDF is *not* conditional, making
>> any instruction encoding with a condition prefix other than 0xe (always
>> execute) unallocated.
>
> The latest version of the ARM architecture reference manual may say
> that, but earlier versions say different things. The latest reference
> manual does not apply to earlier architectures, so if you're writing
> code to cover multiple different architectures, you must have an
> understanding of each of those architectures.
>
> So, from the code:
>
>   ARM:    0111      
>
> From DDI0100E:
>
> 3.13.1 Undefined instruction space
>Instructions with the following opcodes are undefined
>instruction space:
>
>opcode[27:25] = 0b011
>opcode[4] = 1
>
>31 28 27 26 25 24 5 4 3 0
>cond  0  1  1  x  x x x x x x x x x x x x x x x x x x x 1 x x x x
>
> So, in this version of the architecture, undefined instructions may
> be conditional - and indeed that used to be the case.  The condition
> code was always respected, and cond= meant "never" (NV).
>
> Hence, trapping them if the condition code is not 1110 (AL) is
> entirely reasonable, legal and safe.  If an ARM CPU defines an
> instruction coding that matches the above, then it won't take the
> undefined instruction trap, and we'll never see it.
>
> Now, as for UDF usage in the kernel, it may be quite correct that we
> always use the AL condition code for them, but it would be very odd
> for there to be an instruction implemented with a different (non-NV)
> condition code that can't also have it's AL condition code encoding.
> You could never execute such an instruction unconditionally.
>

That makes sense. Thank you very much for a great answer!

Fredrik



Re: [RFC PATCH] arm: Don't trap conditional UDF instructions

2020-05-13 Thread Russell King - ARM Linux admin
On Wed, May 13, 2020 at 05:41:58PM +0200, Fredrik Strupe wrote:
> Hi,
> 
> This is more of a question than a patch, but I hope the attached patch makes
> the issue a bit clearer.
> 
> The arm port of Linux supports hooking/trapping of undefined instructions. 
> Some
> parts of the code use this to trap UDF instructions with certain immediates in
> order to use them for other purposes, like 'UDF #16' which is equivalent to a
> BKPT instruction in A32.
> 
> Moreover, most of the undef hooks on UDF instructions assume that UDF is
> conditional and mask out the condition prefix during matching. The attached
> patch shows the locations where this happens. However, the Arm architecture
> reference manual explicitly states that UDF is *not* conditional, making
> any instruction encoding with a condition prefix other than 0xe (always
> execute) unallocated.

The latest version of the ARM architecture reference manual may say
that, but earlier versions say different things. The latest reference
manual does not apply to earlier architectures, so if you're writing
code to cover multiple different architectures, you must have an
understanding of each of those architectures.

So, from the code:

ARM:    0111      

>From DDI0100E:

3.13.1 Undefined instruction space
   Instructions with the following opcodes are undefined
   instruction space:

   opcode[27:25] = 0b011
   opcode[4] = 1

   31 28 27 26 25 24 5 4 3 0
   cond  0  1  1  x  x x x x x x x x x x x x x x x x x x x 1 x x x x

So, in this version of the architecture, undefined instructions may
be conditional - and indeed that used to be the case.  The condition
code was always respected, and cond= meant "never" (NV).

Hence, trapping them if the condition code is not 1110 (AL) is
entirely reasonable, legal and safe.  If an ARM CPU defines an
instruction coding that matches the above, then it won't take the
undefined instruction trap, and we'll never see it.

Now, as for UDF usage in the kernel, it may be quite correct that we
always use the AL condition code for them, but it would be very odd
for there to be an instruction implemented with a different (non-NV)
condition code that can't also have it's AL condition code encoding.
You could never execute such an instruction unconditionally.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 10.2Mbps down 587kbps up