GDT during runtime

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
greyOne
Member
Member
Posts: 58
Joined: Sun Feb 03, 2013 10:38 pm
Location: Canada

GDT during runtime

Post by greyOne »

I'm wondering, how practical, plausible and effective modifying the GDT is during program runtime; every time I spawn a new process, I valloc() it a new stack, and I want to give the stack its own GDT entry. Likewise, every time a process dies, the stack is deallocated and zeroed out, so I'd want to remove said GDT entry.

That said, it might mean I'd be changing the GDT as often as once a minute, perhaps more depending on system load. Furthermore, since threads also have their own stack, they'd need entries as well, which might mean I'd end up with a huge number of them.
Is this at all a practical way to go about this all of this? I haven't really found anything to reference in theory relating to this.

I was wondering if somehow jamming all the stacks together into one bounded area of the memory would be a better solution and just having an entry for that, but then I'd have to somehow manually prevent the stacks from writing over each other, and I'd have a hard cap on how many threads and process can concurrently exist.

EDIT:
Hmm. I just found a reference to LDT, but there doesn't seem to be anything about it on the Wiki...
Maybe Wikipedia...

EDIT:
According to Wikipedia, modern OSes make use of the LDT very little. Paging has replaced it in most cases.
FallenAvatar
Member
Member
Posts: 283
Joined: Mon Jan 03, 2011 6:58 pm

Re: GDT during runtime

Post by FallenAvatar »

Are you in protected mode? if yes, you can use virtual memory for the stack and have all stacks at the same location in memory, but none of the stacks would mess with each other because said virtual memory.

If you are in real mode, you can do what you are saying, but I don't have the experience to even guess at performance, or "realistic" consequences due to this.

- Monk

EDIT: Yes, virtual memory/paging generally replaces the GDT/LDT in terms of inter-process protection as well as forcing a "fixed" address space, and overcoming the limitations of said GDT and LDT.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: GDT during runtime

Post by Brendan »

Hi,
greyOne wrote:I'm wondering, how practical, plausible and effective modifying the GDT is during program runtime; every time I spawn a new process, I valloc() it a new stack, and I want to give the stack its own GDT entry. Likewise, every time a process dies, the stack is deallocated and zeroed out, so I'd want to remove said GDT entry.
It would be easy for the kernel to change a GDT entry (e.g. an "expand down" CPL=3 stack limit), and because SS gets loaded when you return to CPL=3 anyway it won't really effect performance.

However...

For multi-CPU systems different processes/threads will be running on different CPUs and therefore you'd need one GDT entry per CPU. For example, with 16 CPUs you'd need 16 GDT entries for CPL=3 stacks (plus another 16 entries for TSSs). Of course this is a very minor problem.

The big problem is compilers. Consider this code:

Code: Select all

int variableInDataSection = 1234;

void foo(void) {
    int variableOnStack = 3456;

    bar(&variableInDataSection);
    bar(&variableOnStack);
}

void bar(int *pointerToValue) {
    *pointerToValue = *pointerToValue + 1;
}
In this case, the compiler can't know if "pointerToValue" refers to something on the stack or something in the data section; and can't know whether to use DS or SS to access the value. The only real way around this problem is to make the segment part of the pointer (e.g. 48-bit pointers that contain a 16-bit segment plus a 32-bit offset). This means that accessing anything via. pointers involves segment register loads, and "accessing things via. pointers" happens relatively frequently. Segment register loads are slow. You do not want to be doing slow segment register loads frequently.

Nobody else wanted to do slow segment register loads frequently either; which means that modern compilers for 80x86 don't support it - they just assume that DS = ES = SS and that segmentation can be ignored. There are/were some ancient old compilers (mostly intended for DOS) that do support segmentation, but they suck because they're old (e.g. don't support more recent CPU features like SSE4 or AVX) and would make the performance problem worse.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
linguofreak
Member
Member
Posts: 510
Joined: Wed Mar 09, 2011 3:55 am

Re: GDT during runtime

Post by linguofreak »

Brendan wrote: In this case, the compiler can't know if "pointerToValue" refers to something on the stack or something in the data section; and can't know whether to use DS or SS to access the value. The only real way around this problem is to make the segment part of the pointer (e.g. 48-bit pointers that contain a 16-bit segment plus a 32-bit offset). This means that accessing anything via. pointers involves segment register loads, and "accessing things via. pointers" happens relatively frequently. Segment register loads are slow. You do not want to be doing slow segment register loads frequently.
What you could do, (though it would have the restriction that all pointers used in a given function call must belong to the same segment) is use FS or GS as the base segment for all pointers passed as parameters to functions (then you just need an FS or GS override instead of a segment load inside the function). It would be set to a default value (say, such that FS = DS), and any code that wanted to pass a pointer in a different segment as a parameter to a function would load the parameter segment register before making the function call and restore the default afterwards.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: GDT during runtime

Post by Owen »

... thereby breaking any global data/constant/miscellaneous other internal compiler generated references inside that function..
Post Reply