From owner-freebsd-hackers@FreeBSD.ORG Mon Jul 20 15:14:06 2009 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9E8AB106566C for ; Mon, 20 Jul 2009 15:14:06 +0000 (UTC) (envelope-from brampton@gmail.com) Received: from mail-ew0-f222.google.com (mail-ew0-f222.google.com [209.85.219.222]) by mx1.freebsd.org (Postfix) with ESMTP id 2E4308FC2C for ; Mon, 20 Jul 2009 15:14:05 +0000 (UTC) (envelope-from brampton@gmail.com) Received: by ewy22 with SMTP id 22so671121ewy.43 for ; Mon, 20 Jul 2009 08:14:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:sender:received:date :x-google-sender-auth:message-id:subject:from:to:content-type :content-transfer-encoding; bh=BEzqYvfqIGWCmNasZ43g3ojXjA70oBq8SFQVaXtmJvs=; b=Z4TvfaimmYapstcKsbio8UXWLQgQUrqcFJ/E/HP7S4CvfZrJ4GFiGxaaV1CfwKxH54 ka+gC5jauQAOWaZ2jQCDYXSCmTzxn3iXul8Xz2bgmpb3loxcHFbZP+4pwvkY2mvq6Iky fQPfTTJziAFr8SwyQUaxhE9FpAp/cHoPJDc4M= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:sender:date:x-google-sender-auth:message-id:subject :from:to:content-type:content-transfer-encoding; b=NU2ycDAStCgMUSwRP0OwBpx+IPb0XH4paOJdFa/mBYGs5EwEFBNVcNpPU8uV+GCucg Sj+X//n3usXi4QEp1eDuxTEf/YYWt8Hlmd073ePBJ27pwddTAWPOlsT35dXskkgQxtZs 0YHB2ML1CGmAbJsT0LGWv/uXqtHMTa2zgpOBY= MIME-Version: 1.0 Sender: brampton@gmail.com Received: by 10.216.13.84 with SMTP id a62mr1171190wea.219.1248102842373; Mon, 20 Jul 2009 08:14:02 -0700 (PDT) Date: Mon, 20 Jul 2009 16:14:02 +0100 X-Google-Sender-Auth: 7413f4f806531362 Message-ID: From: Andrew Brampton To: freebsd-hackers@freebsd.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Subject: vm_map_protect / pmap_protect Can't lower protection X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Jul 2009 15:14:07 -0000 Hi, I've been playing with memguard(9) and so far it works well until it starts to run out of memory. For those who don't know, memguard is a replacement debugging malloc for the kernel, which is designed to catch use after free errors. It achieves this by setting any free'd pages to read-only, therefore any writes to the page should generate a page fault, and a backtrace allowing you to figure out where your code is using freed memory. To stop memguard using all your system's RAM and setting every page to read-only, it begins to recycle previously freed pages. To do this it must first make the page read-write, and then return it from malloc. The problem I am facing is when memguard, unguards a page (ie changes the page to read-write) it does not actually do this, and the page remains read-only. I have tracked the problem down but I don't know how to fix it. memguard_guard calls vm_map_protect with a read-only flag. vm_map_protect updates the vm_map_entry, and then calls pmap_protect to set the actual pte. pmap_protect successfully sets the pte to read-only and everything works as it should. However, memguard_unguard doesn't work correctly. It first calls vm_map_protect with a read-write flag. vm_map_protect correctly updates the vm_map_entry, and then calls pmap_protect to set the actual pte. pmap_protect is lazy and notices that we are reducing the protection on the page and therefore does nothing. It assumes that later that a page fault will occur, call vm_fault, and then fix up the pte then. The problem I seem to be having is that vm_fault is not called, because when the page fault occurs, calltrap then trap gets called, but it falls into trap_fatal because a non-sleepable lock is held. So my question is, can I call a function which sets the pte in a non-lazy way? I considered rewriting pmap_protect to do this, but I thought it be best to do it another way. Another idea I had was to call vm_fault myself straight after vm_map_protect, but I was unsure if that was allowed. Also, some googling found the function pmap_page_protect claims to do what I want, but has long been missing from FreeBSD. In case it matters, I'm using FreeBSD 7.2, on a amd64 machine. I've looked at HEAD and the relevant code looks the same, so I suspect I will still have problems with that. thanks for any help Andrew