OSDev.org

The Place to Start for Operating System Developers
It is currently Wed Sep 20, 2017 2:06 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: How to force stack switch in interrupt call
PostPosted: Wed Jul 12, 2017 2:47 am 
Offline

Joined: Wed Jul 12, 2017 2:31 am
Posts: 1
I'm writing task switching, which must occur on timer interrupt. But some of threads are in ring 0, others - in ring 3.
So, when task switchs from ring0 to ring3: stack don't switch when entering handler, but on exit, CPU extract 2 extra words from stack and ruins it.

TSS is configured: bochs write the following info:

tr:s=0x2b, base=0x00000000ffffd000, valid=1
ss:esp(0): 0x0010:0x00800ff0
ss:esp(1): 0x0000:0x00000000
ss:esp(2): 0x0000:0x00000000
cr3: 0x00000000
eip: 0x00000000
eflags: 0x00000000
cs: 0x0000 ds: 0x0000 ss: 0x0000
es: 0x0000 fs: 0x0000 gs: 0x0000
eax: 0x00000000 ebx: 0x00000000 ecx: 0x00000000 edx: 0x00000000
esi: 0x00000000 edi: 0x00000000 ebp: 0x00000000 esp: 0x00000000
ldt: 0x0000
i/o map: 0x0000

There is written, that when TSS is configured, stack switchs in any case, not only when ring3-code interrupted. But I can't get such behaviour of CPU.
How to force stack switch even if privilege level don't change?


Top
 Profile  
 
 Post subject: Re: How to force stack switch in interrupt call
PostPosted: Thu Jul 20, 2017 9:30 pm 
Offline
Member
Member
User avatar

Joined: Sat Dec 31, 2016 1:43 am
Posts: 47
Location: China
Well, it seems that you're in x86 mode.
If my memory is correct, TSSes in long mode(x64) contain a Interrupt Stack Table and IntGates(x64) contain a index which points to the table. The IST don't rely on which ring to switch and when interrupts happen, if an index in a IntGate(x64) points to an item in the IST, stack switch will always cause.
But in protected mode, you seems to do it manually :( .


Top
 Profile  
 
 Post subject: Re: How to force stack switch in interrupt call
PostPosted: Fri Jul 21, 2017 12:41 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8085
Location: At his keyboard!
Hi,

osdevuser1923 wrote:
I'm writing task switching, which must occur on timer interrupt.


No.

Task switches occur when:
  • The scheduler has to find something else for CPU to do, because:
    • The currently running task blocks for any reason (e.g. has to wait for disk IO or network or IPC or ....)
    • The currently running task terminates itself (e.g. calls "exit()")
    • The currently running task crashes
  • The scheduler decides that higher priority task should preempt the currently running (lower priority) task immediately, because:
    • The higher priority task was unblocked (whatever it was waiting for happened)
    • A new high priority task is being spawned/created
  • There are 2 or more tasks running (for the CPU), and the currently running task used all of the time slice it was given, and scheduler wants to give other task/s some CPU time

Note that the last reason ("currently running task used all of the time it was given") is relatively unimportant. Most task switches are caused by tasks blocking/unblocking (and it is possible to have perfectly sane scheduler without bothering with "currently running task used all of the time it was given" - e.g. using a "highest priority task that can run does run" approach).

osdevuser1923 wrote:
But some of threads are in ring 0, others - in ring 3.


No; all tasks are running in ring 0 when you find out that a task switch needs to happen.

For ring 3 tasks; something causes the CPU to switch to ring 0 (a kernel API call, an exception, an IRQ), then while you're running in ring 0 anyway the kernel decides it should do a task switch for one of the reasons listed above.

Essentially, switching rings (and TSS, etc) has nothing to do with task switching at all.

osdevuser1923 wrote:
How to force stack switch even if privilege level don't change?


Because all task switches happen when CPU is running in ring 0; you only ever have to worry about switching from a task that is running at ring 0 to another task that was running at ring 0. The low level task switch code can push a few registers onto the old task's kernel stack, save "kernel stack top" (RSP register) somewhere, load a new "kernel stack top" (RSP register) from somewhere, switch to the new task's virtual address space if necessary, then pop a few registers from the new task's kernel stack.

After the task switch happened, the task might or might not switch back to ring 3; but that still has nothing to do with task switching at all.

For a simple example, imagine that:
    A task calls the kernel API's "read()" function (causing switch from ring 3 to ring 0)
  • The kernel's "read()" function checks if the data is cached or not, finds out the data isn't cached, and asks the file system code to fetch the data; and the task is blocked (causing a task switch) because it has to wait while the data is read from a hard disk
  • Later on the data arrives from disk/file system/whatever; and the task is unblocked
  • Sooner or later (possibly immediately) the scheduler does a task switch back to the (now unblocked) task
  • Then the kernel figures out how much data was read (or if there was an error, etc) and returns this information from the kernel API's "read()" function (causing a switch from ring 3 back to ring 0).


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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: Bing [Bot], Google [Bot], Majestic-12 [Bot], MichaelPetch, WeirdEdEdison and 17 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group