Re: sse2 in kernel code

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

 



hm.....thank you for the sharing....i learn something......though
don't quite understand why at the moment .....

On Thu, Oct 15, 2009 at 3:57 AM, Jason Nymble <jason.nymble@xxxxxxxxx> wrote:
>
> On 14 Oct 2009, at 6:28 PM, Peter Teoh wrote:
>
>> On Wed, Oct 14, 2009 at 6:49 AM, Jason Nymble <jason.nymble@xxxxxxxxx>
>> wrote:
>>>
>>> On 14 Oct 2009, at 5:26 AM, Peter Teoh wrote:
>>>
>>>> On Thu, Oct 8, 2009 at 5:10 PM, Jason Nymble <jason.nymble@xxxxxxxxx>
>>>> wrote:
>>>>>
>>>>> Can one safely use SSE2 instructions in kernel module code? Or are
>>>>> those
>>>>> 128bit registers not preserved across kernel/userspace context switch?
>>>>>
>>>>
>>>> should be no problem...the kernel used "fxsave" (assembly instruction)
>>>> to backup all the FPU/SSE/MMX registers during context switch....
>>>>
>>>> from __switch_to()-->__lazy_fpu()-->save_init_fpu()--->fxsave()
>>>> (function):
>>>>
>>>> 128 static inline void fxsave(struct task_struct *tsk)
>>>> 129 {
>>>> 130         /* Using "rex64; fxsave %0" is broken because, if the memory
>>>> operand
>>>> 131            uses any extended registers for addressing, a second REX
>>>> prefix
>>>> 132            will be generated (to the assembler, rex64 followed by
>>>> semicolon
>>>> 133            is a separate instruction), and hence the 64-bitness is
>>>> lost. */
>>>> 134 #if 0
>>>> 135         /* Using "fxsaveq %0" would be the ideal choice, but is
>>>> only supported
>>>> 136            starting with gas 2.16. */
>>>> 137         __asm__ __volatile__("fxsaveq %0"
>>>> 138                              : "=m" (tsk->thread.xstate->fxsave));
>>>> 139 #elif 0
>>>> 140         /* Using, as a workaround, the properly prefixed form below
>>>> isn't
>>>> 141            accepted by any binutils version so far released,
>>>> complaining that
>>>> 142            the same type of prefix is used twice if an extended
>>>> register is
>>>> 143            needed for addressing (fix submitted to mainline
>>>> 2005-11-21). */
>>>> 144         __asm__ __volatile__("rex64/fxsave %0"
>>>> 145                              : "=m" (tsk->thread.xstate->fxsave));
>>>> 146 #else
>>>> 147         /* This, however, we can work around by forcing the
>>>> compiler to select
>>>> 148            an addressing mode that doesn't require extended
>>>> registers.
>>>> */
>>>> 149         __asm__ __volatile__("rex64/fxsave (%1)"
>>>> 150                              : "=m" (tsk->thread.xstate->fxsave)
>>>> 151                              : "cdaSDb"
>>>> (&tsk->thread.xstate->fxsave));
>>>> 152 #endif
>>>> 153 }
>>>> 154
>>>> 155 static inline void __save_init_fpu(struct task_struct *tsk)
>>>> 156 {
>>>> 157         if (task_thread_info(tsk)->status & TS_XSAVE)
>>>> 158                 xsave(tsk);
>>>> 159         else
>>>> 160                 fxsave(tsk);
>>>> 161
>>>> 162         clear_fpu_state(tsk);
>>>> 163         task_thread_info(tsk)->status &= ~TS_USEDFPU;
>>>> 164 }
>>>> 165
>>>>
>>>>>
>>>>
>>>>
>>>
>>> Interesting, thank you. How about protecting SSE2 code from preemptive
>>> scheduling within the kernel itself? Should one disable preemption and/or
>>> interrupts around code which performs SSE2 in the kernel?
>>>
>>
>> it should be treated the same way as any other
>> registers....eax/rax/ebx/rbx etc....right.   no protection should be
>> needed.
>>
>> (for certain registers - definitely not the SSEs - there is a
>> different set of problem to worry about when doing inline assembly -
>> ABI violation).
>>
>> http://www.x86-64.org/documentation/abi.pdf
>>
>> this is the ABI which gcc followed when generating instructions
>> set.....and so all the linux kernel + applications followed this
>> convention.   (for example, if u read the kernel in assembly, every
>> functions have a certain implicit knowledge of which registers can be
>> used and cannot be used, or is holding to the input
>> arguments....following the ABI conventions).   no problem if u program
>> in C.   but when u write inline assembly, gcc does not check for ABI
>> violation....and it will follow your instructions.   data corruptions
>> may result if there exists any conflicts between your inline assembly
>> and those of gcc-generated assembly.
>>
>
> I saw this in the ABI link you posted:
> A.2.4 Miscellaneous Remarks
> Linux Kernel code is not allowed to change the x87 and SSE units. If those
> are
> changed by kernel code, they have to be restored properly before sleeping or
> leav-
> ing the kernel. On preemptive kernels also more precautions may be needed.
>
>
> --
> To unsubscribe from this list: send an email with
> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
> Please read the FAQ at http://kernelnewbies.org/FAQ
>
>



-- 
Regards,
Peter Teoh

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ



[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux