protect thread from external terminate while running sysfn 70

git-svn-id: svn://kolibrios.org@3296 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
CleverMouse 2013-02-28 22:03:45 +00:00
parent 910558ed00
commit 165c453d43
9 changed files with 153 additions and 54 deletions

View File

@ -24,7 +24,7 @@ sysfn_saveramdisk: ; 18.6 = SAVE FLOPPY IMAGE (HD version only)
mov ebx, saverd_fileinfo
mov [saverd_fileinfo.name], ecx
pushad
call file_system_lfn ;in ebx
call file_system_lfn_protected ;in ebx
popad
mov [esp+32], eax
ret

View File

@ -103,7 +103,7 @@ endg
read_image:
mov ebx, read_image_fsinfo
pushad
call file_system_lfn
call file_system_lfn_protected
popad
ret

View File

@ -369,7 +369,7 @@ proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
pushad
lea ebx, [cmd]
call file_system_lfn
call file_system_lfn_protected
popad
ret
endp

View File

@ -707,3 +707,78 @@ restore .slot
; mov esi,boot_sched_2
; call boot_log
; ret
; Three following procedures are used to guarantee that
; some part of kernel code will not be terminated from outside
; while it is running.
; Note: they do not protect a thread from terminating due to errors inside
; the thread; accessing a nonexisting memory would still terminate it.
; First two procedures must be used in pair by thread-to-be-protected
; to signal the beginning and the end of an important part.
; It is OK to have nested areas.
; The last procedure must be used by outside wanna-be-terminators;
; if it is safe to terminate the given thread immediately, it returns eax=1;
; otherwise, it returns eax=0 and notifies the target thread that it should
; terminate itself when leaving a critical area (the last critical area if
; they are nested).
; Implementation. Those procedures use one dword in APPDATA for the thread,
; APPDATA.terminate_protection.
; * The upper bit is 1 during normal operations and 0 when terminate is requested.
; * Other bits form a number = depth of critical regions,
; plus 1 if the upper bit is 1.
; * When this dword goes to zero, the thread should be destructed,
; and the procedure in which it happened becomes responsible for destruction.
; Enter critical area. Called by thread which wants to be protected.
proc protect_from_terminate
mov edx, [current_slot]
; Atomically increment depth of critical areas and get the old value.
mov eax, 1
lock xadd [edx+APPDATA.terminate_protection], eax
; If the old value was zero, somebody has started to terminate us,
; so we are destructing and cannot do anything protected.
; Otherwise, return to the caller.
test eax, eax
jz @f
ret
@@:
; Wait for somebody to finish us.
call change_task
jmp @b
endp
; Leave critical area. Called by thread which wants to be protected.
proc unprotect_from_terminate
mov edx, [current_slot]
; Atomically decrement depth of critical areas.
lock dec [edx+APPDATA.terminate_protection]
; If the result of decrement is zero, somebody has requested termination,
; but at that moment we were inside a critical area; terminate now.
jz sys_end
; Otherwise, return to the caller.
ret
endp
; Request termination of thread identified by edx = SLOT_BASE + slot*256.
; Called by anyone.
proc request_terminate
xor eax, eax ; set return value
; Atomically clear the upper bit. If it was already zero, then
; somebody has requested termination before us, so just exit.
lock btr [edx+APPDATA.terminate_protection], 31
jnc .unsafe
; Atomically decrement depth of critical areas.
lock dec [edx+APPDATA.terminate_protection]
; If the result of decrement is nonzero, the target thread is inside a
; critical area; leave termination to leaving that area.
jnz .unsafe
; Otherwise, it is safe to kill the target now and the caller is responsible
; for this. Return eax=1.
inc eax
.unsafe:
ret
endp

View File

@ -190,7 +190,7 @@ iglobal
dd syscall_move_window ; 67-Window move or resize
dd f68 ; 68-Some internal services
dd sys_debug_services ; 69-Debug
dd file_system_lfn ; 70-Common file system interface, version 2
dd file_system_lfn_protected; 70-Common file system interface, version 2
dd syscall_window_settings ; 71-Window settings
dd sys_sendwindowmsg ; 72-Send window message
dd blit_32 ; 73-blitter;

View File

