Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S266150AbUF3Gog (ORCPT ); Wed, 30 Jun 2004 02:44:36 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S266158AbUF3Gog (ORCPT ); Wed, 30 Jun 2004 02:44:36 -0400 Received: from e6.ny.us.ibm.com ([32.97.182.106]:12484 "EHLO e6.ny.us.ibm.com") by vger.kernel.org with ESMTP id S266150AbUF3GoV (ORCPT ); Wed, 30 Jun 2004 02:44:21 -0400 Date: Tue, 29 Jun 2004 23:44:00 -0700 From: "Martin J. Bligh" To: Andrew Morton cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: Re: remap_pte_range Message-ID: <1530000.1088577840@[10.10.2.4]> In-Reply-To: <20040629173037.68e5d958.akpm@osdl.org> References: <65600000.1088554644@flay> <20040629173037.68e5d958.akpm@osdl.org> X-Mailer: Mulberry/2.2.1 (Linux/x86) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 10683 Lines: 195 >> I have no idea what remap_pte_range is trying to do here, but what it >> is doing makes no sense (to me at least). >> >> If the pfn is not valid, we CANNOT safely call PageReserved on it - >> the *page returned from pfn_to_page is bullshit, and we crash deref'ing >> it. >> >> Perhaps this was what it was trying to do? Not sure. >> >> diff -purN -X /home/mbligh/.diff.exclude virgin/mm/memory.c remap_pte_range/mm/memory.c >> --- virgin/mm/memory.c 2004-06-16 10:22:15.000000000 -0700 >> +++ remap_pte_range/mm/memory.c 2004-06-29 17:15:35.000000000 -0700 >> @@ -908,7 +908,7 @@ static inline void remap_pte_range(pte_t >> pfn = phys_addr >> PAGE_SHIFT; >> do { >> BUG_ON(!pte_none(*pte)); >> - if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn))) >> + if (pfn_valid(pfn) && !PageReserved(pfn_to_page(pfn))) >> set_pte(pte, pfn_pte(pfn, prot)); >> address += PAGE_SIZE; >> pfn++; > > It seems OK as-is. > > If the pfn is not valid then establish the pte to point at physical memory. > > If the pfn _is_ valid then check PageReserved. If the page is reserved > then establish a pte to point at it. Mmmm - yeah, maybe I've got that backwards. pfn_valid = 0 => !pfn_valid = 1, so it needn't do the PageReserved by lazy eval I spose. But it seems to. See http://bugme.osdl.org/show_bug.cgi?id=2019 from comment #11 on. The instruction it's blowing up on is "mov (%eax),%eax" inside remap_pte_range (which is inlined), where we're deferencing the page from pfn_to_page for PageReserved. Now the debug I shoved in (to trigger whenever pfn_to_page(pfn) < PAGE_OFFSET) shows pfn_valid is 0 ... but maybe that's for another page there, which is what's confusing me. Humpf. I still find the fact that we're deliberately pointing the pte to a page that doesn't exist a little odd ... but still. > The slightly weird thing is that we do > > pfn = phys_addr >> PAGE_SHIFT; > ... > pfn_pte(pfn); > > to go from the physical address back to a masked&shifted version of the > physical address. Maybe that operation is doing the wrong thing in your > setup and we should go straight from the physical address to the pte value, > like 2.4's mk_pte_phys(). Mmmm. I'm pretty damned sure we're blowing up before we ever do that bit. And pfn_pte looks OK to me ... it should be 36bit (PAE) safe ... M. PS ... here's the second half of remap_page_range for that dump: 0xc0140112 : mov %esi,%ecx 0xc0140114 : call 0xc013e966 0xc0140119 : mov %eax,0xffffffc4(%ebp) 0xc014011c : mov $0xfffffff4,%eax 0xc0140121 : mov 0xffffffc4(%ebp),%ebx 0xc0140124 : test %ebx,%ebx 0xc0140126 : je 0xc014022d 0xc014012c : mov 0xffffffc8(%ebp),%eax 0xc014012f : and $0x1fffff,%esi 0xc0140135 : mov 0xffffffd4(%ebp),%ecx 0xc0140138 : sub 0xffffffd4(%ebp),%eax 0xc014013b : add 0xffffffd0(%ebp),%ecx 0xc014013e : mov 0xffffffc4(%ebp),%ebx 0xc0140141 : lea (%eax,%esi,1),%eax 0xc0140144 : cmp $0x200001,%eax 0xc0140149 : mov %eax,0xffffffc0(%ebp) 0xc014014c : mov $0x200000,%eax 0xc0140151 : cmovb 0xffffffc0(%ebp),%eax 0xc0140155 : shr $0xc,%ecx 0xc0140158 : mov %ecx,%edi 0xc014015a : mov %eax,0xffffffc0(%ebp) 0xc014015d : shl $0xc,%edi 0xc0140160 : mov (%ebx),%eax 0xc0140162 : mov 0x4(%ebx),%edx 0xc0140165 : test %eax,%eax 0xc0140167 : jne 0xc014016d 0xc0140169 : test %edx,%edx 0xc014016b : je 0xc0140175 0xc014016d : ud2a 0xc014016f : xchg %eax,%ebx 0xc0140170 : add 0x89c03b82(%edi),%edx 0xc0140176 : enter $0xe8c1,$0x10 0xc014017a : movzbl 0xc0401a60(%eax),%eax 0xc0140181 : mov 0xc0500860(,%eax,4),%edx 0xc0140188 : mov 0x3d40(%edx),%eax 0xc014018e : add 0x3d38(%edx),%eax 0xc0140194 : cmp %eax,%ecx 0xc0140196 : setb %al 0xc0140199 : movzbl %al,%eax 0xc014019c : test %eax,%eax 0xc014019e : je 0xc01401b8 0xc01401a0 : mov %ecx,%eax 0xc01401a2 : sub 0x3d38(%edx),%eax 0xc01401a8 : shl $0x5,%eax 0xc01401ab : add 0x3d30(%edx),%eax ************** blows up on next instruction *********************** 0xc01401b1 : mov (%eax),%eax 0xc01401b3 : test $0x8,%ah 0xc01401b6 : je 0xc01401d0 0xc01401b8 : mov %ecx,%eax 0xc01401ba : shr $0x14,%eax 0xc01401bd : mov %eax,0xffffffbc(%ebp) 0xc01401c0 : mov 0xc(%ebp),%eax 0xc01401c3 : or %edi,%eax 0xc01401c5 : mov 0xffffffbc(%ebp),%edx 0xc01401c8 : mov %eax,0xffffffb8(%ebp) 0xc01401cb : mov %edx,0x4(%ebx) 0xc01401ce : mov %eax,(%ebx) 0xc01401d0 : add $0x1,%ecx 0xc01401d3 : add $0x1000,%edi 0xc01401d9 : add $0x8,%ebx 0xc01401dc : add $0x1000,%esi 0xc01401e2 : setne %dl 0xc01401e5 : cmp 0xffffffc0(%ebp),%esi 0xc01401e8 : setb %al 0xc01401eb : and %edx,%eax 0xc01401ed : test $0x1,%al 0xc01401ef : jne 0xc0140160 0xc01401f5 : mov $0x7,%edx 0xc01401fa : mov 0xffffffc4(%ebp),%eax 0xc01401fd : call 0xc01154b7 0xc0140202 : mov 0xffffffd4(%ebp),%eax 0xc0140205 : addl $0x8,0xffffffd8(%ebp) 0xc0140209 : add $0x200000,%eax 0xc014020e : mov 0xffffffc8(%ebp),%ecx 0xc0140211 : and $0xffe00000,%eax 0xc0140216 : setne %dl 0xc0140219 : cmp %ecx,%eax 0xc014021b : mov %eax,0xffffffd4(%ebp) 0xc014021e : setb %al 0xc0140221 : and %edx,%eax 0xc0140223 : test $0x1,%al 0xc0140225 : jne 0xc0140106 0xc014022b : xor %eax,%eax 0xc014022d : test %eax,%eax 0xc014022f : mov %eax,%ebx 0xc0140231 : jne 0xc014025c 0xc0140233 : mov 0xffffffec(%ebp),%eax 0xc0140236 : addl $0x8,0xffffffe4(%ebp) 0xc014023a : mov 0xffffffe0(%ebp),%ecx 0xc014023d : add $0x40000000,%eax 0xc0140242 : and $0xc0000000,%eax 0xc0140247 : setne %dl 0xc014024a : cmp %ecx,%eax 0xc014024c : mov %eax,0xffffffec(%ebp) 0xc014024f : setb %al 0xc0140252 : and %edx,%eax 0xc0140254 : test $0x1,%al 0xc0140256 : jne 0xc0140099 0xc014025c : mov 0xfffffff0(%ebp),%edx 0xc014025f : mov (%edx),%eax 0xc0140261 : call 0xc0110a79 0xc0140266 : mov 0xffffffdc(%ebp),%ecx 0xc0140269 : movb $0x1,0x30(%ecx) 0xc014026d : mov $0xffffe000,%eax 0xc0140272 : and %esp,%eax 0xc0140274 : subl $0x1,0x14(%eax) 0xc0140278 : mov 0x8(%eax),%eax 0xc014027b : test $0x8,%al 0xc014027d : jne 0xc0140295 0xc014027f : add $0x3c,%esp 0xc0140282 : mov %ebx,%eax 0xc0140284 : pop %ebx 0xc0140285 : pop %esi 0xc0140286 : pop %edi 0xc0140287 : pop %ebp 0xc0140288 : ret 0xc0140289 : mov %edx,%eax 0xc014028b : call 0xc03a24e3 <__preempt_spin_lock> 0xc0140290 : jmp 0xc0140099 0xc0140295 : call 0xc03a2035 0xc014029a : add $0x3c,%esp 0xc014029d : mov %ebx,%eax 0xc014029f : pop %ebx 0xc01402a0 : pop %esi 0xc01402a1 : pop %edi 0xc01402a2 : pop %ebp 0xc01402a3 : ret - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/