From owner-freebsd-hackers@FreeBSD.ORG Thu Mar 31 11:08:04 2005 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id F141716A4CE for ; Thu, 31 Mar 2005 11:08:04 +0000 (GMT) Received: from comsys.ntu-kpi.kiev.ua (comsys.ntu-kpi.kiev.ua [195.245.194.142]) by mx1.FreeBSD.org (Postfix) with ESMTP id 0A75843D2D for ; Thu, 31 Mar 2005 11:07:20 +0000 (GMT) (envelope-from simon@comsys.ntu-kpi.kiev.ua) Received: from pm514-9.comsys.ntu-kpi.kiev.ua (pm514-9.comsys.ntu-kpi.kiev.ua [10.18.54.109]) (authenticated bits=0)j2VBB6iX059296 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 31 Mar 2005 14:11:06 +0300 (EEST) Received: by pm514-9.comsys.ntu-kpi.kiev.ua (Postfix, from userid 1000) id EF281371; Thu, 31 Mar 2005 14:06:54 +0300 (EEST) Date: Thu, 31 Mar 2005 14:06:54 +0300 From: Andrey Simonenko To: freebsd-hackers@freebsd.org Message-ID: <20050331110654.GB340@pm514-9.comsys.ntu-kpi.kiev.ua> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-Spam-Status: No, score=-4.4 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00 autolearn=ham version=3.0.1 X-Spam-Checker-Version: SpamAssassin 3.0.1 (2004-10-22) on comsys.ntu-kpi.kiev.ua X-Virus-Scanned: ClamAV 0.82/791/Sun Mar 27 00:26:49 2005 on comsys.ntu-kpi.kiev.ua X-Virus-Status: Clean Subject: Comments about vm_fault, vm_map_lookup and user-wired memory, part 2 X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 31 Mar 2005 11:08:05 -0000 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); }