From d5cbc5f4934481e19b1c1b16494f5be54950bfac Mon Sep 17 00:00:00 2001 From: "Evgeny Grechnikov (Diamond)" Date: Sat, 12 Dec 2009 00:16:39 +0000 Subject: [PATCH] * fixed copy-on-write for kernel accesses from other threads * fixed return value of read/write_process_memory * fixed sysfunction 39.4 broken in rev. 1304 * more safe and slightly more effective FDO git-svn-id: svn://kolibrios.org@1314 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/core/memory.inc | 145 +++++++++++++++++++++++++++------- kernel/trunk/core/taskman.inc | 28 ++++--- kernel/trunk/fdo.inc | 19 +++-- kernel/trunk/kernel.asm | 1 + 4 files changed, 148 insertions(+), 45 deletions(-) diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index 4b4f1cd120..212d75be8a 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -714,14 +714,17 @@ end if jmp .exit endp -align 4 -proc map_mem stdcall, lin_addr:dword,pdir:dword,\ - ofs:dword,buf_size:dword - mov eax, [buf_size] - test eax, eax +; returns number of mapped bytes +proc map_mem stdcall, lin_addr:dword,slot:dword,\ + ofs:dword,buf_size:dword,req_access:dword + push 0 ; initialize number of mapped bytes + + cmp [buf_size], 0 jz .exit - mov eax, [pdir] + mov eax, [slot] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dir_table] and eax, 0xFFFFF000 stdcall map_page,[ipc_pdir],eax,PG_UW @@ -753,10 +756,11 @@ proc map_mem stdcall, lin_addr:dword,pdir:dword,\ and edx, 0x3FF mov esi, [ipc_ptab] -.map: mov eax, [esi+edx*4] - and eax, 0xFFFFF000 - jz .exit - stdcall map_page,edi,eax,PG_UW +.map: + stdcall safe_map_page,[slot],[req_access],[ofs] + jnc .exit + add dword [ebp-4], 4096 + add [ofs], 4096 dec ecx jz .exit add edi, 0x1000 @@ -773,20 +777,23 @@ proc map_mem stdcall, lin_addr:dword,pdir:dword,\ jmp .map .exit: + pop eax ret endp -align 4 -proc map_memEx stdcall, lin_addr:dword,pdir:dword,\ - ofs:dword,buf_size:dword - mov eax, [buf_size] - test eax, eax +proc map_memEx stdcall, lin_addr:dword,slot:dword,\ + ofs:dword,buf_size:dword,req_access:dword + push 0 ; initialize number of mapped bytes + + cmp [buf_size], 0 jz .exit - mov eax, [pdir] + mov eax, [slot] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dir_table] and eax, 0xFFFFF000 - stdcall map_page,[proc_mem_pdir],eax,dword PG_UW + stdcall map_page,[proc_mem_pdir],eax,PG_UW mov ebx, [ofs] shr ebx, 22 mov esi, [proc_mem_pdir] @@ -795,7 +802,7 @@ proc map_memEx stdcall, lin_addr:dword,pdir:dword,\ and eax, 0xFFFFF000 test eax, eax jz .exit - stdcall map_page,edi,eax,dword PG_UW + stdcall map_page,edi,eax,PG_UW @@: mov edi, [lin_addr] and edi, 0xFFFFF000 @@ -809,21 +816,101 @@ proc map_memEx stdcall, lin_addr:dword,pdir:dword,\ and edx, 0x3FF mov esi, [proc_mem_tab] -.map: mov eax, [esi+edx*4] -; and eax, 0xFFFFF000 -; test eax, eax -; jz .exit - stdcall map_page,edi,eax,dword PG_UW +.map: + stdcall safe_map_page,[slot],[req_access],[ofs] + jnc .exit + add dword [ebp-4], 0x1000 add edi, 0x1000 + add [ofs], 0x1000 inc edx dec ecx jnz .map .exit: + pop eax ret endp - - +; in: esi+edx*4 = pointer to page table entry +; in: [slot], [req_access], [ofs] on the stack +; in: edi = linear address to map +; out: CF cleared <=> failed +; destroys: only eax +proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword + mov eax, [esi+edx*4] + test al, PG_MAP + jz .not_present + test al, PG_WRITE + jz .resolve_readonly +; normal case: writable page, just map with requested access +.map: + stdcall map_page, edi, eax, [req_access] + stc +.fail: + ret +.not_present: +; check for alloc-on-demand page + test al, 2 + jz .fail +; allocate new page, save it to source page table + push ecx + call alloc_page + pop ecx + test eax, eax + jz .fail + or al, PG_UW + mov [esi+edx*4], eax + jmp .map +.resolve_readonly: +; readonly page, probably copy-on-write +; check: readonly request of readonly page is ok + test [req_access], PG_WRITE + jz .map +; find control structure for this page + pushf + cli + cld + push ebx ecx + mov eax, [slot] + shl eax, 8 + mov eax, [SLOT_BASE+eax+APPDATA.dlls_list_ptr] + test eax, eax + jz .no_hdll + mov ecx, [eax+HDLL.fd] +.scan_hdll: + cmp ecx, eax + jz .no_hdll + mov ebx, [ofs] + and ebx, not 0xFFF + sub ebx, [ecx+HDLL.base] + cmp ebx, [ecx+HDLL.size] + jb .hdll_found + mov ecx, [ecx+HDLL.fd] + jmp .scan_hdll +.no_hdll: + pop ecx ebx + popf + clc + ret +.hdll_found: +; allocate page, save it in page table, map it, copy contents from base + mov eax, [ecx+HDLL.parent] + add ebx, [eax+DLLDESCR.data] + call alloc_page + test eax, eax + jz .no_hdll + or al, PG_UW + mov [esi+edx*4], eax + stdcall map_page, edi, eax, [req_access] + push esi edi + mov esi, ebx + mov ecx, 4096/4 + rep movsd + pop edi esi + pop ecx ebx + popf + stc + ret +endp sys_IPC: ;input: @@ -907,15 +994,15 @@ proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword mov ecx, [ipc_tmp] cmp esi, 0x40000-0x1000 ; size of [ipc_tmp] minus one page jbe @f - push eax esi edi + push esi edi add esi,0x1000 stdcall alloc_kernel_space,esi mov ecx, eax - pop edi esi eax + pop edi esi @@: mov [used_buf], ecx - stdcall map_mem, ecx, [SLOT_BASE+eax+0xB8],\ - edi, esi + stdcall map_mem, ecx, [dst_slot],\ + edi, esi, PG_SW mov edi, [dst_offset] add edi, [used_buf] diff --git a/kernel/trunk/core/taskman.inc b/kernel/trunk/core/taskman.inc index 1e1b734b2c..79e5a64a88 100644 --- a/kernel/trunk/core/taskman.inc +++ b/kernel/trunk/core/taskman.inc @@ -751,18 +751,22 @@ proc read_process_memory jna @F mov ecx, 0x8000 @@: - mov eax, [slot] - shl eax,8 mov ebx, [offset] push ecx stdcall map_memEx, [proc_mem_map],\ - [SLOT_BASE+eax+0xB8],\ - ebx, ecx + [slot], ebx, ecx, PG_MAP pop ecx mov esi, [offset] and esi, 0xfff + sub eax, esi + jbe .ret + cmp ecx, eax + jbe @f + mov ecx, eax + mov [tmp_r_cnt], eax +@@: add esi, [proc_mem_map] mov edi, [buff] mov edx, ecx @@ -772,7 +776,7 @@ proc read_process_memory add [offset], edx sub [tmp_r_cnt], edx jnz .read_mem - +.ret: popad mov eax, [r_count] ret @@ -818,18 +822,22 @@ proc write_process_memory jna @F mov ecx, 0x8000 @@: - mov eax, [slot] - shl eax,8 mov ebx, [offset] ; add ebx, new_app_base push ecx stdcall map_memEx, [proc_mem_map],\ - [SLOT_BASE+eax+0xB8],\ - ebx, ecx + [slot], ebx, ecx, PG_SW pop ecx mov edi, [offset] and edi, 0xfff + sub eax, edi + jbe .ret + cmp ecx, eax + jbe @f + mov ecx, eax + mov [tmp_w_cnt], eax +@@: add edi, [proc_mem_map] mov esi, [buff] mov edx, ecx @@ -839,7 +847,7 @@ proc write_process_memory add [offset], edx sub [tmp_w_cnt], edx jnz .read_mem - +.ret: popad mov eax, [w_count] ret diff --git a/kernel/trunk/fdo.inc b/kernel/trunk/fdo.inc index ca9055b563..787401aa7b 100644 --- a/kernel/trunk/fdo.inc +++ b/kernel/trunk/fdo.inc @@ -6,6 +6,7 @@ $Revision$ +_esp equ esp ; ; Formatted Debug Output (FDO) @@ -61,9 +62,11 @@ macro DEBUGS_N _sign,_num,[_str] { jmp ..label ..str db _str,0 ..label: - add esp,4*8+4 +; add esp,4*8+4 +esp equ esp+4*8+4 mov edx,..str - sub esp,4*8+4 +esp equ _esp +; sub esp,4*8+4 else mov edx,_str end if @@ -147,7 +150,8 @@ macro DEBUGD_N _sign,_num,_dec { else if _dec eqtype 0 mov eax,_dec else - add esp,4*8+4 +; add esp,4*8+4 +esp equ esp+4*8+4 if _num eq mov eax,dword _dec else if _num = 1 @@ -165,7 +169,8 @@ macro DEBUGD_N _sign,_num,_dec { else mov eax,dword _dec end if - sub esp,4*8+4 +esp equ _esp +; sub esp,4*8+4 end if mov cl,_sign call fdo_debug_outdec @@ -215,9 +220,11 @@ macro DEBUGH_N _sign,_num,_hex { else if _hex eqtype 0 mov eax,_hex else - add esp,4*8+4 +; add esp,4*8+4 +esp equ esp+4*8+4 mov eax,dword _hex - sub esp,4*8+4 +esp equ _esp +; sub esp,4*8+4 end if if ~_num eq mov edx,_num diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 59e529e509..968e47764a 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -2604,6 +2604,7 @@ nogb1: nogb2: ; cmp eax,4 ; TILED / STRETCHED + dec ebx dec ebx jnz nogb4 mov eax,[BgrDrawMode]