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.
Well I think it's a very simple question, but how to clear x64 TSS busy bit? I tried to reset the attribute direct to the descriptor, and to load another empty TSS, but the original TSS is still busy.
(By the way, could anybody tell me more about context switching in long mode?)
x86_64 does not support hardware task switching. The 64-bit TSS does not contain a register image (it's figure 7-11 in my copy of the Intel SDM). Use software task switching instead (i.e. save/restore all general-purpse registers and use iret to restore RIP and RFLAGS). AFAICT there is no need to bother with the busy bit (or more than one TSS per processor) in 64-bit mode.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
Korona wrote: AFAICT there is no need to bother with the busy bit (or more than one TSS per processor) in 64-bit mode.
Yes of course you're right. So I've already made this. However, I created a process queue based on an array, and the enqueue and dequeue operation changes the position of each process, so I've got to change my TSS.RSP0 so it'll point to correct position. (I use stack to save GPR and so on, so the image will be stored in the process structure.)
The busy flag is used in 32 bit mode to prevent things like recursively entering a task through a task gate when you use hardware task switching.
Although the manual isn't particularly clear on this, the 64 bit busy flag seems to be a leftover from hardware task switching. It seems to serve no particular function anymore. In particular (and this also holds in 32 bit mode), one can allways edit the elements of a TSS, even when it is loaded into the TR.
Do note however that simply changing TSS.RSP0 will not change your current stack pointer, it will only change the value that the processor will load when switching from ring 1, 2 or 3 to ring 0.