Question about User Mode

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
kemosparc
Member
Member
Posts: 207
Joined: Tue Oct 29, 2013 1:13 pm

Re: Question about User Mode

Post by kemosparc »

Ya, I completely agree :)

Alternatively, today after work I will add some modifications such that I have two stacks for each process; kernel stack and user stack, instead of having to set registers manually.

Will keep you posted.

Thanks,
Karim.
kemosparc
Member
Member
Posts: 207
Joined: Tue Oct 29, 2013 1:13 pm

Re: Question about User Mode

Post by kemosparc »

Hi,

I have managed to solve the problems and it turned out at the end that I was overwriting the TSS stack.

The solution was that for each process I create two stacks; kernel stack and user stack.

I have a problem that I have worked around but I need to understand its symptom as I cannot comprehend it.

This piece of code :

Code: Select all

        asm volatile("         \
              cli;                 \
              mov %0, %%rcx;       \
              mov %1, %%rsp;       \
              mov %2, %%rbp;       \
              mov %3, %%cr3;       \
              mov $0x12345, %%rax; \
              sti;                 \
              jmp *%%rcx           " : : "r"(rip), "r"(rsp), "r"(rbp), "r"(page_directory_address));
And here is the objdump for that piece of code:

Code: Select all

   287a8:       fa                      cli    
   287a9:       4c 89 e9                mov    %r13,%rcx
   287ac:       4c 89 f4                mov    %r14,%rsp
   287af:       4c 89 fd                mov    %r15,%rbp
   287b2:       0f 22 d9                mov    %rcx,%cr3
   287b5:       48 c7 c0 45 23 01 00    mov    $0x12345,%rax
   287bc:       fb                      sti    
   287bd:       ff e1                   jmpq   *%rcx
Notice that the second instruction load the C variable rip into the asm register rcx and this is used to store the address of the instruction I jump to at the end of the inline asm. The problem is that the compiler generates a code that overwrites the rcx with the value of the C variable page_directory_address to store it in cr3. My question is why does the compiler use rcx, I mean it should detect the dependability and use some other register.


I got around this by one of two options:

First option is to move the cr3 instruction to be the first one.

Code: Select all

        asm volatile("         \
              cli;                 \
              mov %3, %%cr3;       \
              mov %0, %%rcx;       \
              mov %1, %%rsp;       \
              mov %2, %%rbp;       \
              mov $0x12345, %%rax; \
              sti;                 \
              jmp *%%rcx           " : : "r"(rip), "r"(rsp), "r"(rbp), "r"(page_directory_address));
or use the rcx constraint "c"

Code: Select all

        asm volatile("         \
              cli;                 \
              mov %0, %%rcx;       \
              mov %1, %%rsp;       \
              mov %2, %%rbp;       \
              mov %3, %%cr3;       \
              mov $0x12345, %%rax; \
              sti;                 \
              jmp *%%rcx           " : : "c"(rip), "r"(rsp), "r"(rbp), "r"(page_directory_address));
I am really not confident that this completely solve the problem and that this is the right way to tackle it.

Is this normal? do I have to go and look at the objdump code to make sure that there are no dependability problems?!

Is there any compiler options that I can use to avoid that?

Please let me know if anyone can explain or if there is a better way to do that

Thanks,
Karim.
Octocontrabass
Member
Member
Posts: 5590
Joined: Mon Mar 25, 2013 7:01 pm

Re: Question about User Mode

Post by Octocontrabass »

kemosparc wrote:My question is why does the compiler use rcx, I mean it should detect the dependability and use some other register.
The compiler doesn't know anything about assembly other than what you tell it. You didn't tell it that you're clobbering rcx, so the compiler thinks there's no problem placing one of the input values in rcx. (Why are you clobbering rcx, anyway? Couldn't you just use "jmpq *%0" instead?)

You probably shouldn't use inline assembly for this.
Post Reply