1

Regarding the working of current macro in Linux kernel(I am referring to ARM architecture)

The code for current macro :

return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));

This means that the struct thread_info is placed at the top of stack ?

This is from linux Kernel development 3rd edition :

struct thread_info lives at the bottom of the stack (for stacks that grow down) and at the top of the stack (for stacks that grow up).

How is this struct thread_info prevented by getting overwritten ?

artless noise
  • 21,212
  • 6
  • 68
  • 105
Leo Messi
  • 822
  • 10
  • 19
  • I think: `(sp & ~(THREAD_SIZE - 1));` check whether odd number of thread id. Code checks last bit is one. – Grijesh Chauhan Oct 13 '13 at 18:02
  • @GrijeshChauhan : I am not sure whether it does that I say that because further this code is used like this : current_thread_info()->task – Leo Messi Oct 13 '13 at 18:08
  • I myself couldn't understand this but I understand that `(sp & ~(THREAD_SIZE - 1)` check last bit is one or not. – Grijesh Chauhan Oct 13 '13 at 18:10
  • Suppose `THREAD_SIZE` is a power of two, say `0x100`. Then `(THREAD_SIZE-1)` will be `0xff`. ~(THREAD_SIZE-1)` will be the same mask inverted : `0xfffffff00` So, the macro mask off the lowest bits. The current struct is probably located at the lower size of the stack (assuming sp is the stack pointer, or a pointer into an array of thread structures) – wildplasser Oct 13 '13 at 18:17
  • The only thing that makes this **ARM** specific is the register used to get the *stack pointer*. Ie, on the **ARM**, it is `sp` whereas the **PowerPC**, it is `R1`, etc. The same concept is used on most (all?) architectures. – artless noise Oct 15 '13 at 19:25
  • @LeoMessi, do you know what page in the book you got that from? – mikeazo May 23 '17 at 18:29
  • @artlessnoise, I know this is old, but thought I'd answer your comment. According to the book, some architectures use a dedicated register to store this pointer. For PPC, it is in r2. It may also be at the bottom of the stack, but it is also in a specific register. – mikeazo May 23 '17 at 18:30

3 Answers3

2

THREAD_SIZE is a constant with a power of 2, which gives the amount of memory allocated for the thread's stack.

  • The expression ~(THREAD_SIZE - 1) then gives a bitmask for getting rid of the actual stack address. Eg. For 8 kB stack, it would be 0xffffff00.

By taking a bitwise and with the stack pointer value, we get the lowest address allocated for the stack.

The stack pointer is useful for getting the thread information because each thread always has its own stack.

Umer Farooq
  • 7,356
  • 7
  • 42
  • 67
  • Thanks for the clarification , Agreed so you get the start address of thread_info and from there we get task also but what about overwrite protection ? – Leo Messi Oct 13 '13 at 18:26
  • @LeoMessi I am not sure about that. This may help you http://stackoverflow.com/questions/6270945/linux-stack-sizes – Umer Farooq Oct 13 '13 at 18:34
1

It is not protected from overrun.

If the stack grows too large (stack overflow), the first thing it overruns is the `struct thread_info, which soon leads to various nasty failures.

So when writing kernel code, use a s little stack space as possible, to avoid overruns.

ugoren
  • 16,023
  • 3
  • 35
  • 65
0

A pointer to the thread's struct thread_info is placed at the bottom of the memory that is reserved for the thread's kernel stack. (Each thread needs its own stack, so the stack pointer's value is guaranteed to be unique for each thread.)

There is no special protection mechanism to prevent overwriting this pointer, except the fact that kernel code does not use much space space (and that interrupts get switched to their own stack).

CL.
  • 173,858
  • 17
  • 217
  • 259