* possible Malta 4Kc cache problem ... @ 2002-12-04 6:45 Jun Sun 2002-12-04 9:38 ` Kevin D. Kissell 2002-12-04 22:53 ` Jun Sun 0 siblings, 2 replies; 29+ messages in thread From: Jun Sun @ 2002-12-04 6:45 UTC (permalink / raw) To: linux-mips; +Cc: jsun [-- Attachment #1: Type: text/plain, Size: 1340 bytes --] I attached the test case. Untar it. Type 'make' and run 'a.out'. If the test fails you will see a print-out. Otherwise you see nothing. It does not always fail. But if it fails, it is usually pretty consistent. Try a few times. Moving source tree to a different directory may cause the symptom appear or disappear. I spent quite some time to trace this problem, and came to suspect there might be a hardware problem. The problem involves emulating a "lw" instruction in cp1 branch delay slot, which needs to set up trampoline in user stack. The net effect looks as if the icache line or dcache line is not flushed properly. Using gdb/kgdb, printf or printk in any useful places would hide the bug. I did find a smaller part of the problem. flush_cache_sigtramp for MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented and executed as no-op (*ick*). Even after fixing this, I still see the problem happening. If you replace flush_cache_sigtramp() with flush_cache_all(), symptom would disppear. Several of my tests seem to suggest it is the icache that did not get flushed (or updated) properly. Not re-producible on other MIPS boards. At least so far. Does anybody with more knowledge about 4Kc have any clues here? Thanks. Jun [-- Attachment #2: fp_java.tar.gz --] [-- Type: application/x-tar-gz, Size: 11388 bytes --] ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 9:38 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 9:38 UTC (permalink / raw) To: linux-mips, Jun Sun > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > If the test fails you will see a print-out. Otherwise you see nothing. > > It does not always fail. But if it fails, it is usually pretty consistent. > Try a few times. Moving source tree to a different directory may cause > the symptom appear or disappear. > > I spent quite some time to trace this problem, and came to suspect > there might be a hardware problem. > > The problem involves emulating a "lw" instruction in cp1 branch delay > slot, which needs to set up trampoline in user stack. The net effect > looks as if the icache line or dcache line is not flushed properly. > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > I did find a smaller part of the problem. flush_cache_sigtramp for > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > and executed as no-op (*ick*). Which version of the 4Kc manual are you looking at? I'm looking at a very recent version of the 4Kc Software User's Manual (version 1.17, dated September 25, 2002), and it only shows Hit_Writeback_D to be invalid for *secondary and teritary* caches, which makes sense, since the 4KSc doesn't have any. > Even after fixing this, I still see the problem happening. That's not too surprising. The 4Kc D-cache is write-through, so if you're really seeing a problem with trampolimes, it is almost certain to be a problem with the Icache invalidation, not the Dcache flush. > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > would disppear. Which again would make sense if there's a problem on the icache side of the flush. Oddly enough, we've seen some glitches on other CPUs with other kernels that might have been explicable by failures of protected_flush_icache_line(), but we never found a problem with it, and a higher-level memory management patch made the problem go away. Makes me wonder if we shouldn't look at it again, more closely. Is there any possibility that the logic for restarting a protected kernel access following a page fault will somehow screw up on CACHE instructions, as opposed to the loads and stores for which the code was originally written? > Several of my tests seem to suggest it is the icache that did not > get flushed (or updated) properly. > > Not re-producible on other MIPS boards. At least so far. > > Does anybody with more knowledge about 4Kc have any clues here? > > Thanks. > > Jun ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 9:38 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 9:38 UTC (permalink / raw) To: linux-mips, Jun Sun > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > If the test fails you will see a print-out. Otherwise you see nothing. > > It does not always fail. But if it fails, it is usually pretty consistent. > Try a few times. Moving source tree to a different directory may cause > the symptom appear or disappear. > > I spent quite some time to trace this problem, and came to suspect > there might be a hardware problem. > > The problem involves emulating a "lw" instruction in cp1 branch delay > slot, which needs to set up trampoline in user stack. The net effect > looks as if the icache line or dcache line is not flushed properly. > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > I did find a smaller part of the problem. flush_cache_sigtramp for > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > and executed as no-op (*ick*). Which version of the 4Kc manual are you looking at? I'm looking at a very recent version of the 4Kc Software User's Manual (version 1.17, dated September 25, 2002), and it only shows Hit_Writeback_D to be invalid for *secondary and teritary* caches, which makes sense, since the 4KSc doesn't have any. > Even after fixing this, I still see the problem happening. That's not too surprising. The 4Kc D-cache is write-through, so if you're really seeing a problem with trampolimes, it is almost certain to be a problem with the Icache invalidation, not the Dcache flush. > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > would disppear. Which again would make sense if there's a problem on the icache side of the flush. Oddly enough, we've seen some glitches on other CPUs with other kernels that might have been explicable by failures of protected_flush_icache_line(), but we never found a problem with it, and a higher-level memory management patch made the problem go away. Makes me wonder if we shouldn't look at it again, more closely. Is there any possibility that the logic for restarting a protected kernel access following a page fault will somehow screw up on CACHE instructions, as opposed to the loads and stores for which the code was originally written? > Several of my tests seem to suggest it is the icache that did not > get flushed (or updated) properly. > > Not re-producible on other MIPS boards. At least so far. > > Does anybody with more knowledge about 4Kc have any clues here? > > Thanks. > > Jun ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 9:46 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 9:46 UTC (permalink / raw) To: linux-mips > Which version of the 4Kc manual are you looking at? I'm looking > at a very recent version of the 4Kc Software User's Manual > (version 1.17, dated September 25, 2002), and it only shows > Hit_Writeback_D to be invalid for *secondary and teritary* > caches, which makes sense, since the 4KSc doesn't have any. Note for the pendantic - that "S" was a typo, though of course the lack of secondary and tertiary caches applies to the whole 4K family, c, Ec, Sc, and Sd. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 9:46 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 9:46 UTC (permalink / raw) To: linux-mips > Which version of the 4Kc manual are you looking at? I'm looking > at a very recent version of the 4Kc Software User's Manual > (version 1.17, dated September 25, 2002), and it only shows > Hit_Writeback_D to be invalid for *secondary and teritary* > caches, which makes sense, since the 4KSc doesn't have any. Note for the pendantic - that "S" was a typo, though of course the lack of secondary and tertiary caches applies to the whole 4K family, c, Ec, Sc, and Sd. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 9:38 ` Kevin D. Kissell (?) (?) @ 2002-12-04 10:08 ` Carsten Langgaard 2002-12-04 11:21 ` Carsten Langgaard 2002-12-04 22:19 ` Jun Sun -1 siblings, 2 replies; 29+ messages in thread From: Carsten Langgaard @ 2002-12-04 10:08 UTC (permalink / raw) To: Kevin D. Kissell; +Cc: linux-mips, Jun Sun I have just tried your test on a 4Kc and I see no problems. However I'm running on our internal kernel sources, and as Kevin mention we have changed a fixed a few things in this area. As Kevin also mention it sure look more like a I-cache invalidation problem, rather than a D-cache flush problem, as the 4Kc has a write-through cache. One think you could try, is our latest kernel release. You can find it here: ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ /Carsten "Kevin D. Kissell" wrote: > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > > > If the test fails you will see a print-out. Otherwise you see nothing. > > > > It does not always fail. But if it fails, it is usually pretty consistent. > > Try a few times. Moving source tree to a different directory may cause > > the symptom appear or disappear. > > > > I spent quite some time to trace this problem, and came to suspect > > there might be a hardware problem. > > > > The problem involves emulating a "lw" instruction in cp1 branch delay > > slot, which needs to set up trampoline in user stack. The net effect > > looks as if the icache line or dcache line is not flushed properly. > > > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > > > I did find a smaller part of the problem. flush_cache_sigtramp for > > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > > and executed as no-op (*ick*). > > Which version of the 4Kc manual are you looking at? I'm looking > at a very recent version of the 4Kc Software User's Manual > (version 1.17, dated September 25, 2002), and it only shows > Hit_Writeback_D to be invalid for *secondary and teritary* > caches, which makes sense, since the 4KSc doesn't have any. > > > Even after fixing this, I still see the problem happening. > > That's not too surprising. The 4Kc D-cache is write-through, > so if you're really seeing a problem with trampolimes, it is almost > certain to be a problem with the Icache invalidation, not the > Dcache flush. > > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > > would disppear. > > Which again would make sense if there's a problem on > the icache side of the flush. Oddly enough, we've seen > some glitches on other CPUs with other kernels that > might have been explicable by failures of protected_flush_icache_line(), > but we never found a problem with it, and a higher-level > memory management patch made the problem go away. > Makes me wonder if we shouldn't look at it again, more > closely. Is there any possibility that the logic for restarting > a protected kernel access following a page fault will somehow > screw up on CACHE instructions, as opposed to the loads > and stores for which the code was originally written? > > > Several of my tests seem to suggest it is the icache that did not > > get flushed (or updated) properly. > > > > Not re-producible on other MIPS boards. At least so far. > > > > Does anybody with more knowledge about 4Kc have any clues here? > > > > Thanks. > > > > Jun -- _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 Denmark http://www.mips.com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 10:08 ` Carsten Langgaard @ 2002-12-04 11:21 ` Carsten Langgaard 2002-12-04 13:06 ` Kevin D. Kissell 2002-12-04 22:19 ` Jun Sun 1 sibling, 1 reply; 29+ messages in thread From: Carsten Langgaard @ 2002-12-04 11:21 UTC (permalink / raw) To: Kevin D. Kissell, linux-mips, Jun Sun [-- Attachment #1: Type: text/plain, Size: 4223 bytes --] I just noticed that the patch I send (I don't know how long ago), hasn't made it into the CVS tree. So there is a potentially hole in the indexed flushes, which might only flush one of the cache ways. Please try the mips32_cache.h, I have attached. /Carsten Carsten Langgaard wrote: > I have just tried your test on a 4Kc and I see no problems. > However I'm running on our internal kernel sources, and as Kevin mention we have > changed a fixed a few things in this area. > As Kevin also mention it sure look more like a I-cache invalidation problem, > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > One think you could try, is our latest kernel release. You can find it here: > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > /Carsten > > "Kevin D. Kissell" wrote: > > > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > > > > > If the test fails you will see a print-out. Otherwise you see nothing. > > > > > > It does not always fail. But if it fails, it is usually pretty consistent. > > > Try a few times. Moving source tree to a different directory may cause > > > the symptom appear or disappear. > > > > > > I spent quite some time to trace this problem, and came to suspect > > > there might be a hardware problem. > > > > > > The problem involves emulating a "lw" instruction in cp1 branch delay > > > slot, which needs to set up trampoline in user stack. The net effect > > > looks as if the icache line or dcache line is not flushed properly. > > > > > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > > > > > I did find a smaller part of the problem. flush_cache_sigtramp for > > > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > > > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > > > and executed as no-op (*ick*). > > > > Which version of the 4Kc manual are you looking at? I'm looking > > at a very recent version of the 4Kc Software User's Manual > > (version 1.17, dated September 25, 2002), and it only shows > > Hit_Writeback_D to be invalid for *secondary and teritary* > > caches, which makes sense, since the 4KSc doesn't have any. > > > > > Even after fixing this, I still see the problem happening. > > > > That's not too surprising. The 4Kc D-cache is write-through, > > so if you're really seeing a problem with trampolimes, it is almost > > certain to be a problem with the Icache invalidation, not the > > Dcache flush. > > > > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > > > would disppear. > > > > Which again would make sense if there's a problem on > > the icache side of the flush. Oddly enough, we've seen > > some glitches on other CPUs with other kernels that > > might have been explicable by failures of protected_flush_icache_line(), > > but we never found a problem with it, and a higher-level > > memory management patch made the problem go away. > > Makes me wonder if we shouldn't look at it again, more > > closely. Is there any possibility that the logic for restarting > > a protected kernel access following a page fault will somehow > > screw up on CACHE instructions, as opposed to the loads > > and stores for which the code was originally written? > > > > > Several of my tests seem to suggest it is the icache that did not > > > get flushed (or updated) properly. > > > > > > Not re-producible on other MIPS boards. At least so far. > > > > > > Does anybody with more knowledge about 4Kc have any clues here? > > > > > > Thanks. > > > > > > Jun > > -- > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > Denmark http://www.mips.com -- _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 Denmark http://www.mips.com [-- Attachment #2: mips32_cache.h --] [-- Type: text/plain, Size: 7151 bytes --] /* * mips32_cache.h * * Carsten Langgaard, carstenl@mips.com * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. * * ######################################################################## * * This program is free software; you can distribute it and/or modify it * under the terms of the GNU General Public License (Version 2) as * published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. * * ######################################################################## * * Inline assembly cache operations. * * This file is the original r4cache.c file with modification that makes the * cache handling more generic. * * FIXME: Handle split L2 caches. * */ #ifndef _MIPS_R4KCACHE_H #define _MIPS_R4KCACHE_H #include <asm/asm.h> #include <asm/cacheops.h> static inline void flush_icache_line_indexed(unsigned long addr) { unsigned long waystep = icache_size/mips_cpu.icache.ways; unsigned int way; for (way = 0; way < mips_cpu.icache.ways; way++) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Index_Invalidate_I)); addr += waystep; } } static inline void flush_dcache_line_indexed(unsigned long addr) { unsigned long waystep = dcache_size/mips_cpu.dcache.ways; unsigned int way; for (way = 0; way < mips_cpu.dcache.ways; way++) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Index_Writeback_Inv_D)); addr += waystep; } } static inline void flush_scache_line_indexed(unsigned long addr) { unsigned long waystep = scache_size/mips_cpu.scache.ways; unsigned int way; for (way = 0; way < mips_cpu.scache.ways; way++) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Index_Writeback_Inv_SD)); addr += waystep; } } static inline void flush_icache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Hit_Invalidate_I)); } static inline void flush_dcache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Hit_Writeback_Inv_D)); } static inline void invalidate_dcache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Hit_Invalidate_D)); } static inline void invalidate_scache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Hit_Invalidate_SD)); } static inline void flush_scache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n\t" "cache %1, (%0)\n\t" ".set mips0\n\t" ".set reorder" : : "r" (addr), "i" (Hit_Writeback_Inv_SD)); } /* * The next two are for badland addresses like signal trampolines. */ static inline void protected_flush_icache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n" "1:\tcache %1,(%0)\n" "2:\t.set mips0\n\t" ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" STR(PTR)"\t1b,2b\n\t" ".previous" : : "r" (addr), "i" (Hit_Invalidate_I)); } static inline void protected_writeback_dcache_line(unsigned long addr) { __asm__ __volatile__( ".set noreorder\n\t" ".set mips3\n" "1:\tcache %1,(%0)\n" "2:\t.set mips0\n\t" ".set reorder\n\t" ".section\t__ex_table,\"a\"\n\t" STR(PTR)"\t1b,2b\n\t" ".previous" : : "r" (addr), "i" (Hit_Writeback_D)); } #define cache_unroll(base,op) \ __asm__ __volatile__(" \ .set noreorder; \ .set mips3; \ cache %1, (%0); \ .set mips0; \ .set reorder" \ : \ : "r" (base), \ "i" (op)); static inline void blast_dcache(void) { unsigned long start = KSEG0; unsigned long end = (start + dcache_size); while(start < end) { cache_unroll(start,Index_Writeback_Inv_D); start += dc_lsize; } } static inline void blast_dcache_page(unsigned long page) { unsigned long start = page; unsigned long end = (start + PAGE_SIZE); while(start < end) { cache_unroll(start,Hit_Writeback_Inv_D); start += dc_lsize; } } static inline void blast_dcache_page_indexed(unsigned long page) { unsigned long start; unsigned long end = (page + PAGE_SIZE); unsigned long waystep = dcache_size/mips_cpu.dcache.ways; unsigned int way; for (way = 0; way < mips_cpu.dcache.ways; way++) { start = page + way*waystep; while(start < end) { cache_unroll(start,Index_Writeback_Inv_D); start += dc_lsize; } } } static inline void blast_icache(void) { unsigned long start = KSEG0; unsigned long end = (start + icache_size); while(start < end) { cache_unroll(start,Index_Invalidate_I); start += ic_lsize; } } static inline void blast_icache_page(unsigned long page) { unsigned long start = page; unsigned long end = (start + PAGE_SIZE); while(start < end) { cache_unroll(start,Hit_Invalidate_I); start += ic_lsize; } } static inline void blast_icache_page_indexed(unsigned long page) { unsigned long start; unsigned long end = (page + PAGE_SIZE); unsigned long waystep = icache_size/mips_cpu.icache.ways; unsigned int way; for (way = 0; way < mips_cpu.icache.ways; way++) { start = page + way*waystep; while(start < end) { cache_unroll(start,Index_Invalidate_I); start += ic_lsize; } } } static inline void blast_scache(void) { unsigned long start = KSEG0; unsigned long end = KSEG0 + scache_size; while(start < end) { cache_unroll(start,Index_Writeback_Inv_SD); start += sc_lsize; } } static inline void blast_scache_page(unsigned long page) { unsigned long start = page; unsigned long end = page + PAGE_SIZE; while(start < end) { cache_unroll(start,Hit_Writeback_Inv_SD); start += sc_lsize; } } static inline void blast_scache_page_indexed(unsigned long page) { unsigned long start; unsigned long end = (page + PAGE_SIZE); unsigned long waystep = scache_size/mips_cpu.scache.ways; unsigned int way; for (way = 0; way < mips_cpu.scache.ways; way++) { start = page + way*waystep; while(start < end) { cache_unroll(start,Index_Writeback_Inv_SD); start += sc_lsize; } } } #endif /* !(_MIPS_R4KCACHE_H) */ ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 13:06 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 13:06 UTC (permalink / raw) To: Carsten Langgaard, linux-mips, Jun Sun I think that Carsten's patch (or equivalent) should certainly be applied to the main tree, but I wonder how relevant it is here. The flushes associated with trampolines don't do indexed flush operations, do they? I don't have a 4Kc platform at hand, but I think that Jun Sun *may* have found a better way to get at the other problem I was referring to, which we rarely saw on non-superscalar issue CPUs, and which seems to be masked by an otherwise superfluous flush of the Icache that was added to the latest versions of break_cow(). If Carsten's patch solves the problem without applying that other update, I'd want to know that. If it *doesn't*, I'd be really interested to know if, by any chance, there is a corelation between failures of Jun Sun's test and the incidence of page faults on the CACHE op in protected_icache_invalidate_line(). Kevin K. ----- Original Message ----- From: "Carsten Langgaard" <carstenl@mips.com> To: "Kevin D. Kissell" <kevink@mips.com>; <linux-mips@linux-mips.org>; "Jun Sun" <jsun@mvista.com> Sent: Wednesday, December 04, 2002 12:21 PM Subject: Re: possible Malta 4Kc cache problem ... > I just noticed that the patch I send (I don't know how long ago), hasn't made it > into the CVS tree. > So there is a potentially hole in the indexed flushes, which might only flush one > of the cache ways. > > Please try the mips32_cache.h, I have attached. > > /Carsten > > > > Carsten Langgaard wrote: > > > I have just tried your test on a 4Kc and I see no problems. > > However I'm running on our internal kernel sources, and as Kevin mention we have > > changed a fixed a few things in this area. > > As Kevin also mention it sure look more like a I-cache invalidation problem, > > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > > One think you could try, is our latest kernel release. You can find it here: > > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > > > /Carsten > > > > "Kevin D. Kissell" wrote: > > > > > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > > > > > > > If the test fails you will see a print-out. Otherwise you see nothing. > > > > > > > > It does not always fail. But if it fails, it is usually pretty consistent. > > > > Try a few times. Moving source tree to a different directory may cause > > > > the symptom appear or disappear. > > > > > > > > I spent quite some time to trace this problem, and came to suspect > > > > there might be a hardware problem. > > > > > > > > The problem involves emulating a "lw" instruction in cp1 branch delay > > > > slot, which needs to set up trampoline in user stack. The net effect > > > > looks as if the icache line or dcache line is not flushed properly. > > > > > > > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > > > > > > > I did find a smaller part of the problem. flush_cache_sigtramp for > > > > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > > > > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > > > > and executed as no-op (*ick*). > > > > > > Which version of the 4Kc manual are you looking at? I'm looking > > > at a very recent version of the 4Kc Software User's Manual > > > (version 1.17, dated September 25, 2002), and it only shows > > > Hit_Writeback_D to be invalid for *secondary and teritary* > > > caches, which makes sense, since the 4KSc doesn't have any. > > > > > > > Even after fixing this, I still see the problem happening. > > > > > > That's not too surprising. The 4Kc D-cache is write-through, > > > so if you're really seeing a problem with trampolimes, it is almost > > > certain to be a problem with the Icache invalidation, not the > > > Dcache flush. > > > > > > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > > > > would disppear. > > > > > > Which again would make sense if there's a problem on > > > the icache side of the flush. Oddly enough, we've seen > > > some glitches on other CPUs with other kernels that > > > might have been explicable by failures of protected_flush_icache_line(), > > > but we never found a problem with it, and a higher-level > > > memory management patch made the problem go away. > > > Makes me wonder if we shouldn't look at it again, more > > > closely. Is there any possibility that the logic for restarting > > > a protected kernel access following a page fault will somehow > > > screw up on CACHE instructions, as opposed to the loads > > > and stores for which the code was originally written? > > > > > > > Several of my tests seem to suggest it is the icache that did not > > > > get flushed (or updated) properly. > > > > > > > > Not re-producible on other MIPS boards. At least so far. > > > > > > > > Does anybody with more knowledge about 4Kc have any clues here? > > > > > > > > Thanks. > > > > > > > > Jun > > > > -- > > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > > Denmark http://www.mips.com > > -- > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > Denmark http://www.mips.com > > > -------------------------------------------------------------------------------- > /* > * mips32_cache.h > * > * Carsten Langgaard, carstenl@mips.com > * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. > * > * ######################################################################## > * > * This program is free software; you can distribute it and/or modify it > * under the terms of the GNU General Public License (Version 2) as > * published by the Free Software Foundation. > * > * This program is distributed in the hope it will be useful, but WITHOUT > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > * for more details. > * > * You should have received a copy of the GNU General Public License along > * with this program; if not, write to the Free Software Foundation, Inc., > * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. > * > * ######################################################################## > * > * Inline assembly cache operations. > * > * This file is the original r4cache.c file with modification that makes the > * cache handling more generic. > * > * FIXME: Handle split L2 caches. > * > */ > #ifndef _MIPS_R4KCACHE_H > #define _MIPS_R4KCACHE_H > > #include <asm/asm.h> > #include <asm/cacheops.h> > > static inline void flush_icache_line_indexed(unsigned long addr) > { > unsigned long waystep = icache_size/mips_cpu.icache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.icache.ways; way++) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Index_Invalidate_I)); > > addr += waystep; > } > } > > static inline void flush_dcache_line_indexed(unsigned long addr) > { > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.dcache.ways; way++) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Index_Writeback_Inv_D)); > > addr += waystep; > } > } > > static inline void flush_scache_line_indexed(unsigned long addr) > { > unsigned long waystep = scache_size/mips_cpu.scache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.scache.ways; way++) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Index_Writeback_Inv_SD)); > > addr += waystep; > } > } > > static inline void flush_icache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Invalidate_I)); > } > > static inline void flush_dcache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Writeback_Inv_D)); > } > > static inline void invalidate_dcache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Invalidate_D)); > } > > static inline void invalidate_scache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Invalidate_SD)); > } > > static inline void flush_scache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Writeback_Inv_SD)); > } > > /* > * The next two are for badland addresses like signal trampolines. > */ > static inline void protected_flush_icache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n" > "1:\tcache %1,(%0)\n" > "2:\t.set mips0\n\t" > ".set reorder\n\t" > ".section\t__ex_table,\"a\"\n\t" > STR(PTR)"\t1b,2b\n\t" > ".previous" > : > : "r" (addr), > "i" (Hit_Invalidate_I)); > } > > static inline void protected_writeback_dcache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n" > "1:\tcache %1,(%0)\n" > "2:\t.set mips0\n\t" > ".set reorder\n\t" > ".section\t__ex_table,\"a\"\n\t" > STR(PTR)"\t1b,2b\n\t" > ".previous" > : > : "r" (addr), > "i" (Hit_Writeback_D)); > } > > #define cache_unroll(base,op) \ > __asm__ __volatile__(" \ > .set noreorder; \ > .set mips3; \ > cache %1, (%0); \ > .set mips0; \ > .set reorder" \ > : \ > : "r" (base), \ > "i" (op)); > > > static inline void blast_dcache(void) > { > unsigned long start = KSEG0; > unsigned long end = (start + dcache_size); > > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_D); > start += dc_lsize; > } > } > > static inline void blast_dcache_page(unsigned long page) > { > unsigned long start = page; > unsigned long end = (start + PAGE_SIZE); > > while(start < end) { > cache_unroll(start,Hit_Writeback_Inv_D); > start += dc_lsize; > } > } > > static inline void blast_dcache_page_indexed(unsigned long page) > { > unsigned long start; > unsigned long end = (page + PAGE_SIZE); > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.dcache.ways; way++) { > start = page + way*waystep; > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_D); > start += dc_lsize; > } > } > } > > static inline void blast_icache(void) > { > unsigned long start = KSEG0; > unsigned long end = (start + icache_size); > > while(start < end) { > cache_unroll(start,Index_Invalidate_I); > start += ic_lsize; > } > } > > static inline void blast_icache_page(unsigned long page) > { > unsigned long start = page; > unsigned long end = (start + PAGE_SIZE); > > while(start < end) { > cache_unroll(start,Hit_Invalidate_I); > start += ic_lsize; > } > } > > static inline void blast_icache_page_indexed(unsigned long page) > { > unsigned long start; > unsigned long end = (page + PAGE_SIZE); > unsigned long waystep = icache_size/mips_cpu.icache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.icache.ways; way++) { > start = page + way*waystep; > while(start < end) { > cache_unroll(start,Index_Invalidate_I); > start += ic_lsize; > } > } > } > > static inline void blast_scache(void) > { > unsigned long start = KSEG0; > unsigned long end = KSEG0 + scache_size; > > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_SD); > start += sc_lsize; > } > } > > static inline void blast_scache_page(unsigned long page) > { > unsigned long start = page; > unsigned long end = page + PAGE_SIZE; > > while(start < end) { > cache_unroll(start,Hit_Writeback_Inv_SD); > start += sc_lsize; > } > } > > static inline void blast_scache_page_indexed(unsigned long page) > { > unsigned long start; > unsigned long end = (page + PAGE_SIZE); > unsigned long waystep = scache_size/mips_cpu.scache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.scache.ways; way++) { > start = page + way*waystep; > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_SD); > start += sc_lsize; > } > } > } > > #endif /* !(_MIPS_R4KCACHE_H) */ > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 13:06 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 13:06 UTC (permalink / raw) To: Carsten Langgaard, linux-mips, Jun Sun I think that Carsten's patch (or equivalent) should certainly be applied to the main tree, but I wonder how relevant it is here. The flushes associated with trampolines don't do indexed flush operations, do they? I don't have a 4Kc platform at hand, but I think that Jun Sun *may* have found a better way to get at the other problem I was referring to, which we rarely saw on non-superscalar issue CPUs, and which seems to be masked by an otherwise superfluous flush of the Icache that was added to the latest versions of break_cow(). If Carsten's patch solves the problem without applying that other update, I'd want to know that. If it *doesn't*, I'd be really interested to know if, by any chance, there is a corelation between failures of Jun Sun's test and the incidence of page faults on the CACHE op in protected_icache_invalidate_line(). Kevin K. ----- Original Message ----- From: "Carsten Langgaard" <carstenl@mips.com> To: "Kevin D. Kissell" <kevink@mips.com>; <linux-mips@linux-mips.org>; "Jun Sun" <jsun@mvista.com> Sent: Wednesday, December 04, 2002 12:21 PM Subject: Re: possible Malta 4Kc cache problem ... > I just noticed that the patch I send (I don't know how long ago), hasn't made it > into the CVS tree. > So there is a potentially hole in the indexed flushes, which might only flush one > of the cache ways. > > Please try the mips32_cache.h, I have attached. > > /Carsten > > > > Carsten Langgaard wrote: > > > I have just tried your test on a 4Kc and I see no problems. > > However I'm running on our internal kernel sources, and as Kevin mention we have > > changed a fixed a few things in this area. > > As Kevin also mention it sure look more like a I-cache invalidation problem, > > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > > One think you could try, is our latest kernel release. You can find it here: > > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > > > /Carsten > > > > "Kevin D. Kissell" wrote: > > > > > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > > > > > > > If the test fails you will see a print-out. Otherwise you see nothing. > > > > > > > > It does not always fail. But if it fails, it is usually pretty consistent. > > > > Try a few times. Moving source tree to a different directory may cause > > > > the symptom appear or disappear. > > > > > > > > I spent quite some time to trace this problem, and came to suspect > > > > there might be a hardware problem. > > > > > > > > The problem involves emulating a "lw" instruction in cp1 branch delay > > > > slot, which needs to set up trampoline in user stack. The net effect > > > > looks as if the icache line or dcache line is not flushed properly. > > > > > > > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > > > > > > > I did find a smaller part of the problem. flush_cache_sigtramp for > > > > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > > > > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > > > > and executed as no-op (*ick*). > > > > > > Which version of the 4Kc manual are you looking at? I'm looking > > > at a very recent version of the 4Kc Software User's Manual > > > (version 1.17, dated September 25, 2002), and it only shows > > > Hit_Writeback_D to be invalid for *secondary and teritary* > > > caches, which makes sense, since the 4KSc doesn't have any. > > > > > > > Even after fixing this, I still see the problem happening. > > > > > > That's not too surprising. The 4Kc D-cache is write-through, > > > so if you're really seeing a problem with trampolimes, it is almost > > > certain to be a problem with the Icache invalidation, not the > > > Dcache flush. > > > > > > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > > > > would disppear. > > > > > > Which again would make sense if there's a problem on > > > the icache side of the flush. Oddly enough, we've seen > > > some glitches on other CPUs with other kernels that > > > might have been explicable by failures of protected_flush_icache_line(), > > > but we never found a problem with it, and a higher-level > > > memory management patch made the problem go away. > > > Makes me wonder if we shouldn't look at it again, more > > > closely. Is there any possibility that the logic for restarting > > > a protected kernel access following a page fault will somehow > > > screw up on CACHE instructions, as opposed to the loads > > > and stores for which the code was originally written? > > > > > > > Several of my tests seem to suggest it is the icache that did not > > > > get flushed (or updated) properly. > > > > > > > > Not re-producible on other MIPS boards. At least so far. > > > > > > > > Does anybody with more knowledge about 4Kc have any clues here? > > > > > > > > Thanks. > > > > > > > > Jun > > > > -- > > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > > Denmark http://www.mips.com > > -- > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > Denmark http://www.mips.com > > > -------------------------------------------------------------------------------- > /* > * mips32_cache.h > * > * Carsten Langgaard, carstenl@mips.com > * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. > * > * ######################################################################## > * > * This program is free software; you can distribute it and/or modify it > * under the terms of the GNU General Public License (Version 2) as > * published by the Free Software Foundation. > * > * This program is distributed in the hope it will be useful, but WITHOUT > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > * for more details. > * > * You should have received a copy of the GNU General Public License along > * with this program; if not, write to the Free Software Foundation, Inc., > * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. > * > * ######################################################################## > * > * Inline assembly cache operations. > * > * This file is the original r4cache.c file with modification that makes the > * cache handling more generic. > * > * FIXME: Handle split L2 caches. > * > */ > #ifndef _MIPS_R4KCACHE_H > #define _MIPS_R4KCACHE_H > > #include <asm/asm.h> > #include <asm/cacheops.h> > > static inline void flush_icache_line_indexed(unsigned long addr) > { > unsigned long waystep = icache_size/mips_cpu.icache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.icache.ways; way++) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Index_Invalidate_I)); > > addr += waystep; > } > } > > static inline void flush_dcache_line_indexed(unsigned long addr) > { > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.dcache.ways; way++) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Index_Writeback_Inv_D)); > > addr += waystep; > } > } > > static inline void flush_scache_line_indexed(unsigned long addr) > { > unsigned long waystep = scache_size/mips_cpu.scache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.scache.ways; way++) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Index_Writeback_Inv_SD)); > > addr += waystep; > } > } > > static inline void flush_icache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Invalidate_I)); > } > > static inline void flush_dcache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Writeback_Inv_D)); > } > > static inline void invalidate_dcache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Invalidate_D)); > } > > static inline void invalidate_scache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Invalidate_SD)); > } > > static inline void flush_scache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n\t" > "cache %1, (%0)\n\t" > ".set mips0\n\t" > ".set reorder" > : > : "r" (addr), > "i" (Hit_Writeback_Inv_SD)); > } > > /* > * The next two are for badland addresses like signal trampolines. > */ > static inline void protected_flush_icache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n" > "1:\tcache %1,(%0)\n" > "2:\t.set mips0\n\t" > ".set reorder\n\t" > ".section\t__ex_table,\"a\"\n\t" > STR(PTR)"\t1b,2b\n\t" > ".previous" > : > : "r" (addr), > "i" (Hit_Invalidate_I)); > } > > static inline void protected_writeback_dcache_line(unsigned long addr) > { > __asm__ __volatile__( > ".set noreorder\n\t" > ".set mips3\n" > "1:\tcache %1,(%0)\n" > "2:\t.set mips0\n\t" > ".set reorder\n\t" > ".section\t__ex_table,\"a\"\n\t" > STR(PTR)"\t1b,2b\n\t" > ".previous" > : > : "r" (addr), > "i" (Hit_Writeback_D)); > } > > #define cache_unroll(base,op) \ > __asm__ __volatile__(" \ > .set noreorder; \ > .set mips3; \ > cache %1, (%0); \ > .set mips0; \ > .set reorder" \ > : \ > : "r" (base), \ > "i" (op)); > > > static inline void blast_dcache(void) > { > unsigned long start = KSEG0; > unsigned long end = (start + dcache_size); > > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_D); > start += dc_lsize; > } > } > > static inline void blast_dcache_page(unsigned long page) > { > unsigned long start = page; > unsigned long end = (start + PAGE_SIZE); > > while(start < end) { > cache_unroll(start,Hit_Writeback_Inv_D); > start += dc_lsize; > } > } > > static inline void blast_dcache_page_indexed(unsigned long page) > { > unsigned long start; > unsigned long end = (page + PAGE_SIZE); > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.dcache.ways; way++) { > start = page + way*waystep; > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_D); > start += dc_lsize; > } > } > } > > static inline void blast_icache(void) > { > unsigned long start = KSEG0; > unsigned long end = (start + icache_size); > > while(start < end) { > cache_unroll(start,Index_Invalidate_I); > start += ic_lsize; > } > } > > static inline void blast_icache_page(unsigned long page) > { > unsigned long start = page; > unsigned long end = (start + PAGE_SIZE); > > while(start < end) { > cache_unroll(start,Hit_Invalidate_I); > start += ic_lsize; > } > } > > static inline void blast_icache_page_indexed(unsigned long page) > { > unsigned long start; > unsigned long end = (page + PAGE_SIZE); > unsigned long waystep = icache_size/mips_cpu.icache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.icache.ways; way++) { > start = page + way*waystep; > while(start < end) { > cache_unroll(start,Index_Invalidate_I); > start += ic_lsize; > } > } > } > > static inline void blast_scache(void) > { > unsigned long start = KSEG0; > unsigned long end = KSEG0 + scache_size; > > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_SD); > start += sc_lsize; > } > } > > static inline void blast_scache_page(unsigned long page) > { > unsigned long start = page; > unsigned long end = page + PAGE_SIZE; > > while(start < end) { > cache_unroll(start,Hit_Writeback_Inv_SD); > start += sc_lsize; > } > } > > static inline void blast_scache_page_indexed(unsigned long page) > { > unsigned long start; > unsigned long end = (page + PAGE_SIZE); > unsigned long waystep = scache_size/mips_cpu.scache.ways; > unsigned int way; > > for (way = 0; way < mips_cpu.scache.ways; way++) { > start = page + way*waystep; > while(start < end) { > cache_unroll(start,Index_Writeback_Inv_SD); > start += sc_lsize; > } > } > } > > #endif /* !(_MIPS_R4KCACHE_H) */ > ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 13:06 ` Kevin D. Kissell (?) @ 2002-12-04 13:14 ` Carsten Langgaard 2002-12-04 13:28 ` Carsten Langgaard 2002-12-04 17:08 ` Kevin D. Kissell -1 siblings, 2 replies; 29+ messages in thread From: Carsten Langgaard @ 2002-12-04 13:14 UTC (permalink / raw) To: Kevin D. Kissell; +Cc: linux-mips, Jun Sun "Kevin D. Kissell" wrote: > I think that Carsten's patch (or equivalent) should certainly be > applied to the main tree, but I wonder how relevant it is here. > The flushes associated with trampolines don't do indexed > flush operations, do they? True, but are we sure that it's the trampoline that's the problem here. > I don't have a 4Kc platform at > hand, but I think that Jun Sun *may* have found a better > way to get at the other problem I was referring to, which > we rarely saw on non-superscalar issue CPUs, and which > seems to be masked by an otherwise superfluous flush of > the Icache that was added to the latest versions of break_cow(). > If Carsten's patch solves the problem without applying that > other update, I'd want to know that. If it *doesn't*, I'd be > really interested to know if, by any chance, there is a > corelation between failures of Jun Sun's test and the incidence > of page faults on the CACHE op in protected_icache_invalidate_line(). > > Kevin K. > > ----- Original Message ----- > From: "Carsten Langgaard" <carstenl@mips.com> > To: "Kevin D. Kissell" <kevink@mips.com>; <linux-mips@linux-mips.org>; "Jun Sun" <jsun@mvista.com> > Sent: Wednesday, December 04, 2002 12:21 PM > Subject: Re: possible Malta 4Kc cache problem ... > > > I just noticed that the patch I send (I don't know how long ago), hasn't made it > > into the CVS tree. > > So there is a potentially hole in the indexed flushes, which might only flush one > > of the cache ways. > > > > Please try the mips32_cache.h, I have attached. > > > > /Carsten > > > > > > > > Carsten Langgaard wrote: > > > > > I have just tried your test on a 4Kc and I see no problems. > > > However I'm running on our internal kernel sources, and as Kevin mention we have > > > changed a fixed a few things in this area. > > > As Kevin also mention it sure look more like a I-cache invalidation problem, > > > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > > > One think you could try, is our latest kernel release. You can find it here: > > > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > > > > > /Carsten > > > > > > "Kevin D. Kissell" wrote: > > > > > > > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > > > > > > > > > If the test fails you will see a print-out. Otherwise you see nothing. > > > > > > > > > > It does not always fail. But if it fails, it is usually pretty consistent. > > > > > Try a few times. Moving source tree to a different directory may cause > > > > > the symptom appear or disappear. > > > > > > > > > > I spent quite some time to trace this problem, and came to suspect > > > > > there might be a hardware problem. > > > > > > > > > > The problem involves emulating a "lw" instruction in cp1 branch delay > > > > > slot, which needs to set up trampoline in user stack. The net effect > > > > > looks as if the icache line or dcache line is not flushed properly. > > > > > > > > > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > > > > > > > > > I did find a smaller part of the problem. flush_cache_sigtramp for > > > > > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > > > > > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > > > > > and executed as no-op (*ick*). > > > > > > > > Which version of the 4Kc manual are you looking at? I'm looking > > > > at a very recent version of the 4Kc Software User's Manual > > > > (version 1.17, dated September 25, 2002), and it only shows > > > > Hit_Writeback_D to be invalid for *secondary and teritary* > > > > caches, which makes sense, since the 4KSc doesn't have any. > > > > > > > > > Even after fixing this, I still see the problem happening. > > > > > > > > That's not too surprising. The 4Kc D-cache is write-through, > > > > so if you're really seeing a problem with trampolimes, it is almost > > > > certain to be a problem with the Icache invalidation, not the > > > > Dcache flush. > > > > > > > > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > > > > > would disppear. > > > > > > > > Which again would make sense if there's a problem on > > > > the icache side of the flush. Oddly enough, we've seen > > > > some glitches on other CPUs with other kernels that > > > > might have been explicable by failures of protected_flush_icache_line(), > > > > but we never found a problem with it, and a higher-level > > > > memory management patch made the problem go away. > > > > Makes me wonder if we shouldn't look at it again, more > > > > closely. Is there any possibility that the logic for restarting > > > > a protected kernel access following a page fault will somehow > > > > screw up on CACHE instructions, as opposed to the loads > > > > and stores for which the code was originally written? > > > > > > > > > Several of my tests seem to suggest it is the icache that did not > > > > > get flushed (or updated) properly. > > > > > > > > > > Not re-producible on other MIPS boards. At least so far. > > > > > > > > > > Does anybody with more knowledge about 4Kc have any clues here? > > > > > > > > > > Thanks. > > > > > > > > > > Jun > > > > > > -- > > > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > > > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > > > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > > > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > > > Denmark http://www.mips.com > > > > -- > > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > > Denmark http://www.mips.com > > > > > > > > -------------------------------------------------------------------------------- > > > /* > > * mips32_cache.h > > * > > * Carsten Langgaard, carstenl@mips.com > > * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. > > * > > * ######################################################################## > > * > > * This program is free software; you can distribute it and/or modify it > > * under the terms of the GNU General Public License (Version 2) as > > * published by the Free Software Foundation. > > * > > * This program is distributed in the hope it will be useful, but WITHOUT > > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > > * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > > * for more details. > > * > > * You should have received a copy of the GNU General Public License along > > * with this program; if not, write to the Free Software Foundation, Inc., > > * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. > > * > > * ######################################################################## > > * > > * Inline assembly cache operations. > > * > > * This file is the original r4cache.c file with modification that makes the > > * cache handling more generic. > > * > > * FIXME: Handle split L2 caches. > > * > > */ > > #ifndef _MIPS_R4KCACHE_H > > #define _MIPS_R4KCACHE_H > > > > #include <asm/asm.h> > > #include <asm/cacheops.h> > > > > static inline void flush_icache_line_indexed(unsigned long addr) > > { > > unsigned long waystep = icache_size/mips_cpu.icache.ways; > > unsigned int way; > > > > for (way = 0; way < mips_cpu.icache.ways; way++) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Index_Invalidate_I)); > > > > addr += waystep; > > } > > } > > > > static inline void flush_dcache_line_indexed(unsigned long addr) > > { > > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > > unsigned int way; > > > > for (way = 0; way < mips_cpu.dcache.ways; way++) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Index_Writeback_Inv_D)); > > > > addr += waystep; > > } > > } > > > > static inline void flush_scache_line_indexed(unsigned long addr) > > { > > unsigned long waystep = scache_size/mips_cpu.scache.ways; > > unsigned int way; > > > > for (way = 0; way < mips_cpu.scache.ways; way++) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Index_Writeback_Inv_SD)); > > > > addr += waystep; > > } > > } > > > > static inline void flush_icache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Hit_Invalidate_I)); > > } > > > > static inline void flush_dcache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Hit_Writeback_Inv_D)); > > } > > > > static inline void invalidate_dcache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Hit_Invalidate_D)); > > } > > > > static inline void invalidate_scache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Hit_Invalidate_SD)); > > } > > > > static inline void flush_scache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n\t" > > "cache %1, (%0)\n\t" > > ".set mips0\n\t" > > ".set reorder" > > : > > : "r" (addr), > > "i" (Hit_Writeback_Inv_SD)); > > } > > > > /* > > * The next two are for badland addresses like signal trampolines. > > */ > > static inline void protected_flush_icache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n" > > "1:\tcache %1,(%0)\n" > > "2:\t.set mips0\n\t" > > ".set reorder\n\t" > > ".section\t__ex_table,\"a\"\n\t" > > STR(PTR)"\t1b,2b\n\t" > > ".previous" > > : > > : "r" (addr), > > "i" (Hit_Invalidate_I)); > > } > > > > static inline void protected_writeback_dcache_line(unsigned long addr) > > { > > __asm__ __volatile__( > > ".set noreorder\n\t" > > ".set mips3\n" > > "1:\tcache %1,(%0)\n" > > "2:\t.set mips0\n\t" > > ".set reorder\n\t" > > ".section\t__ex_table,\"a\"\n\t" > > STR(PTR)"\t1b,2b\n\t" > > ".previous" > > : > > : "r" (addr), > > "i" (Hit_Writeback_D)); > > } > > > > #define cache_unroll(base,op) \ > > __asm__ __volatile__(" \ > > .set noreorder; \ > > .set mips3; \ > > cache %1, (%0); \ > > .set mips0; \ > > .set reorder" \ > > : \ > > : "r" (base), \ > > "i" (op)); > > > > > > static inline void blast_dcache(void) > > { > > unsigned long start = KSEG0; > > unsigned long end = (start + dcache_size); > > > > while(start < end) { > > cache_unroll(start,Index_Writeback_Inv_D); > > start += dc_lsize; > > } > > } > > > > static inline void blast_dcache_page(unsigned long page) > > { > > unsigned long start = page; > > unsigned long end = (start + PAGE_SIZE); > > > > while(start < end) { > > cache_unroll(start,Hit_Writeback_Inv_D); > > start += dc_lsize; > > } > > } > > > > static inline void blast_dcache_page_indexed(unsigned long page) > > { > > unsigned long start; > > unsigned long end = (page + PAGE_SIZE); > > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > > unsigned int way; > > > > for (way = 0; way < mips_cpu.dcache.ways; way++) { > > start = page + way*waystep; > > while(start < end) { > > cache_unroll(start,Index_Writeback_Inv_D); > > start += dc_lsize; > > } > > } > > } > > > > static inline void blast_icache(void) > > { > > unsigned long start = KSEG0; > > unsigned long end = (start + icache_size); > > > > while(start < end) { > > cache_unroll(start,Index_Invalidate_I); > > start += ic_lsize; > > } > > } > > > > static inline void blast_icache_page(unsigned long page) > > { > > unsigned long start = page; > > unsigned long end = (start + PAGE_SIZE); > > > > while(start < end) { > > cache_unroll(start,Hit_Invalidate_I); > > start += ic_lsize; > > } > > } > > > > static inline void blast_icache_page_indexed(unsigned long page) > > { > > unsigned long start; > > unsigned long end = (page + PAGE_SIZE); > > unsigned long waystep = icache_size/mips_cpu.icache.ways; > > unsigned int way; > > > > for (way = 0; way < mips_cpu.icache.ways; way++) { > > start = page + way*waystep; > > while(start < end) { > > cache_unroll(start,Index_Invalidate_I); > > start += ic_lsize; > > } > > } > > } > > > > static inline void blast_scache(void) > > { > > unsigned long start = KSEG0; > > unsigned long end = KSEG0 + scache_size; > > > > while(start < end) { > > cache_unroll(start,Index_Writeback_Inv_SD); > > start += sc_lsize; > > } > > } > > > > static inline void blast_scache_page(unsigned long page) > > { > > unsigned long start = page; > > unsigned long end = page + PAGE_SIZE; > > > > while(start < end) { > > cache_unroll(start,Hit_Writeback_Inv_SD); > > start += sc_lsize; > > } > > } > > > > static inline void blast_scache_page_indexed(unsigned long page) > > { > > unsigned long start; > > unsigned long end = (page + PAGE_SIZE); > > unsigned long waystep = scache_size/mips_cpu.scache.ways; > > unsigned int way; > > > > for (way = 0; way < mips_cpu.scache.ways; way++) { > > start = page + way*waystep; > > while(start < end) { > > cache_unroll(start,Index_Writeback_Inv_SD); > > start += sc_lsize; > > } > > } > > } > > > > #endif /* !(_MIPS_R4KCACHE_H) */ > > -- _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 Denmark http://www.mips.com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 13:14 ` Carsten Langgaard @ 2002-12-04 13:28 ` Carsten Langgaard 2002-12-04 17:08 ` Kevin D. Kissell 1 sibling, 0 replies; 29+ messages in thread From: Carsten Langgaard @ 2002-12-04 13:28 UTC (permalink / raw) To: Kevin D. Kissell, linux-mips, Jun Sun Carsten Langgaard wrote: > "Kevin D. Kissell" wrote: > > > I think that Carsten's patch (or equivalent) should certainly be > > applied to the main tree, but I wonder how relevant it is here. > > The flushes associated with trampolines don't do indexed > > flush operations, do they? > Sorry, my answer was probably not very clear. The trampoline flushes do not do indexed flush, but it use hit-writeback-invalidate for the D-cache and hit-invalidate for the I-cache. > > True, but are we sure that it's the trampoline that's the problem here. > > > I don't have a 4Kc platform at > > hand, but I think that Jun Sun *may* have found a better > > way to get at the other problem I was referring to, which > > we rarely saw on non-superscalar issue CPUs, and which > > seems to be masked by an otherwise superfluous flush of > > the Icache that was added to the latest versions of break_cow(). > > If Carsten's patch solves the problem without applying that > > other update, I'd want to know that. If it *doesn't*, I'd be > > really interested to know if, by any chance, there is a > > corelation between failures of Jun Sun's test and the incidence > > of page faults on the CACHE op in protected_icache_invalidate_line(). > > > > Kevin K. > > > > ----- Original Message ----- > > From: "Carsten Langgaard" <carstenl@mips.com> > > To: "Kevin D. Kissell" <kevink@mips.com>; <linux-mips@linux-mips.org>; "Jun Sun" <jsun@mvista.com> > > Sent: Wednesday, December 04, 2002 12:21 PM > > Subject: Re: possible Malta 4Kc cache problem ... > > > > > I just noticed that the patch I send (I don't know how long ago), hasn't made it > > > into the CVS tree. > > > So there is a potentially hole in the indexed flushes, which might only flush one > > > of the cache ways. > > > > > > Please try the mips32_cache.h, I have attached. > > > > > > /Carsten > > > > > > > > > > > > Carsten Langgaard wrote: > > > > > > > I have just tried your test on a 4Kc and I see no problems. > > > > However I'm running on our internal kernel sources, and as Kevin mention we have > > > > changed a fixed a few things in this area. > > > > As Kevin also mention it sure look more like a I-cache invalidation problem, > > > > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > > > > One think you could try, is our latest kernel release. You can find it here: > > > > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > > > > > > > /Carsten > > > > > > > > "Kevin D. Kissell" wrote: > > > > > > > > > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > > > > > > > > > > > If the test fails you will see a print-out. Otherwise you see nothing. > > > > > > > > > > > > It does not always fail. But if it fails, it is usually pretty consistent. > > > > > > Try a few times. Moving source tree to a different directory may cause > > > > > > the symptom appear or disappear. > > > > > > > > > > > > I spent quite some time to trace this problem, and came to suspect > > > > > > there might be a hardware problem. > > > > > > > > > > > > The problem involves emulating a "lw" instruction in cp1 branch delay > > > > > > slot, which needs to set up trampoline in user stack. The net effect > > > > > > looks as if the icache line or dcache line is not flushed properly. > > > > > > > > > > > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > > > > > > > > > > > I did find a smaller part of the problem. flush_cache_sigtramp for > > > > > > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > > > > > > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > > > > > > and executed as no-op (*ick*). > > > > > > > > > > Which version of the 4Kc manual are you looking at? I'm looking > > > > > at a very recent version of the 4Kc Software User's Manual > > > > > (version 1.17, dated September 25, 2002), and it only shows > > > > > Hit_Writeback_D to be invalid for *secondary and teritary* > > > > > caches, which makes sense, since the 4KSc doesn't have any. > > > > > > > > > > > Even after fixing this, I still see the problem happening. > > > > > > > > > > That's not too surprising. The 4Kc D-cache is write-through, > > > > > so if you're really seeing a problem with trampolimes, it is almost > > > > > certain to be a problem with the Icache invalidation, not the > > > > > Dcache flush. > > > > > > > > > > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > > > > > > would disppear. > > > > > > > > > > Which again would make sense if there's a problem on > > > > > the icache side of the flush. Oddly enough, we've seen > > > > > some glitches on other CPUs with other kernels that > > > > > might have been explicable by failures of protected_flush_icache_line(), > > > > > but we never found a problem with it, and a higher-level > > > > > memory management patch made the problem go away. > > > > > Makes me wonder if we shouldn't look at it again, more > > > > > closely. Is there any possibility that the logic for restarting > > > > > a protected kernel access following a page fault will somehow > > > > > screw up on CACHE instructions, as opposed to the loads > > > > > and stores for which the code was originally written? > > > > > > > > > > > Several of my tests seem to suggest it is the icache that did not > > > > > > get flushed (or updated) properly. > > > > > > > > > > > > Not re-producible on other MIPS boards. At least so far. > > > > > > > > > > > > Does anybody with more knowledge about 4Kc have any clues here? > > > > > > > > > > > > Thanks. > > > > > > > > > > > > Jun > > > > > > > > -- > > > > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > > > > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > > > > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > > > > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > > > > Denmark http://www.mips.com > > > > > > -- > > > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > > > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > > > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > > > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > > > Denmark http://www.mips.com > > > > > > > > > > > > > -------------------------------------------------------------------------------- > > > > > /* > > > * mips32_cache.h > > > * > > > * Carsten Langgaard, carstenl@mips.com > > > * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. > > > * > > > * ######################################################################## > > > * > > > * This program is free software; you can distribute it and/or modify it > > > * under the terms of the GNU General Public License (Version 2) as > > > * published by the Free Software Foundation. > > > * > > > * This program is distributed in the hope it will be useful, but WITHOUT > > > * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or > > > * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > > > * for more details. > > > * > > > * You should have received a copy of the GNU General Public License along > > > * with this program; if not, write to the Free Software Foundation, Inc., > > > * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. > > > * > > > * ######################################################################## > > > * > > > * Inline assembly cache operations. > > > * > > > * This file is the original r4cache.c file with modification that makes the > > > * cache handling more generic. > > > * > > > * FIXME: Handle split L2 caches. > > > * > > > */ > > > #ifndef _MIPS_R4KCACHE_H > > > #define _MIPS_R4KCACHE_H > > > > > > #include <asm/asm.h> > > > #include <asm/cacheops.h> > > > > > > static inline void flush_icache_line_indexed(unsigned long addr) > > > { > > > unsigned long waystep = icache_size/mips_cpu.icache.ways; > > > unsigned int way; > > > > > > for (way = 0; way < mips_cpu.icache.ways; way++) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Index_Invalidate_I)); > > > > > > addr += waystep; > > > } > > > } > > > > > > static inline void flush_dcache_line_indexed(unsigned long addr) > > > { > > > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > > > unsigned int way; > > > > > > for (way = 0; way < mips_cpu.dcache.ways; way++) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Index_Writeback_Inv_D)); > > > > > > addr += waystep; > > > } > > > } > > > > > > static inline void flush_scache_line_indexed(unsigned long addr) > > > { > > > unsigned long waystep = scache_size/mips_cpu.scache.ways; > > > unsigned int way; > > > > > > for (way = 0; way < mips_cpu.scache.ways; way++) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Index_Writeback_Inv_SD)); > > > > > > addr += waystep; > > > } > > > } > > > > > > static inline void flush_icache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Hit_Invalidate_I)); > > > } > > > > > > static inline void flush_dcache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Hit_Writeback_Inv_D)); > > > } > > > > > > static inline void invalidate_dcache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Hit_Invalidate_D)); > > > } > > > > > > static inline void invalidate_scache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Hit_Invalidate_SD)); > > > } > > > > > > static inline void flush_scache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n\t" > > > "cache %1, (%0)\n\t" > > > ".set mips0\n\t" > > > ".set reorder" > > > : > > > : "r" (addr), > > > "i" (Hit_Writeback_Inv_SD)); > > > } > > > > > > /* > > > * The next two are for badland addresses like signal trampolines. > > > */ > > > static inline void protected_flush_icache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n" > > > "1:\tcache %1,(%0)\n" > > > "2:\t.set mips0\n\t" > > > ".set reorder\n\t" > > > ".section\t__ex_table,\"a\"\n\t" > > > STR(PTR)"\t1b,2b\n\t" > > > ".previous" > > > : > > > : "r" (addr), > > > "i" (Hit_Invalidate_I)); > > > } > > > > > > static inline void protected_writeback_dcache_line(unsigned long addr) > > > { > > > __asm__ __volatile__( > > > ".set noreorder\n\t" > > > ".set mips3\n" > > > "1:\tcache %1,(%0)\n" > > > "2:\t.set mips0\n\t" > > > ".set reorder\n\t" > > > ".section\t__ex_table,\"a\"\n\t" > > > STR(PTR)"\t1b,2b\n\t" > > > ".previous" > > > : > > > : "r" (addr), > > > "i" (Hit_Writeback_D)); > > > } > > > > > > #define cache_unroll(base,op) \ > > > __asm__ __volatile__(" \ > > > .set noreorder; \ > > > .set mips3; \ > > > cache %1, (%0); \ > > > .set mips0; \ > > > .set reorder" \ > > > : \ > > > : "r" (base), \ > > > "i" (op)); > > > > > > > > > static inline void blast_dcache(void) > > > { > > > unsigned long start = KSEG0; > > > unsigned long end = (start + dcache_size); > > > > > > while(start < end) { > > > cache_unroll(start,Index_Writeback_Inv_D); > > > start += dc_lsize; > > > } > > > } > > > > > > static inline void blast_dcache_page(unsigned long page) > > > { > > > unsigned long start = page; > > > unsigned long end = (start + PAGE_SIZE); > > > > > > while(start < end) { > > > cache_unroll(start,Hit_Writeback_Inv_D); > > > start += dc_lsize; > > > } > > > } > > > > > > static inline void blast_dcache_page_indexed(unsigned long page) > > > { > > > unsigned long start; > > > unsigned long end = (page + PAGE_SIZE); > > > unsigned long waystep = dcache_size/mips_cpu.dcache.ways; > > > unsigned int way; > > > > > > for (way = 0; way < mips_cpu.dcache.ways; way++) { > > > start = page + way*waystep; > > > while(start < end) { > > > cache_unroll(start,Index_Writeback_Inv_D); > > > start += dc_lsize; > > > } > > > } > > > } > > > > > > static inline void blast_icache(void) > > > { > > > unsigned long start = KSEG0; > > > unsigned long end = (start + icache_size); > > > > > > while(start < end) { > > > cache_unroll(start,Index_Invalidate_I); > > > start += ic_lsize; > > > } > > > } > > > > > > static inline void blast_icache_page(unsigned long page) > > > { > > > unsigned long start = page; > > > unsigned long end = (start + PAGE_SIZE); > > > > > > while(start < end) { > > > cache_unroll(start,Hit_Invalidate_I); > > > start += ic_lsize; > > > } > > > } > > > > > > static inline void blast_icache_page_indexed(unsigned long page) > > > { > > > unsigned long start; > > > unsigned long end = (page + PAGE_SIZE); > > > unsigned long waystep = icache_size/mips_cpu.icache.ways; > > > unsigned int way; > > > > > > for (way = 0; way < mips_cpu.icache.ways; way++) { > > > start = page + way*waystep; > > > while(start < end) { > > > cache_unroll(start,Index_Invalidate_I); > > > start += ic_lsize; > > > } > > > } > > > } > > > > > > static inline void blast_scache(void) > > > { > > > unsigned long start = KSEG0; > > > unsigned long end = KSEG0 + scache_size; > > > > > > while(start < end) { > > > cache_unroll(start,Index_Writeback_Inv_SD); > > > start += sc_lsize; > > > } > > > } > > > > > > static inline void blast_scache_page(unsigned long page) > > > { > > > unsigned long start = page; > > > unsigned long end = page + PAGE_SIZE; > > > > > > while(start < end) { > > > cache_unroll(start,Hit_Writeback_Inv_SD); > > > start += sc_lsize; > > > } > > > } > > > > > > static inline void blast_scache_page_indexed(unsigned long page) > > > { > > > unsigned long start; > > > unsigned long end = (page + PAGE_SIZE); > > > unsigned long waystep = scache_size/mips_cpu.scache.ways; > > > unsigned int way; > > > > > > for (way = 0; way < mips_cpu.scache.ways; way++) { > > > start = page + way*waystep; > > > while(start < end) { > > > cache_unroll(start,Index_Writeback_Inv_SD); > > > start += sc_lsize; > > > } > > > } > > > } > > > > > > #endif /* !(_MIPS_R4KCACHE_H) */ > > > > > -- > _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com > |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 > | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 > TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 > Denmark http://www.mips.com -- _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 Denmark http://www.mips.com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 17:08 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 17:08 UTC (permalink / raw) To: Carsten Langgaard; +Cc: linux-mips, Jun Sun > > I think that Carsten's patch (or equivalent) should certainly be > > applied to the main tree, but I wonder how relevant it is here. > > The flushes associated with trampolines don't do indexed > > flush operations, do they? > > True, but are we sure that it's the trampoline that's the problem here? Jun Sun seemed to think it was. To quote his original message "The problem involves emulating a "lw" instruction in cp1 branch delay slot, which needs to set up trampoline in user stack. The net effect looks as if the icache line or dcache line is not flushed properly." I don't know what his actual observations were that lead to that conclusion, but the resemblence to what was reported under LTP with the pre-break_cow()-patch kernel intrigues me. So, I repeat... > > ...I don't have a 4Kc platform at > > hand, but I think that Jun Sun *may* have found a better > > way to get at the other problem I was referring to, which > > we rarely saw on non-superscalar issue CPUs, and which > > seems to be masked by an otherwise superfluous flush of > > the Icache that was added to the latest versions of break_cow(). > > If Carsten's patch solves the problem without applying that > > other update, I'd want to know that. If it *doesn't*, I'd be > > really interested to know if, by any chance, there is a > > corelation between failures of Jun Sun's test and the incidence > > of page faults on the CACHE op in protected_icache_invalidate_line(). > > > > Kevin K. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 17:08 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 17:08 UTC (permalink / raw) To: Carsten Langgaard; +Cc: linux-mips, Jun Sun > > I think that Carsten's patch (or equivalent) should certainly be > > applied to the main tree, but I wonder how relevant it is here. > > The flushes associated with trampolines don't do indexed > > flush operations, do they? > > True, but are we sure that it's the trampoline that's the problem here? Jun Sun seemed to think it was. To quote his original message "The problem involves emulating a "lw" instruction in cp1 branch delay slot, which needs to set up trampoline in user stack. The net effect looks as if the icache line or dcache line is not flushed properly." I don't know what his actual observations were that lead to that conclusion, but the resemblence to what was reported under LTP with the pre-break_cow()-patch kernel intrigues me. So, I repeat... > > ...I don't have a 4Kc platform at > > hand, but I think that Jun Sun *may* have found a better > > way to get at the other problem I was referring to, which > > we rarely saw on non-superscalar issue CPUs, and which > > seems to be masked by an otherwise superfluous flush of > > the Icache that was added to the latest versions of break_cow(). > > If Carsten's patch solves the problem without applying that > > other update, I'd want to know that. If it *doesn't*, I'd be > > really interested to know if, by any chance, there is a > > corelation between failures of Jun Sun's test and the incidence > > of page faults on the CACHE op in protected_icache_invalidate_line(). > > > > Kevin K. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 17:08 ` Kevin D. Kissell (?) @ 2002-12-04 17:32 ` Daniel Jacobowitz 2002-12-04 20:28 ` Carsten Langgaard -1 siblings, 1 reply; 29+ messages in thread From: Daniel Jacobowitz @ 2002-12-04 17:32 UTC (permalink / raw) To: Kevin D. Kissell; +Cc: Carsten Langgaard, linux-mips, Jun Sun On Wed, Dec 04, 2002 at 06:08:22PM +0100, Kevin D. Kissell wrote: > > > I think that Carsten's patch (or equivalent) should certainly be > > > applied to the main tree, but I wonder how relevant it is here. > > > The flushes associated with trampolines don't do indexed > > > flush operations, do they? > > > > True, but are we sure that it's the trampoline that's the problem here? > > Jun Sun seemed to think it was. To quote his original message > > "The problem involves emulating a "lw" instruction in cp1 branch delay > slot, which needs to set up trampoline in user stack. The net effect > looks as if the icache line or dcache line is not flushed properly." > > I don't know what his actual observations were that lead to that > conclusion, but the resemblence to what was reported under LTP > with the pre-break_cow()-patch kernel intrigues me. Here's some of the actual observations: if you single-step over the bc1t instruction, then it comes out as you'd expect; the load in the delay slot was executed. Even if you breakpoint in the general vicinity and then continue. But if you breakpoint _after_ the instruction, it is evident that the load did not occur as expected. > So, I repeat... > > > ...I don't have a 4Kc platform at > > > hand, but I think that Jun Sun *may* have found a better > > > way to get at the other problem I was referring to, which > > > we rarely saw on non-superscalar issue CPUs, and which > > > seems to be masked by an otherwise superfluous flush of > > > the Icache that was added to the latest versions of break_cow(). > > > If Carsten's patch solves the problem without applying that > > > other update, I'd want to know that. If it *doesn't*, I'd be > > > really interested to know if, by any chance, there is a > > > corelation between failures of Jun Sun's test and the incidence > > > of page faults on the CACHE op in protected_icache_invalidate_line(). > > > > > > Kevin K. > > > -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 17:32 ` Daniel Jacobowitz @ 2002-12-04 20:28 ` Carsten Langgaard 2002-12-04 22:58 ` Jun Sun 0 siblings, 1 reply; 29+ messages in thread From: Carsten Langgaard @ 2002-12-04 20:28 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: Kevin D. Kissell, linux-mips, Jun Sun Could you please tell us, which 4Kc you are running on ? What are the cache configuration (size, number of ways) ? Are you running on the latest kernel sources from the CVS tree ? Have you tried the mips32_cache.h file I send and/or have you tried the kernel from the ftp.mips.com FTP server ? Many question at the same time ;-) /Carsten Daniel Jacobowitz wrote: > On Wed, Dec 04, 2002 at 06:08:22PM +0100, Kevin D. Kissell wrote: > > > > I think that Carsten's patch (or equivalent) should certainly be > > > > applied to the main tree, but I wonder how relevant it is here. > > > > The flushes associated with trampolines don't do indexed > > > > flush operations, do they? > > > > > > True, but are we sure that it's the trampoline that's the problem here? > > > > Jun Sun seemed to think it was. To quote his original message > > > > "The problem involves emulating a "lw" instruction in cp1 branch delay > > slot, which needs to set up trampoline in user stack. The net effect > > looks as if the icache line or dcache line is not flushed properly." > > > > I don't know what his actual observations were that lead to that > > conclusion, but the resemblence to what was reported under LTP > > with the pre-break_cow()-patch kernel intrigues me. > > Here's some of the actual observations: if you single-step over the > bc1t instruction, then it comes out as you'd expect; the load in the > delay slot was executed. Even if you breakpoint in the general > vicinity and then continue. > > But if you breakpoint _after_ the instruction, it is evident that the > load did not occur as expected. > > > So, I repeat... > > > > ...I don't have a 4Kc platform at > > > > hand, but I think that Jun Sun *may* have found a better > > > > way to get at the other problem I was referring to, which > > > > we rarely saw on non-superscalar issue CPUs, and which > > > > seems to be masked by an otherwise superfluous flush of > > > > the Icache that was added to the latest versions of break_cow(). > > > > If Carsten's patch solves the problem without applying that > > > > other update, I'd want to know that. If it *doesn't*, I'd be > > > > really interested to know if, by any chance, there is a > > > > corelation between failures of Jun Sun's test and the incidence > > > > of page faults on the CACHE op in protected_icache_invalidate_line(). > > > > > > > > Kevin K. > > > > > > > > -- > Daniel Jacobowitz > MontaVista Software Debian GNU/Linux Developer ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 20:28 ` Carsten Langgaard @ 2002-12-04 22:58 ` Jun Sun 2002-12-05 9:38 ` Carsten Langgaard 0 siblings, 1 reply; 29+ messages in thread From: Jun Sun @ 2002-12-04 22:58 UTC (permalink / raw) To: Carsten Langgaard; +Cc: Daniel Jacobowitz, Kevin D. Kissell, linux-mips, jsun I guess I still did not answer some of your questions: On Wed, Dec 04, 2002 at 09:28:34PM +0100, Carsten Langgaard wrote: > Could you please tell us, which 4Kc you are running on ? Is the PRID telling enough? I posted it in the other email. > What are the cache configuration (size, number of ways) ? > Are you running on the latest kernel sources from the CVS tree ? Debugging work is done with my kernel, but confirmed that latest CVS tree shows the same problem. > Have you tried the mips32_cache.h file I send and No, because I don't think it is related to indexed cache operations. > /or have you tried the kernel > from the ftp.mips.com FTP server ? > Jun ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 22:58 ` Jun Sun @ 2002-12-05 9:38 ` Carsten Langgaard 2002-12-06 16:42 ` Maciej W. Rozycki 0 siblings, 1 reply; 29+ messages in thread From: Carsten Langgaard @ 2002-12-05 9:38 UTC (permalink / raw) To: Jun Sun; +Cc: Daniel Jacobowitz, Kevin D. Kissell, linux-mips I think I know what the problem is, the PRID is telling me everything. Jun Sun, you have just found an ancient 4Kc bug, sorry if you spend a lot of time debugging this. We have a newer TMSC 4Kc board, which doesn't have this problem You fix flushing the whole cache works, but the problem with this kind of bug, is that there are other potential problems. There is what the errata sheet says: E16. Fill buffers not flushed on CACHE instructions Problem: The fill buffers in the cache controllers were not flushed by CACHE instructions. Under certain circumstances, the fill buffer could service future loads even though the cache was invalidated with the intent of causing a refill from memory. The ICache fill buffer is left valid for all cache refills (and all cacheable read requests) until the following cache miss. In this case, memory was being updated and the ICache was being cleared. The line being cleared was the last one to be filled and there was not another cache miss before that line was re-accessed. The second fetch can get the stale data from the fill buffer. A similar problem exists in the DCache, but the DFB is invalidated when the cache is written. Thus, the only time this would be seen is if all ways of the DCache were locked and the fill buffer was being treated as an extra way of the cache. Implication: This could show up in any place where self modifying code exists and the ICache is selectively flushed. (If the entire cache is flushed, there will be an intervening cache miss or uncached reference to flush the FB). The problem with the DCache would primarily show up when accessing the same memory with different physical addresses or cache coherency attributes. If an invalidate is used to flush an entry from the DCache with the intent of forcing a refill, the refill may not occur. Workarounds: Flush the entire ICache when using self-modifying code. Force a cache miss, cache refill, or uncached access to clear fill buffers near the invalidation. For the instruction cache, this could be done by using a CACHE Fill instruction to pre-load the invalidation routine into the cache. This will force a refill which will flush the fill buffer. Status: Fixed. /Carsten Jun Sun wrote: > I guess I still did not answer some of your questions: > > On Wed, Dec 04, 2002 at 09:28:34PM +0100, Carsten Langgaard wrote: > > Could you please tell us, which 4Kc you are running on ? > > Is the PRID telling enough? I posted it in the other email. > > > What are the cache configuration (size, number of ways) ? > > Are you running on the latest kernel sources from the CVS tree ? > > Debugging work is done with my kernel, but confirmed that latest > CVS tree shows the same problem. > > > Have you tried the mips32_cache.h file I send and > > No, because I don't think it is related to indexed cache operations. > > > /or have you tried the kernel > > from the ftp.mips.com FTP server ? > > > > Jun -- _ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com |\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527 | \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555 TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556 Denmark http://www.mips.com ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-05 9:38 ` Carsten Langgaard @ 2002-12-06 16:42 ` Maciej W. Rozycki 2002-12-06 22:24 ` Hartvig Ekner 0 siblings, 1 reply; 29+ messages in thread From: Maciej W. Rozycki @ 2002-12-06 16:42 UTC (permalink / raw) To: Carsten Langgaard; +Cc: Kevin D. Kissell, linux-mips On Thu, 5 Dec 2002, Carsten Langgaard wrote: > There is what the errata sheet says: Is the errata doc available from anywhere? Actually are such docs available for any of your current (recent) processor products? -- + Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: macro@ds2.pg.gda.pl, PGP key available + ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-06 22:24 ` Hartvig Ekner 0 siblings, 0 replies; 29+ messages in thread From: Hartvig Ekner @ 2002-12-06 22:24 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: Carsten Langgaard, Kevin D. Kissell, linux-mips The documents are provided to all core customers, and our marketing dept has decided that nobody else needs them :-) As we now have a case which clearly proves otherwise, maybe somebody should reopen this discussion internally in MIPS? Dominic, do you want to volunteer? /Hartvig Maciej W. Rozycki writes: > > On Thu, 5 Dec 2002, Carsten Langgaard wrote: > > > There is what the errata sheet says: > > Is the errata doc available from anywhere? Actually are such docs > available for any of your current (recent) processor products? > > -- > + Maciej W. Rozycki, Technical University of Gdansk, Poland + > +--------------------------------------------------------------+ > + e-mail: macro@ds2.pg.gda.pl, PGP key available + ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-06 22:24 ` Hartvig Ekner 0 siblings, 0 replies; 29+ messages in thread From: Hartvig Ekner @ 2002-12-06 22:24 UTC (permalink / raw) To: Maciej W. Rozycki; +Cc: Carsten Langgaard, Kevin D. Kissell, linux-mips The documents are provided to all core customers, and our marketing dept has decided that nobody else needs them :-) As we now have a case which clearly proves otherwise, maybe somebody should reopen this discussion internally in MIPS? Dominic, do you want to volunteer? /Hartvig Maciej W. Rozycki writes: > > On Thu, 5 Dec 2002, Carsten Langgaard wrote: > > > There is what the errata sheet says: > > Is the errata doc available from anywhere? Actually are such docs > available for any of your current (recent) processor products? > > -- > + Maciej W. Rozycki, Technical University of Gdansk, Poland + > +--------------------------------------------------------------+ > + e-mail: macro@ds2.pg.gda.pl, PGP key available + ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-09 10:51 ` Dominic Sweetman 0 siblings, 0 replies; 29+ messages in thread From: Dominic Sweetman @ 2002-12-09 10:51 UTC (permalink / raw) To: Hartvig Ekner Cc: Maciej W. Rozycki, Carsten Langgaard, Kevin D. Kissell, linux-mips Hartvig, > As we now have a case which clearly proves otherwise, maybe somebody > should reopen this discussion internally in MIPS? Dominic, do you want > to volunteer? I am stirring... -- Dominic ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-09 10:51 ` Dominic Sweetman 0 siblings, 0 replies; 29+ messages in thread From: Dominic Sweetman @ 2002-12-09 10:51 UTC (permalink / raw) To: Hartvig Ekner Cc: Maciej W. Rozycki, Carsten Langgaard, Kevin D. Kissell, linux-mips Hartvig, > As we now have a case which clearly proves otherwise, maybe somebody > should reopen this discussion internally in MIPS? Dominic, do you want > to volunteer? I am stirring... -- Dominic ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 10:08 ` Carsten Langgaard 2002-12-04 11:21 ` Carsten Langgaard @ 2002-12-04 22:19 ` Jun Sun 2002-12-05 9:27 ` Kevin D. Kissell 1 sibling, 1 reply; 29+ messages in thread From: Jun Sun @ 2002-12-04 22:19 UTC (permalink / raw) To: Carsten Langgaard; +Cc: Kevin D. Kissell, linux-mips, jsun On Wed, Dec 04, 2002 at 11:08:20AM +0100, Carsten Langgaard wrote: > I have just tried your test on a 4Kc and I see no problems. > However I'm running on our internal kernel sources, and as Kevin mention we have > changed a fixed a few things in this area. > As Kevin also mention it sure look more like a I-cache invalidation problem, > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > One think you could try, is our latest kernel release. You can find it here: > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > Yes, the problem still exists with this kernel. Try to move the source tree to /root/, rename top dir to "try18", re-make the binary, and try again. This problem is tricky to reproduce. The location of the tree definitely matters. I am testing 32bit LE version. Have not tried BE. I think I have pinned down the problem. See my other follow-up posting. Jun ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-05 9:27 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-05 9:27 UTC (permalink / raw) To: Jun Sun, Carsten Langgaard; +Cc: linux-mips, jsun > On Wed, Dec 04, 2002 at 11:08:20AM +0100, Carsten Langgaard wrote: > > I have just tried your test on a 4Kc and I see no problems. > > However I'm running on our internal kernel sources, and as Kevin mention we have > > changed a fixed a few things in this area. > > As Kevin also mention it sure look more like a I-cache invalidation problem, > > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > > One think you could try, is our latest kernel release. You can find it here: > > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > > > Yes, the problem still exists with this kernel. > > Try to move the source tree to /root/, rename top dir to "try18", > re-make the binary, and try again. > > This problem is tricky to reproduce. The location of the tree > definitely matters. I am testing 32bit LE version. Have not > tried BE. > > I think I have pinned down the problem. See my other follow-up posting. Your results are certainly interesting and suspicious. Before I take it up with the designers as a possible hardware bug, I would really like to know if there is more than one chip which exhibits this behavior. In principle, it *could* be a manufacturing defect. And while I acknowledge that your trace info would seem to argue on the face of it that the hardware didn't do what it should have done, there is a remarkable similarity between what you report and something that Carsten saw on a couple of completely different CPUs a week or two ago, which makes me wonder if there isn't still some subtle software failure behind all this. Thank you very, very, much for digging into this as deeply as you have. Kevin K. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-05 9:27 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-05 9:27 UTC (permalink / raw) To: Jun Sun, Carsten Langgaard; +Cc: linux-mips > On Wed, Dec 04, 2002 at 11:08:20AM +0100, Carsten Langgaard wrote: > > I have just tried your test on a 4Kc and I see no problems. > > However I'm running on our internal kernel sources, and as Kevin mention we have > > changed a fixed a few things in this area. > > As Kevin also mention it sure look more like a I-cache invalidation problem, > > rather than a D-cache flush problem, as the 4Kc has a write-through cache. > > One think you could try, is our latest kernel release. You can find it here: > > ftp://ftp.mips.com/pub/linux/mips/kernel/2.4/images/ > > > > Yes, the problem still exists with this kernel. > > Try to move the source tree to /root/, rename top dir to "try18", > re-make the binary, and try again. > > This problem is tricky to reproduce. The location of the tree > definitely matters. I am testing 32bit LE version. Have not > tried BE. > > I think I have pinned down the problem. See my other follow-up posting. Your results are certainly interesting and suspicious. Before I take it up with the designers as a possible hardware bug, I would really like to know if there is more than one chip which exhibits this behavior. In principle, it *could* be a manufacturing defect. And while I acknowledge that your trace info would seem to argue on the face of it that the hardware didn't do what it should have done, there is a remarkable similarity between what you report and something that Carsten saw on a couple of completely different CPUs a week or two ago, which makes me wonder if there isn't still some subtle software failure behind all this. Thank you very, very, much for digging into this as deeply as you have. Kevin K. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 9:38 ` Kevin D. Kissell ` (2 preceding siblings ...) (?) @ 2002-12-04 21:59 ` Jun Sun 2002-12-04 23:14 ` Kevin D. Kissell -1 siblings, 1 reply; 29+ messages in thread From: Jun Sun @ 2002-12-04 21:59 UTC (permalink / raw) To: Kevin D. Kissell; +Cc: linux-mips, jsun On Wed, Dec 04, 2002 at 10:38:36AM +0100, Kevin D. Kissell wrote: > > Which version of the 4Kc manual are you looking at? I'm looking > at a very recent version of the 4Kc Software User's Manual > (version 1.17, dated September 25, 2002), and it only shows > Hit_Writeback_D to be invalid for *secondary and teritary* > caches, which makes sense, since the 4KSc doesn't have any. > I was looking at rev 1.12, Jan 3, 2001. Good to know that 4K family does have Hit_WRiteback_D. However, since it is "recommanded" instead of "required". Shouldn't we still use "Hit_Writeback_Inv_D" just to be on the safe side? Jun ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 23:14 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 23:14 UTC (permalink / raw) To: Jun Sun; +Cc: linux-mips, jsun > On Wed, Dec 04, 2002 at 10:38:36AM +0100, Kevin D. Kissell wrote: > > > > Which version of the 4Kc manual are you looking at? I'm looking > > at a very recent version of the 4Kc Software User's Manual > > (version 1.17, dated September 25, 2002), and it only shows > > Hit_Writeback_D to be invalid for *secondary and teritary* > > caches, which makes sense, since the 4KSc doesn't have any. > > > > I was looking at rev 1.12, Jan 3, 2001. > > Good to know that 4K family does have Hit_WRiteback_D. However, > since it is "recommanded" instead of "required". Shouldn't we > still use "Hit_Writeback_Inv_D" just to be on the safe side? Pardon me, but I thought that you were talking about hit-writeback-invalidates to begin with. Indeed, I had thought that we had organized things so that Linux always did writeback-invalidates and never simple writebacks, just to be on the safe side, as you say, but tampoline code is a special case where I can see no possible multiprocessor coherence issues with failing to invalidate the local Dcache copy. In any case, it would be100% correct for a pure "hit writeback" to be a no-op on a write-through cache, since there is never anything dirty to write back. Kevin K. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... @ 2002-12-04 23:14 ` Kevin D. Kissell 0 siblings, 0 replies; 29+ messages in thread From: Kevin D. Kissell @ 2002-12-04 23:14 UTC (permalink / raw) To: Jun Sun; +Cc: linux-mips > On Wed, Dec 04, 2002 at 10:38:36AM +0100, Kevin D. Kissell wrote: > > > > Which version of the 4Kc manual are you looking at? I'm looking > > at a very recent version of the 4Kc Software User's Manual > > (version 1.17, dated September 25, 2002), and it only shows > > Hit_Writeback_D to be invalid for *secondary and teritary* > > caches, which makes sense, since the 4KSc doesn't have any. > > > > I was looking at rev 1.12, Jan 3, 2001. > > Good to know that 4K family does have Hit_WRiteback_D. However, > since it is "recommanded" instead of "required". Shouldn't we > still use "Hit_Writeback_Inv_D" just to be on the safe side? Pardon me, but I thought that you were talking about hit-writeback-invalidates to begin with. Indeed, I had thought that we had organized things so that Linux always did writeback-invalidates and never simple writebacks, just to be on the safe side, as you say, but tampoline code is a special case where I can see no possible multiprocessor coherence issues with failing to invalidate the local Dcache copy. In any case, it would be100% correct for a pure "hit writeback" to be a no-op on a write-through cache, since there is never anything dirty to write back. Kevin K. ^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: possible Malta 4Kc cache problem ... 2002-12-04 6:45 possible Malta 4Kc cache problem Jun Sun 2002-12-04 9:38 ` Kevin D. Kissell @ 2002-12-04 22:53 ` Jun Sun 1 sibling, 0 replies; 29+ messages in thread From: Jun Sun @ 2002-12-04 22:53 UTC (permalink / raw) To: linux-mips; +Cc: jsun [-- Attachment #1: Type: text/plain, Size: 4566 bytes --] OK, I am fully convinced that this is some kind of hardware problem. Basically, it appears CPU is running from a stale icache line even though it has invalid flags! In order to see how I draw this conclusion, you will need to be a little patient. Here is the relavent user code segment: 400f3c: 45010009 bc1t 400f64 <C_x_co_DIDI_J+0x84> 400f40: 8c510008 lw $s1,8($v0) .... 400f94: 4501000a bc1t 400fc0 <C_x_co_DIDI_J+0xe0> 400f98: 8fa20050 lw $v0,80($sp) In both cases, branch are taken. The faulting symptom is that "lw" in the second delay slot does not load correct value to $v0. I wrote some sizable instrumentation code to capture what has happened before and after "lw" emulation. A rough patch of my change is included for the diehard hackers. Here is the output from my captured data for the faulting "lw" case: ---------- dsemul_insns = 7fff78f0, epc=00400f98, cpc=00400fc0, ir=8fa20050 v0 = 10000028, s1=00000004 ret_epc = 7fff78f4, ret_ir=8fa20050, ret_sp=7fff7900, ret_sp_80val=00000004 ret_v0 = 10000028, ret_s1=00000004, bad_addr=00000000 cache tags before: 0018a8f2, 03b878f0, 000308f2, 03b888f2 cache tags after : 0018a8f2, 03b87800, 000308f2, 03b888f2 mem @ a3b878f0 : 8fa20050, 8c000001, 0000bd36, 00400fc0 ---------- Several notes and observations: . 7fff78f0 is in fact 83b878f0 (or a3b878f0) in kernel space . ret_v0 is the v0 value after we return from trampoline execution. Wowla, it has the same value as before, meaning "lw $v0,80($sp)" did not happen. To further confirm that, I actually printed out the value at 80($sp) which is "ret_sp_80val=00000004" (That is the right value $v0 should have, BTW). . apparently the trampoline is executed, because we did come back from it through unaligned access exception. . In order to figure out what the first instruction is, I modified $s1 value to 0x55 right before we start to execute trampoline code. Guess what, after it comes back, $s1 is changed to "ret_s1=00000004", which suggests an stale instruction "lw $s1,8($v0)" was executed. This instruction was put into icache during the previous bc1t emulation. . "cache tags before/after" dumps cache tags of all four ways in the same set as the trampoline. It is clear that after flush_cache_sigtramp() the valid bits are correctly cleared. . The last line shows memory indeed has the right values. It is the icache to blame. . No page fault has happened during flush_cache_sigtramp() because bad_addr would otherwise contains the faulting address. It seems safe to conclude CPU executed from a stale icache line. I have no clue why icache exhibits such a problem. I modified flush_cache_sigtramp() to flush the whole icache, and things appear to be working. However, not knowing the root cause I am not 100% sure if this is a valid workaround. Here are some info related to the CPU: CPU revision is: 00018001 Primary instruction cache 16kb, linesize 16 bytes (4 ways) Primary data cache 16kb, linesize 16 bytes (4 ways) Jun On Tue, Dec 03, 2002 at 10:45:04PM -0800, Jun Sun wrote: > > I attached the test case. Untar it. Type 'make' and run 'a.out'. > > If the test fails you will see a print-out. Otherwise you see nothing. > > It does not always fail. But if it fails, it is usually pretty consistent. > Try a few times. Moving source tree to a different directory may cause > the symptom appear or disappear. > > I spent quite some time to trace this problem, and came to suspect > there might be a hardware problem. > > The problem involves emulating a "lw" instruction in cp1 branch delay > slot, which needs to set up trampoline in user stack. The net effect > looks as if the icache line or dcache line is not flushed properly. > > Using gdb/kgdb, printf or printk in any useful places would hide the bug. > > I did find a smaller part of the problem. flush_cache_sigtramp for > MIPS32 (4Kc) calls protected_writeback_dcache_line in mips32_cache.h. > It uses Hit_Writeback_D, and the 4Kc mannual says it is not implemented > and executed as no-op (*ick*). > > Even after fixing this, I still see the problem happening. > > If you replace flush_cache_sigtramp() with flush_cache_all(), symptom > would disppear. > > Several of my tests seem to suggest it is the icache that did not > get flushed (or updated) properly. > > Not re-producible on other MIPS boards. At least so far. > > Does anybody with more knowledge about 4Kc have any clues here? > > Thanks. > > Jun [-- Attachment #2: trace.patch --] [-- Type: text/plain, Size: 10213 bytes --] diff -Nru ./arch/mips/math-emu/cp1emu.c.orig ./arch/mips/math-emu/cp1emu.c --- ./arch/mips/math-emu/cp1emu.c.orig Tue Oct 22 18:36:50 2002 +++ ./arch/mips/math-emu/cp1emu.c Wed Dec 4 13:44:55 2002 @@ -772,6 +772,47 @@ /* Instruction inserted following the AdELOAD to further tag the sequence */ #define BD_COOKIE 0x0000bd36 /* tne $0,$0 with baggage */ +int jsun_flag=0; +unsigned long jsun_addr; +struct { + unsigned dsemul_insns, epc, cpc, ir; + unsigned v0, s1; + unsigned ret_epc, ret_ir, ret_sp, ret_sp_80val; + unsigned ret_v0, ret_s1; + unsigned long bad_addr; + unsigned cache_tag[4], ret_cache_tag[4]; + unsigned long kaddr; + unsigned kaddr_data[4]; +} jsun_array[200]; +int jsun_index; + +extern unsigned long user_to_kernel(unsigned long addr); +extern int dcache_way_offset, icache_way_offset; + +#include <asm/cacheops.h> +static inline unsigned load_icache_line_indexed(unsigned long addr) +{ + __asm__ __volatile__( + ".set noreorder\n\t" + ".set mips3\n\t" + "cache %1, (%0)\n\t" + ".set mips0\n\t" + ".set reorder" + : + : "r" (addr), + "i" (Index_Load_Tag_I)); + + return read_32bit_cp0_register(CP0_TAGLO); +} + +void read_cache_tag(unsigned long addr, unsigned *tag) +{ + tag[0] = load_icache_line_indexed(addr); + tag[1] = load_icache_line_indexed(addr+icache_way_offset); + tag[2] = load_icache_line_indexed(addr+icache_way_offset*2); + tag[3] = load_icache_line_indexed(addr+icache_way_offset*3); +} + int do_dsemulret(struct pt_regs *xcp) { unsigned long *pinst; @@ -786,7 +827,7 @@ * If we can't even access the area, something is very wrong, but we'll * leave that to the default handling */ - if (verify_area(VERIFY_READ, pinst, sizeof(unsigned long) * 3)) + if (verify_area(VERIFY_READ, pinst-1, sizeof(unsigned long) * 4)) return 0; /* Is the instruction pointed to by the EPC an AdELOAD? */ @@ -826,16 +867,77 @@ /* Set EPC to return to post-branch instruction */ xcp->cp0_epc = stackitem; + jsun_array[jsun_index].ret_epc = (unsigned long)pinst; + jsun_array[jsun_index].ret_ir = mips_get_word(xcp, pinst-1, &err); + jsun_array[jsun_index].ret_sp = xcp->regs[29]; + jsun_array[jsun_index].ret_v0 = xcp->regs[2]; + jsun_array[jsun_index].ret_s1 = xcp->regs[17]; + jsun_array[jsun_index].ret_sp_80val = mips_get_word(xcp, xcp->regs[29]+80, &err); + if (jsun_array[jsun_index].ret_ir == 0x8fa20050) { + xcp->regs[17] = jsun_array[jsun_index].s1; + } + + jsun_index ++; + return 1; } #define AdELOAD 0x8c000001 /* lw $0,1($0) */ +void jsun_dump_struct(void) +{ + int i; + printk("dump jsun_struct:\n"); + for (i=0; i< jsun_index; i++) { + printk("------\n"); + printk("dsemul_insns = %08x, epc=%08x, cpc=%08x, ir=%08x\n", + jsun_array[i].dsemul_insns, + jsun_array[i].epc, + jsun_array[i].cpc, + jsun_array[i].ir); + printk("v0 = %08x, s1=%08x\n", + jsun_array[i].v0, + jsun_array[i].s1); + printk("ret_epc = %08x, ret_ir=%08x, ret_sp=%08x, ret_sp_80val=%08x\n", + jsun_array[i].ret_epc, + jsun_array[i].ret_ir, + jsun_array[i].ret_sp, + jsun_array[i].ret_sp_80val); + printk("ret_v0 = %08x, ret_s1=%08x, bad_addr=%08lx\n", + jsun_array[i].ret_v0, + jsun_array[i].ret_s1, + jsun_array[i].bad_addr + ); + printk("cache tags before: %08x, %08x, %08x, %08x\n", + jsun_array[i].cache_tag[0], + jsun_array[i].cache_tag[1], + jsun_array[i].cache_tag[2], + jsun_array[i].cache_tag[3] + ); + printk("cache tags after : %08x, %08x, %08x, %08x\n", + jsun_array[i].ret_cache_tag[0], + jsun_array[i].ret_cache_tag[1], + jsun_array[i].ret_cache_tag[2], + jsun_array[i].ret_cache_tag[3] + ); + printk("mem @ %08x : %08x, %08x, %08x, %08x\n", + jsun_array[i].kaddr + 0x20000000, + jsun_array[i].kaddr_data[0], + jsun_array[i].kaddr_data[1], + jsun_array[i].kaddr_data[2], + jsun_array[i].kaddr_data[3]); + + } + jsun_index = 0; +} + static int mips_dsemul(struct pt_regs *regs, mips_instruction ir, vaddr_t cpc) { mips_instruction *dsemul_insns; extern asmlinkage void handle_dsemulret(void); + mips_instruction new_ir; + unsigned long temp; if (ir == 0) { /* a nop is easy */ regs->cp0_epc = VA_TO_REG(cpc); @@ -864,11 +966,17 @@ dsemul_insns = (mips_instruction *) (regs->regs[29] & ~0xf); dsemul_insns -= 4; /* Retain 16-byte alignment */ + temp=user_to_kernel((unsigned long)dsemul_insns); + /* Verify that the stack pointer is not competely insane */ if (verify_area (VERIFY_WRITE, dsemul_insns, sizeof(mips_instruction) * 4)) return SIGBUS; + if (ir == 0x8fa20050) { + // ir = 0x24020004; // li v0, 9 + // regs->regs[2]=0; + } if (mips_put_word(regs, &dsemul_insns[0], ir)) { fpuemuprivate.stats.errors++; return (SIGBUS); @@ -890,9 +998,50 @@ return (SIGBUS); } + + jsun_array[jsun_index].dsemul_insns = (unsigned long)dsemul_insns; + jsun_array[jsun_index].epc = (unsigned long)regs->cp0_epc; + jsun_array[jsun_index].cpc = cpc; + jsun_array[jsun_index].v0 = regs->regs[2]; + jsun_array[jsun_index].s1 = regs->regs[17]; + jsun_array[jsun_index].ir = *(unsigned long *)&ir; + jsun_array[jsun_index].kaddr = temp; + + // jsun_index ++; + + if (ir == 0x8fa20050) { + regs->regs[17] = 0x55; + } + regs->cp0_epc = VA_TO_REG & dsemul_insns[0]; + read_cache_tag(temp, jsun_array[jsun_index].cache_tag); + jsun_addr=0; flush_cache_sigtramp((unsigned long)dsemul_insns); + jsun_array[jsun_index].bad_addr = jsun_addr; + read_cache_tag(temp, jsun_array[jsun_index].ret_cache_tag); + + jsun_array[jsun_index].kaddr_data[0] = *(unsigned*)(temp + 0x20000000); + jsun_array[jsun_index].kaddr_data[1] = *(unsigned*)(temp + 0x20000004); + jsun_array[jsun_index].kaddr_data[2] = *(unsigned*)(temp + 0x20000008); + jsun_array[jsun_index].kaddr_data[3] = *(unsigned*)(temp + 0x2000000c); + + // my_flush_cache_sigtramp((unsigned long)dsemul_insns); + // flush_cache_all(); + +#if 0 + jsun_addr=user_to_kernel((unsigned long)dsemul_insns); + if (jsun_addr) + printk("mem @ %08x : %08x, %08x, %08x, %08x\n", + jsun_addr, + *(unsigned long*)jsun_addr, + *(unsigned long*)(jsun_addr+4), + *(unsigned long*)(jsun_addr+8), + *(unsigned long*)(jsun_addr+12)); + else + printk("convertion failed\n"); +#endif + return SIGILL; /* force out of emulation loop */ } diff -Nru ./arch/mips/mm/c-mips32.c.orig ./arch/mips/mm/c-mips32.c --- ./arch/mips/mm/c-mips32.c.orig Tue Dec 3 18:54:52 2002 +++ ./arch/mips/mm/c-mips32.c Wed Dec 4 13:04:29 2002 @@ -39,6 +39,7 @@ /* Primary cache parameters. */ int icache_size, dcache_size; /* Size in bytes */ int ic_lsize, dc_lsize; /* LineSize in bytes */ +int icache_way_offset, dcache_way_offset; /* offset between ways w. same set */ /* Secondary cache (if present) parameters. */ unsigned int scache_size, sc_lsize; /* Again, in bytes */ @@ -407,6 +408,55 @@ * very much about what happens in that case. Usually a segmentation * fault will dump the process later on anyway ... */ +static void indexed_writeback_dcache_line(unsigned long addr) +{ + int i; + int set_size = dcache_size / mips_cpu.dcache.ways; + for (i=0; i<mips_cpu.dcache.ways; i++) { + flush_dcache_line_indexed(addr); + addr += set_size; + } +} + +void my_flush_cache_sigtramp(unsigned long addr) +{ + indexed_writeback_dcache_line(addr & ~(dc_lsize - 1)); + protected_flush_icache_line(addr & ~(ic_lsize - 1)); +} + +unsigned long user_to_kernel(unsigned long addr) +{ + unsigned offset; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + mem_map_t *pg; + struct mm_struct *mm; + + offset = addr & ~PAGE_MASK; + addr &= PAGE_MASK; + if (!current->mm || + !current->mm->context || + !current->active_mm || + !current->active_mm->context || + current->mm != current->active_mm) { + printk("user_to_kernel condition failed\n"); + return 0; + } + + mm= current->mm; + pgd = pgd_offset(mm, addr); + pmd = pmd_offset(pgd, addr); + pte = pte_offset(pmd, addr); + if(!(pte_val(*pte) & _PAGE_VALID)) { + printk("user_to_kernel : pte not valid\n"); + return 0; + } + + pg= pte_page(*pte); + return (unsigned long)pg->virtual + offset; +} + static void mips32_flush_cache_sigtramp(unsigned long addr) { protected_writeback_dcache_line(addr & ~(dc_lsize - 1)); @@ -451,6 +501,7 @@ } printk("Primary instruction cache %dkb, linesize %d bytes (%d ways)\n", icache_size >> 10, ic_lsize, mips_cpu.icache.ways); + icache_way_offset = icache_size / mips_cpu.icache.ways; } static void __init probe_dcache(unsigned long config) @@ -490,6 +541,7 @@ } printk("Primary data cache %dkb, linesize %d bytes (%d ways)\n", dcache_size >> 10, dc_lsize, mips_cpu.dcache.ways); + dcache_way_offset = dcache_size / mips_cpu.dcache.ways; } diff -Nru ./arch/mips/mm/fault.c.orig ./arch/mips/mm/fault.c --- ./arch/mips/mm/fault.c.orig Tue Oct 22 18:36:51 2002 +++ ./arch/mips/mm/fault.c Wed Dec 4 10:35:26 2002 @@ -74,6 +74,7 @@ * and the problem, and then passes it off to one of the appropriate * routines. */ +extern unsigned long jsun_addr; asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, unsigned long address) { @@ -193,6 +194,7 @@ long new_epc; tsk->thread.cp0_baduaddr = address; + jsun_addr = address; new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); if (development_version) printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", diff -Nru ./include/asm-mips/mips32_cache.h.orig ./include/asm-mips/mips32_cache.h --- ./include/asm-mips/mips32_cache.h.orig Tue Oct 22 18:37:03 2002 +++ ./include/asm-mips/mips32_cache.h Tue Dec 3 18:24:25 2002 @@ -171,7 +171,7 @@ ".previous" : : "r" (addr), - "i" (Hit_Writeback_D)); + "i" (Hit_Writeback_Inv_D)); } #define cache_unroll(base,op) \ diff -Nru ./net/ipv4/icmp.c.orig ./net/ipv4/icmp.c --- ./net/ipv4/icmp.c.orig Mon Feb 25 11:38:14 2002 +++ ./net/ipv4/icmp.c Tue Dec 3 12:08:01 2002 @@ -733,6 +733,7 @@ static void icmp_echo(struct sk_buff *skb) { + jsun_dump_struct(); if (!sysctl_icmp_echo_ignore_all) { struct icmp_bxm icmp_param; ^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2002-12-09 10:53 UTC | newest] Thread overview: 29+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2002-12-04 6:45 possible Malta 4Kc cache problem Jun Sun 2002-12-04 9:38 ` Kevin D. Kissell 2002-12-04 9:38 ` Kevin D. Kissell 2002-12-04 9:46 ` Kevin D. Kissell 2002-12-04 9:46 ` Kevin D. Kissell 2002-12-04 10:08 ` Carsten Langgaard 2002-12-04 11:21 ` Carsten Langgaard 2002-12-04 13:06 ` Kevin D. Kissell 2002-12-04 13:06 ` Kevin D. Kissell 2002-12-04 13:14 ` Carsten Langgaard 2002-12-04 13:28 ` Carsten Langgaard 2002-12-04 17:08 ` Kevin D. Kissell 2002-12-04 17:08 ` Kevin D. Kissell 2002-12-04 17:32 ` Daniel Jacobowitz 2002-12-04 20:28 ` Carsten Langgaard 2002-12-04 22:58 ` Jun Sun 2002-12-05 9:38 ` Carsten Langgaard 2002-12-06 16:42 ` Maciej W. Rozycki 2002-12-06 22:24 ` Hartvig Ekner 2002-12-06 22:24 ` Hartvig Ekner 2002-12-09 10:51 ` Dominic Sweetman 2002-12-09 10:51 ` Dominic Sweetman 2002-12-04 22:19 ` Jun Sun 2002-12-05 9:27 ` Kevin D. Kissell 2002-12-05 9:27 ` Kevin D. Kissell 2002-12-04 21:59 ` Jun Sun 2002-12-04 23:14 ` Kevin D. Kissell 2002-12-04 23:14 ` Kevin D. Kissell 2002-12-04 22:53 ` Jun Sun
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.