Date: Thu, 31 Mar 2005 14:06:54 +0300 From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua> To: freebsd-hackers@freebsd.org Subject: Comments about vm_fault, vm_map_lookup and user-wired memory, part 2 Message-ID: <20050331110654.GB340@pm514-9.comsys.ntu-kpi.kiev.ua>
next in thread | raw e-mail | index | archive | help
Greetings, Second question. Consider following code (listing is given at the end of this letter): mmap() anonymous private read-only memory, fork() and mlock() this memory only in one process. Here we have: COW, NEEDS_COPY, read-only memory in both processes, but in one process it is USER_WIRED. Both memories refer to the same vm_object. Let's modify one byte in USER_WIRED memory from the debugger, as the result both processes will get modification in own memories: 1. When debugger wants to modify something in a memory, it calls vm_fault() with VM_PROT_WRITE and VM_PROT_OVERRIDE_WRITE. 2. vm_fault() calls vm_map_lookup(). 3. Since VM_PROT_OVERRIDE_WITE is on, vm_map_lookup() takes entry->max_protection and finds out that VM_PROT_WRITE is Ok for this memory (first if() condition passes). Since flag VM_PROT_OVERRIDE_WRITE is on, we continue (second if() condition passes). Since fault is on wired memory, vm_map_lookup() drops fault_tipe to entry->protection, which has only VM_PROT_READ, since our memory is read-only. As the result, shadow object is not created. 4. Debugger calls uiomove_fromphys() and modifies memory in the object, shared by both processes, but mappings are MAP_PRIVATE. Here is my question: what is the idea of this code in vm_map_lookup(), I mean modification of fault_type: *wired = (entry->wired_count != 0); if (*wired) prot = fault_type = entry->protection; And the result question from both my questions. As I understand something is wrong here, at least I cannot find good explanation. Is it allowed to create shadow objects for user-wired memory? If yes, then should pages in a shared object, which shadow user-wired pages, be also user-wired? ----- if ( (addr = mmap((void *)0, 1, PROT_READ, MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) err(1, "mmap"); printf("addr %p\n", addr); if (fork() == 0) for (;;) { printf("<%c>\n", *(char *)addr); sleep(1); } if (mlock(addr, 1) < 0) err(1, "mlock"); for (;;) { printf("[%c]\n", *(char *)addr); sleep(1); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050331110654.GB340>