Skip to contentSkip to conversation

break_cow and cache flushing

DISCUSSION Kip Walker 3 participants 4 messages Oct 16, 2002 – Oct 17, 2002 MIPS

lore
Share & tools
lore

Kip Walker

author
#0 lore raw

Can anyone comment on the following observations:

1) 'flush_cache_page' seems to be intended for flushing virtually indexed dcaches when a virtual->physical mapping changes (based on PAddr)
2) 'flush_page_to_ram' is also related to avoiding virtual aliasing in the dcache (based on VAddr)
3) 'flush_icache_page' seems to be intended for making the icache coherent with the dcache after an executable page has been filled
4) 'break_cow' may copy an executable page that is marked executable, for example a stack page (which has VM_EXEC) and might contain a live signal trampoline

On a CPU with writeback physically indexed/tagged dcache and virtually indexed icache that isn't coherent with the dcache, (1) and (2) are NOPs and (3) must writeback the dcache and flush the icache.

BUT either my understanding of (1) or (2) is wrong, or 'break_cow' needs to do a 'flush_icache_page' when the page is executable. Consider the following (evil) case.

A process takes a signal, and calls 'fork' from the handler. The signal trampoline is sitting in the stack, and both processes end up with the stack page COW. The parent ends up breaking the COW and so it gets the new copy of the page, but if the caches aren't flushed, it may execute garbage from the old contents of the new stack page.

Whew.

I've verified that doing a 'flush_icache_page' in 'break_cow' whenever an executable page is copied (which shouldn't be too often, I'd guess) and leaving 'flush_cache_page' and 'flush_page_to_ram' as NOPs seems stable (and fixes the previously crashing case described above).

Kip

#1 lore raw
Quoted 3 lines · Kip Walker

BUT either my understanding of (1) or (2) is wrong, or 'break_cow' needs to do a 'flush_icache_page' when the page is executable. Consider the following (evil) case.

Ok, didn't get hold of Rik but another mm guy. He agrees that fix is what should be used.

Coincidentally that also explains a problem the ia64 guys were seeing :-)

Ralf

#2 lore raw
In reply to Kip Walker

On Wed, Oct 16, 2002 at 04:53:47PM -0700, Kip Walker wrote:

To add a few technical details ...

Quoted 3 lines

1) 'flush_cache_page' seems to be intended for flushing virtually indexed dcaches when a virtual->physical mapping changes (based on PAddr)

Yes.

Quoted 2 lines

2) 'flush_page_to_ram' is also related to avoiding virtual aliasing in the dcache (based on VAddr)

Yes again.

Note that flush_page_to_ram is deprecated and should be implement as empty function for all architecture and the other flushing mechanisms be used instead.

Quoted 2 lines

3) 'flush_icache_page' seems to be intended for making the icache coherent with the dcache after an executable page has been filled

Yes.

Quoted 3 lines

4) 'break_cow' may copy an executable page that is marked executable, for example a stack page (which has VM_EXEC) and might contain a live signal trampoline

Yes.

Quoted 3 lines

On a CPU with writeback physically indexed/tagged dcache and virtually indexed icache that isn't coherent with the dcache, (1) and (2) are NOPs and (3) must writeback the dcache and flush the icache.

Yes, where this is getting complicated by some CPUs where remote i-caches are coherent but the local isn't.

Ralf

#3 lore raw
In reply to Kip Walker

MOO!, Don't hurt me, MOOOO!!!!

(cow collapses against the fence, twitching and subsiding into silience, as the farmer loads the offcut onto the carry-all)

sorry, just had to...

-----Original Message-----
From: [email protected] [mailto:[email protected]]On Behalf Of Kip Walker
Sent: Thursday, 17 October 2002 10:54
To: [email protected]
Subject: break_cow and cache flushing

Can anyone comment on the following observations:

1) 'flush_cache_page' seems to be intended for flushing virtually indexed dcaches when a virtual->physical mapping changes (based on PAddr)
2) 'flush_page_to_ram' is also related to avoiding virtual aliasing in the dcache (based on VAddr)
3) 'flush_icache_page' seems to be intended for making the icache coherent with the dcache after an executable page has been filled
4) 'break_cow' may copy an executable page that is marked executable, for example a stack page (which has VM_EXEC) and might contain a live signal trampoline

On a CPU with writeback physically indexed/tagged dcache and virtually indexed icache that isn't coherent with the dcache, (1) and (2) are NOPs and (3) must writeback the dcache and flush the icache.

BUT either my understanding of (1) or (2) is wrong, or 'break_cow' needs to do a 'flush_icache_page' when the page is executable. Consider the following (evil) case.

A process takes a signal, and calls 'fork' from the handler. The signal trampoline is sitting in the stack, and both processes end up with the stack page COW. The parent ends up breaking the COW and so it gets the new copy of the page, but if the caches aren't flushed, it may execute garbage from the old contents of the new stack page.

Whew.

I've verified that doing a 'flush_icache_page' in 'break_cow' whenever an executable page is copied (which shouldn't be too often, I'd guess) and leaving 'flush_cache_page' and 'flush_page_to_ram' as NOPs seems stable (and fixes the previously crashing case described above).

Kip