[parisc-linux] Need help to improve uaccess.h patch
jsoe0708@tiscali.be
jsoe0708@tiscali.be
Mon, 7 Oct 2002 18:12:22 +0200
Randolph Chung wrote:
>>>That is my main doubt :(
>>>In this uaccess.h, I read (but i am not quit sure to have understand all
>>> fine aspect) that we have to 'jump' after the erronious code (for me
>>>3b-[12]b + 1 ? am i wrong? ). And understand +3 in get_user_asm because
>>>we would have to jump after the cast "(x) = (__typeof__(*(ptr)))
>>>__gu_val;". Is it wrong?
>>
>>I may be wrong but I think the code is trying to build a PLABEL. In
>>which case, the value should be 2 or 3. The least significant bit is
>>not used. See the runtime architecture manual for more info on PLABELs.
>
>
> nah, the comment says:
>
> /*
> * The exception table contains two values: the first is an address
> * for an instruction that is allowed to fault, and the second is
> * the number of bytes to skip if a fault occurs. We also support in
> * two bit flags: 0x2 tells the exception handler to clear register
> * r9 and 0x1 tells the exception handler to put -EFAULT in r8.
> * This allows us to handle the simple cases for put_user and
> * get_user without having to have .fixup sections.
> */
But may I any way use a .fixup section (I do not find any usage of a .fixup
section in parisc code). Even lusercopy.S do not use it (just a kind of)?
>
> struct exception_table_entry {
> unsigned long addr; /* address of insn that is allowed to fault.
*/
> long skip; /* pcoq skip | r9 clear flag | r8 -EFAULT
flag */
> };
>
> so let's take __get_user() ...
>
> #define __get_user(x,ptr) \
> ({ \
> register long __gu_err __asm__ ("r8") = 0; \
> register long __gu_val __asm__ ("r9") = 0; \
> [...]
Well in the case of a 64bits int, I could not use only one "r9" register.
May I used a third register: "r10" for instance?
> } \
> (x) = (__typeof__(*(ptr))) __gu_val; \
> __gu_err; \
> })
>
> iow, at the end of __get_user, x == r9, and the return value is r8
>
> so, if the extable says:
> "\t.section __ex_table,\"a\"\n" \
> "\t.word\t1b\n" \
> "\t.word\t(2b-1b)+3\n" \
> "\t.previous" \
>
> this means that:
> if the insn at label 1 faults, handle the fault (see
> arch/parisc/mm/fault.c) and then continue at
> label1+((label2-label1)&~3) == label2; also, since the lowest 2 bits are
> set (+3), set r9 = 0 and r8 = -EFAULT --> get_user will set x = 0 and
> return -EFAULT
>
Thanks a lot for all of your understand and help,
Joel