Critical sections in userspace without syscalls?

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.
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: Critical sections in userspace without syscalls?

Post by rdos »

tjmonk15 wrote:If it wasn't an issue, why did you suddenly update us with how you "fixed" it?

- Monk
It wasn't a fix. Merely a design-idea of how it could be solved in long mode without breaking protected mode.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Critical sections in userspace without syscalls?

Post by Combuster »

Feel free to keep dreaming :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: Critical sections in userspace without syscalls?

Post by rdos »

Combuster wrote:Feel free to keep dreaming :wink:
OK, go on to find the fix :)

Reference kernel code: http://www.rdos.net/svn/trunk/kernel/os/task.asm

Sections using the owner field:

Code: Select all

acquire_take:
    push es
    mov es,fs:ps_curr_thread
    mov ax,es:p_futex_id
    pop es
    mov es:[esi].fs_owner,ax
    mov es:[esi].fs_counter,1
and:

Code: Select all

    push es
    push esi
    lea esi,ds:[ebx].fh_list
    call RemoveBlock32
    mov es:p_data,0
    mov cx,es
    mov di,es:p_futex_id
    pop esi
    pop es
;
    mov es:[esi].fs_owner,di
    mov es:[esi].fs_counter,1
Does anybody see it being used by kernel? :mrgreen:
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Critical sections in userspace without syscalls?

Post by Gigasoft »

In my OS, semaphores look like this right now:

Code: Select all

No waiters:
cccc cccc cccc cccm mmmm mmmm mmmm mm01
c = Count
m = Maximum

Waiting (user mode semaphore):
iiii iiii iiii iiit tttt tttt tttt tt00
i = Semaphore index
t = Thread handle

Waiting (kernel mode semaphore):
pppp pppp pppp pppp pppp pppp pppp pp00
p = Pointer to wait block
For a semaphore that has a maximum count of 1 and is normally not held, special cased functions AcquireMutex and ReleaseMutex exist that can be called in user mode. These perform a cmpxchg to change 0x20005 into 5 or vice versa, and call the generic kernel mode WaitEvents and SignalSemaphore functions if this fails. The kernel then takes cares of everything. No hash maps or complicated user mode retry loops are required, and the handle is already created at thread initialization. The downside is that user mode semaphores are only valid within the same process. I'm still not sure of how to extend this to multiple processes, but it might be possible by using system wide thread IDs instead of thread handles, and verifying that the physical address of the semaphore matches up with what it should be when the thread belongs to another process. This should ensure that you can't tamper with the operation of a thread that is not actually waiting for what you're claiming.
Post Reply