@ -1023,6 +1023,7 @@ proc set_app_params stdcall,slot:dword, params:dword,\
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
mov [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h
;set default io permission map
mov ecx, [SLOT_BASE+256+APPDATA.io_map]

View File

@ -103,6 +103,17 @@ fs_additional_handlers:
dd 0
endg
file_system_lfn_protected:
pushad
call protect_from_terminate
call file_system_lfn
call unprotect_from_terminate
popad
mov [image_of_eax], eax
mov [image_of_ebx], ebx
ret
file_system_lfn:
; in: ebx->fileinfo block
; operation codes:

View File

@ -612,6 +612,52 @@ no_mode_0x12:
mov [mem_BACKGROUND], 4
mov [img_background], static_background_data
; SET UP OS TASK
mov esi, boot_setostask
call boot_log
xor eax, eax
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+APPDATA.except_mask], eax
; name for OS/IDLE process
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
mov edi, [os_stack_seg]
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
add edi, 0x2000-512
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi; just for case
mov dword [SLOT_BASE+256+APPDATA.terminate_protection], 80000001h
mov esi, fpu_data
mov ecx, 512/4
cld
rep movsd
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
; task list
mov dword [TASK_DATA+TASKDATA.mem_start], eax; process base address
inc eax
mov dword [CURRENT_TASK], eax
mov dword [TASK_COUNT], eax
mov [current_slot], SLOT_BASE+256
mov [TASK_BASE], dword TASK_DATA
mov byte[TASK_DATA+TASKDATA.wnd_number], al ; on screen number
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
mov [SLOT_BASE + 256 + APPDATA.dir_table], sys_pgdir - OS_BASE
stdcall kernel_alloc, 0x10000/8
@ -752,7 +798,6 @@ end if
mov [pci_access_enabled], 1
; SET PRELIMINARY WINDOW STACK AND POSITIONS
mov esi, boot_windefs
@ -772,52 +817,6 @@ end if
call boot_log
call reserve_irqs_ports
; SET UP OS TASK
mov esi, boot_setostask
call boot_log
xor eax, eax
mov dword [SLOT_BASE+APPDATA.fpu_state], fpu_data
mov dword [SLOT_BASE+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+APPDATA.except_mask], eax
; name for OS/IDLE process
mov dword [SLOT_BASE+256+APPDATA.app_name], dword 'OS/I'
mov dword [SLOT_BASE+256+APPDATA.app_name+4], dword 'DLE '
mov edi, [os_stack_seg]
mov dword [SLOT_BASE+256+APPDATA.pl0_stack], edi
add edi, 0x2000-512
mov dword [SLOT_BASE+256+APPDATA.fpu_state], edi
mov dword [SLOT_BASE+256+APPDATA.saved_esp0], edi; just for case
; [SLOT_BASE+256+APPDATA.io_map] was set earlier
mov esi, fpu_data
mov ecx, 512/4
cld
rep movsd
mov dword [SLOT_BASE+256+APPDATA.exc_handler], eax
mov dword [SLOT_BASE+256+APPDATA.except_mask], eax
mov ebx, SLOT_BASE+256+APP_OBJ_OFFSET
mov dword [SLOT_BASE+256+APPDATA.fd_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.bk_obj], ebx
mov dword [SLOT_BASE+256+APPDATA.cur_dir], sysdir_path
mov dword [SLOT_BASE+256+APPDATA.tls_base], eax
; task list
mov dword [TASK_DATA+TASKDATA.mem_start], eax; process base address
inc eax
mov dword [CURRENT_TASK], eax
mov dword [TASK_COUNT], eax
mov [current_slot], SLOT_BASE+256
mov [TASK_BASE], dword TASK_DATA
mov byte[TASK_DATA+TASKDATA.wnd_number], al ; on screen number
mov dword [TASK_DATA+TASKDATA.pid], eax ; process id number
call init_display
mov eax, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor], eax
@ -931,8 +930,8 @@ end if
call fs_execute_from_sysdir
; cmp eax,2 ; continue if a process has been loaded
sub eax, 2
jz first_app_found
test eax, eax
jns first_app_found
mov esi, boot_failed
call boot_log
@ -2110,6 +2109,12 @@ sysfn_terminate: ; 18.2 = TERMINATE
add ecx, CURRENT_TASK+TASKDATA.state
cmp byte [ecx], 9
jz noprocessterminate
push ecx edx
lea edx, [(ecx-(CURRENT_TASK and 1FFFFFFFh)-TASKDATA.state)*8+SLOT_BASE]
call request_terminate
pop edx ecx
test eax, eax
jz noprocessterminate
;--------------------------------------
cmp [_display.select_cursor], 0
je .restore_end
@ -3489,7 +3494,14 @@ nobackgr:
;--------------------------------------
align 4
markz:
push ecx edx
lea edx, [(edx-(TASK_DATA and 1FFFFFFFh))*8+SLOT_BASE]
call request_terminate
pop edx ecx
test eax, eax
jz @f
mov [edx+TASKDATA.state], byte 3
@@:
add edx, 0x20
loop markz
;--------------------------------------

View File

@ -137,7 +137,7 @@ struct APPDATA
ipc_size dd ?
event_mask dd ?
debugger_slot dd ?
dd ?
terminate_protection dd ?
keyboard_mode db ?
rb 3
dir_table dd ?