GDT Entry

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.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: wtf?

Post by Mikemk »

BMW wrote:
m12 wrote:
BMW wrote:

Code: Select all

disable_interrupts();
__asm__ __volatile__("lgdt %0" : : "m" (*ptr));
enable_interrupts();
That is an excellent way to crash.
Works fine for me.

Please explain...?
In some cases (probably most), it'll continue working. However, GCC expects/requires the descriptors to remain the same, and if your cpu reloads the descriptors (don't flame me, I've seen this this happen) on lgdt, then it might cause undefined behavior. Grub2 seems to load kernels to 0x10 instead of 0x8, and so if this happens, and your kernel code segment is 0x8, then you will get a #GP, a #DF, and finally a triple fault/cpu reset.

Personally, in cases involving segment register changes, stack changes, gdt, ect. I find it safer/easier to put a callable function in an external file.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
User avatar
BMW
Member
Member
Posts: 286
Joined: Mon Nov 05, 2012 8:31 pm
Location: New Zealand

Re: GDT Entry

Post by BMW »

Ok, but I am not actually changing the GDT, just relocating it due to virtual memory mapping. (and maybe adding entries for user mode).
Currently developing Lithium OS (LiOS).

Recursive paging saves lives.
"I want to change the world, but they won't give me the source code."
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: GDT Entry

Post by Griwes »

In some cases (probably most), it'll continue working. However, GCC expects/requires the descriptors to remain the same, and if your cpu reloads the descriptors (don't flame me, I've seen this this happen) on lgdt, then it might cause undefined behavior. Grub2 seems to load kernels to 0x10 instead of 0x8, and so if this happens, and your kernel code segment is 0x8, then you will get a #GP, a #DF, and finally a triple fault/cpu reset.
You surely do know that you have to reload the segment register for any change to actually happen? If lgdt reloaded segments, it would be dead retarded and unusable. And you surely do know no modern compiler messes with segments, so it totally doesn't matter?
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: GDT Entry

Post by bluemoon »

LGDT only update the CPU's GPT pointer, it does not invalidate and has no effect on current descriptor caches unless a reload of such register is performed.
So you probably want to reload DS/ES/SS/CS(via IRET) before re-enable interrupt.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: GDT Entry

Post by Mikemk »

Griwes wrote:
In some cases (probably most), it'll continue working. However, GCC expects/requires the descriptors to remain the same, and if your cpu reloads the descriptors (don't flame me, I've seen this this happen) on lgdt, then it might cause undefined behavior. Grub2 seems to load kernels to 0x10 instead of 0x8, and so if this happens, and your kernel code segment is 0x8, then you will get a #GP, a #DF, and finally a triple fault/cpu reset.
You surely do know that you have to reload the segment register for any change to actually happen? If lgdt reloaded segments, it would be dead retarded and unusable. And you surely do know no modern compiler messes with segments, so it totally doesn't matter?
Didnt i say, "don't flame me, i've seen it happen"?
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
User avatar
Kazinsal
Member
Member
Posts: 559
Joined: Wed Jul 13, 2011 7:38 pm
Libera.chat IRC: Kazinsal
Location: Vancouver
Contact:

Re: GDT Entry

Post by Kazinsal »

If an x86 CPU is reloading descriptors on LGDT, it's a very poor implementation of the x86 architecture.
Vol. 2A 3-457 wrote:

Code: Select all

IF OperandSize = 16
    THEN 
        GDTR(Limit) ← SRC[0:15];
        GDTR(Base) ← SRC[16:47] AND 00FFFFFFH; 
ELSE IF 32-bit Operand Size
    THEN
        GDTR(Limit) ← SRC[0:15];
        GDTR(Base) ← SRC[16:47]; 
    FI;
ELSE IF 64-bit Operand Size (* In 64-Bit Mode *)
    THEN
        GDTR(Limit) ← SRC[0:15];
        GDTR(Base) ← SRC[16:79]; 
    FI;
FI;
That's the official pseudocode of how LGDT works. I don't see "reload segment registers" anywhere in there.
Mikemk
Member
Member
Posts: 409
Joined: Sat Oct 22, 2011 12:27 pm

Re: GDT Entry

Post by Mikemk »

Blacklight wrote:If an x86 CPU is reloading descriptors on LGDT, it's a very poor implementation of the x86 architecture.
I agree.
Programming is 80% Math, 20% Grammar, and 10% Creativity <--- Do not make fun of my joke!
If you're new, check this out.
Post Reply