* parisc: flush pages through tmpalias space
@ 2010-12-22 16:22 James Bottomley
2010-12-23 0:07 ` Carlos O'Donell
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: James Bottomley @ 2010-12-22 16:22 UTC (permalink / raw)
To: Parisc List
The kernel has an 8M tmpailas space (originally designed for copying
and clearing pages but now only used for clearing). The idea is
to place zeros into the cache above a physical page rather than into
the physical page and flush the cache, because often the zeros end up
being replaced quickly anyway.
We can also use the tmpalias space for flushing a page. The difference
here is that we have to do tmpalias processing in the non access data and
instruction traps. The principle is the same: as long as we know the physical
address and have a virtual address congruent to the real one, the flush will
be effective.
In order to use the tmpalias space, the icache miss path has to be enhanced to
check for the alias region to make the fic instruction effective.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
arch/parisc/include/asm/cacheflush.h | 7 +-
arch/parisc/kernel/cache.c | 109 +++-------------
arch/parisc/kernel/entry.S | 194 ++++++++++++++++++++-------
arch/parisc/kernel/pacache.S | 245 +++++++++++++++-------------------
4 files changed, 272 insertions(+), 283 deletions(-)
diff --git a/arch/parisc/include/asm/cacheflush.h b/arch/parisc/include/asm/cacheflush.h
index f388a85..dc9286a 100644
--- a/arch/parisc/include/asm/cacheflush.h
+++ b/arch/parisc/include/asm/cacheflush.h
@@ -26,8 +26,6 @@ void flush_user_dcache_range_asm(unsigned long, unsigned long);
void flush_kernel_dcache_range_asm(unsigned long, unsigned long);
void flush_kernel_dcache_page_asm(void *);
void flush_kernel_icache_page(void *);
-void flush_user_dcache_page(unsigned long);
-void flush_user_icache_page(unsigned long);
void flush_user_dcache_range(unsigned long, unsigned long);
void flush_user_icache_range(unsigned long, unsigned long);
@@ -90,12 +88,15 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned
void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end);
+/* defined in pacache.S exported in cache.c used by flush_anon_page */
+void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
+
#define ARCH_HAS_FLUSH_ANON_PAGE
static inline void
flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
{
if (PageAnon(page))
- flush_user_dcache_page(vmaddr);
+ flush_dcache_page_asm(page_to_phys(page), vmaddr);
}
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index d054f3d..3f11331 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -27,12 +27,17 @@
#include <asm/pgalloc.h>
#include <asm/processor.h>
#include <asm/sections.h>
+#include <asm/shmparam.h>
int split_tlb __read_mostly;
int dcache_stride __read_mostly;
int icache_stride __read_mostly;
EXPORT_SYMBOL(dcache_stride);
+void flush_dcache_page_asm(unsigned long phys_addr, unsigned long vaddr);
+EXPORT_SYMBOL(flush_dcache_page_asm);
+void flush_icache_page_asm(unsigned long phys_addr, unsigned long vaddr);
+
/* On some machines (e.g. ones with the Merced bus), there can be
* only a single PxTLB broadcast at a time; this must be guaranteed
@@ -259,81 +264,13 @@ void disable_sr_hashing(void)
panic("SpaceID hashing is still on!\n");
}
-/* Simple function to work out if we have an existing address translation
- * for a user space vma. */
-static inline int translation_exists(struct vm_area_struct *vma,
- unsigned long addr, unsigned long pfn)
-{
- pgd_t *pgd = pgd_offset(vma->vm_mm, addr);
- pmd_t *pmd;
- pte_t pte;
-
- if(pgd_none(*pgd))
- return 0;
-
- pmd = pmd_offset(pgd, addr);
- if(pmd_none(*pmd) || pmd_bad(*pmd))
- return 0;
-
- /* We cannot take the pte lock here: flush_cache_page is usually
- * called with pte lock already held. Whereas flush_dcache_page
- * takes flush_dcache_mmap_lock, which is lower in the hierarchy:
- * the vma itself is secure, but the pte might come or go racily.
- */
- pte = *pte_offset_map(pmd, addr);
- /* But pte_unmap() does nothing on this architecture */
-
- /* Filter out coincidental file entries and swap entries */
- if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT)))
- return 0;
-
- return pte_pfn(pte) == pfn;
-}
-
-/* Private function to flush a page from the cache of a non-current
- * process. cr25 contains the Page Directory of the current user
- * process; we're going to hijack both it and the user space %sr3 to
- * temporarily make the non-current process current. We have to do
- * this because cache flushing may cause a non-access tlb miss which
- * the handlers have to fill in from the pgd of the non-current
- * process. */
static inline void
-flush_user_cache_page_non_current(struct vm_area_struct *vma,
- unsigned long vmaddr)
+__flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr,
+ unsigned long physaddr)
{
- /* save the current process space and pgd */
- unsigned long space = mfsp(3), pgd = mfctl(25);
-
- /* we don't mind taking interrupts since they may not
- * do anything with user space, but we can't
- * be preempted here */
- preempt_disable();
-
- /* make us current */
- mtctl(__pa(vma->vm_mm->pgd), 25);
- mtsp(vma->vm_mm->context, 3);
-
- flush_user_dcache_page(vmaddr);
- if(vma->vm_flags & VM_EXEC)
- flush_user_icache_page(vmaddr);
-
- /* put the old current process back */
- mtsp(space, 3);
- mtctl(pgd, 25);
- preempt_enable();
-}
-
-
-static inline void
-__flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr)
-{
- if (likely(vma->vm_mm->context == mfsp(3))) {
- flush_user_dcache_page(vmaddr);
- if (vma->vm_flags & VM_EXEC)
- flush_user_icache_page(vmaddr);
- } else {
- flush_user_cache_page_non_current(vma, vmaddr);
- }
+ flush_dcache_page_asm(physaddr, vmaddr);
+ if (vma->vm_flags & VM_EXEC)
+ flush_icache_page_asm(physaddr, vmaddr);
}
void flush_dcache_page(struct page *page)
@@ -342,10 +279,8 @@ void flush_dcache_page(struct page *page)
struct vm_area_struct *mpnt;
struct prio_tree_iter iter;
unsigned long offset;
- unsigned long addr;
+ unsigned long addr, old_addr = 0;
pgoff_t pgoff;
- unsigned long pfn = page_to_pfn(page);
-
if (mapping && !mapping_mapped(mapping)) {
set_bit(PG_dcache_dirty, &page->flags);
@@ -369,20 +304,11 @@ void flush_dcache_page(struct page *page)
offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
addr = mpnt->vm_start + offset;
- /* Flush instructions produce non access tlb misses.
- * On PA, we nullify these instructions rather than
- * taking a page fault if the pte doesn't exist.
- * This is just for speed. If the page translation
- * isn't there, there's no point exciting the
- * nadtlb handler into a nullification frenzy.
- *
- * Make sure we really have this page: the private
- * mappings may cover this area but have COW'd this
- * particular page.
- */
- if (translation_exists(mpnt, addr, pfn)) {
- __flush_cache_page(mpnt, addr);
- break;
+ if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
+ __flush_cache_page(mpnt, addr, page_to_phys(page));
+ if (old_addr)
+ printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
+ old_addr = addr;
}
}
flush_dcache_mmap_unlock(mapping);
@@ -573,7 +499,6 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long
{
BUG_ON(!vma->vm_mm->context);
- if (likely(translation_exists(vma, vmaddr, pfn)))
- __flush_cache_page(vma, vmaddr);
+ __flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn)));
}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 6337ade..564606d 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -225,22 +225,13 @@
#ifndef CONFIG_64BIT
/*
* naitlb miss interruption handler (parisc 1.1 - 32 bit)
- *
- * Note: naitlb misses will be treated
- * as an ordinary itlb miss for now.
- * However, note that naitlb misses
- * have the faulting address in the
- * IOR/ISR.
*/
.macro naitlb_11 code
mfctl %isr,spc
- b itlb_miss_11
+ b naitlb_miss_11
mfctl %ior,va
- /* FIXME: If user causes a naitlb miss, the priv level may not be in
- * lower bits of va, where the itlb miss handler is expecting them
- */
.align 32
.endm
@@ -248,26 +239,17 @@
/*
* naitlb miss interruption handler (parisc 2.0)
- *
- * Note: naitlb misses will be treated
- * as an ordinary itlb miss for now.
- * However, note that naitlb misses
- * have the faulting address in the
- * IOR/ISR.
*/
.macro naitlb_20 code
mfctl %isr,spc
#ifdef CONFIG_64BIT
- b itlb_miss_20w
+ b naitlb_miss_20w
#else
- b itlb_miss_20
+ b naitlb_miss_20
#endif
mfctl %ior,va
- /* FIXME: If user causes a naitlb miss, the priv level may not be in
- * lower bits of va, where the itlb miss handler is expecting them
- */
.align 32
.endm
@@ -581,7 +563,24 @@
copy \va,\tmp1
depi 0,31,23,\tmp1
cmpb,COND(<>),n \tmp,\tmp1,\fault
- ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot
+ mfctl %cr19,\tmp /* iir */
+ /* get the opcode (first six bits) into \tmp */
+ extrw,u \tmp,5,6,\tmp
+ /*
+ * Only setting the T bit prevents data cache movein
+ * Setting access rights to zero prevents instruction cache movein
+ *
+ * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
+ * to type field and _PAGE_READ goes to top bit of PL1
+ */
+ ldi (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
+ /*
+ * so if the opcode is one (i.e. this is a memory management
+ * instruction) nullify the next load so \prot is only T.
+ * Otherwise this is a normal data operation
+ */
+ cmpiclr,= 0x01,\tmp,%r0
+ ldi (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
depd,z \prot,8,7,\prot
/*
* OK, it is in the temp alias region, check whether "from" or "to".
@@ -631,11 +630,7 @@ ENTRY(fault_vector_20)
def 13
def 14
dtlb_20 15
-#if 0
naitlb_20 16
-#else
- def 16
-#endif
nadtlb_20 17
def 18
def 19
@@ -678,11 +673,7 @@ ENTRY(fault_vector_11)
def 13
def 14
dtlb_11 15
-#if 0
naitlb_11 16
-#else
- def 16
-#endif
nadtlb_11 17
def 18
def 19
@@ -1203,7 +1194,7 @@ nadtlb_miss_20w:
get_pgd spc,ptp
space_check spc,t0,nadtlb_fault
- L3_ptep ptp,pte,t0,va,nadtlb_check_flush_20w
+ L3_ptep ptp,pte,t0,va,nadtlb_check_alias_20w
update_ptep ptp,pte,t0,t1
@@ -1214,6 +1205,14 @@ nadtlb_miss_20w:
rfir
nop
+nadtlb_check_alias_20w:
+ do_alias spc,t0,t1,va,pte,prot,nadtlb_check_flush_20w
+
+ idtlbt pte,prot
+
+ rfir
+ nop
+
nadtlb_check_flush_20w:
bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate
@@ -1255,25 +1254,7 @@ dtlb_miss_11:
nop
dtlb_check_alias_11:
-
- /* Check to see if fault is in the temporary alias region */
-
- cmpib,<>,n 0,spc,dtlb_fault /* forward */
- ldil L%(TMPALIAS_MAP_START),t0
- copy va,t1
- depwi 0,31,23,t1
- cmpb,<>,n t0,t1,dtlb_fault /* forward */
- ldi (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
- depw,z prot,8,7,prot
-
- /*
- * OK, it is in the temp alias region, check whether "from" or "to".
- * Check "subtle" note in pacache.S re: r23/r26.
- */
-
- extrw,u,= va,9,1,r0
- or,tr %r23,%r0,pte /* If "from" use "from" page */
- or %r26,%r0,pte /* else "to", use "to" page */
+ do_alias spc,t0,t1,va,pte,prot,dtlb_fault
idtlba pte,(va)
idtlbp prot,(va)
@@ -1286,7 +1267,7 @@ nadtlb_miss_11:
space_check spc,t0,nadtlb_fault
- L2_ptep ptp,pte,t0,va,nadtlb_check_flush_11
+ L2_ptep ptp,pte,t0,va,nadtlb_check_alias_11
update_ptep ptp,pte,t0,t1
@@ -1304,6 +1285,15 @@ nadtlb_miss_11:
rfir
nop
+nadtlb_check_alias_11:
+ do_alias spc,t0,t1,va,pte,prot,nadtlb_check_flush_11
+
+ idtlba pte,(va)
+ idtlbp prot,(va)
+
+ rfir
+ nop
+
nadtlb_check_flush_11:
bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate
@@ -1359,7 +1349,7 @@ nadtlb_miss_20:
space_check spc,t0,nadtlb_fault
- L2_ptep ptp,pte,t0,va,nadtlb_check_flush_20
+ L2_ptep ptp,pte,t0,va,nadtlb_check_alias_20
update_ptep ptp,pte,t0,t1
@@ -1372,6 +1362,14 @@ nadtlb_miss_20:
rfir
nop
+nadtlb_check_alias_20:
+ do_alias spc,t0,t1,va,pte,prot,nadtlb_check_flush_20
+
+ idtlbt pte,prot
+
+ rfir
+ nop
+
nadtlb_check_flush_20:
bb,>=,n pte,_PAGE_FLUSH_BIT,nadtlb_emulate
@@ -1484,6 +1482,36 @@ itlb_miss_20w:
rfir
nop
+naitlb_miss_20w:
+
+ /*
+ * I miss is a little different, since we allow users to fault
+ * on the gateway page which is in the kernel address space.
+ */
+
+ space_adjust spc,va,t0
+ get_pgd spc,ptp
+ space_check spc,t0,naitlb_fault
+
+ L3_ptep ptp,pte,t0,va,naitlb_check_alias_20w
+
+ update_ptep ptp,pte,t0,t1
+
+ make_insert_tlb spc,pte,prot
+
+ iitlbt pte,prot
+
+ rfir
+ nop
+
+naitlb_check_alias_20w:
+ do_alias spc,t0,t1,va,pte,prot,naitlb_fault
+
+ iitlbt pte,prot
+
+ rfir
+ nop
+
#else
itlb_miss_11:
@@ -1508,6 +1536,38 @@ itlb_miss_11:
rfir
nop
+naitlb_miss_11:
+ get_pgd spc,ptp
+
+ space_check spc,t0,naitlb_fault
+
+ L2_ptep ptp,pte,t0,va,naitlb_check_alias_11
+
+ update_ptep ptp,pte,t0,t1
+
+ make_insert_tlb_11 spc,pte,prot
+
+ mfsp %sr1,t0 /* Save sr1 so we can use it in tlb inserts */
+ mtsp spc,%sr1
+
+ iitlba pte,(%sr1,va)
+ iitlbp prot,(%sr1,va)
+
+ mtsp t0, %sr1 /* Restore sr1 */
+
+ rfir
+ nop
+
+naitlb_check_alias_11:
+ do_alias spc,t0,t1,va,pte,prot,itlb_fault
+
+ iitlba pte,(%sr0, va)
+ iitlbp prot,(%sr0, va)
+
+ rfir
+ nop
+
+
itlb_miss_20:
get_pgd spc,ptp
@@ -1526,6 +1586,32 @@ itlb_miss_20:
rfir
nop
+naitlb_miss_20:
+ get_pgd spc,ptp
+
+ space_check spc,t0,naitlb_fault
+
+ L2_ptep ptp,pte,t0,va,naitlb_check_alias_20
+
+ update_ptep ptp,pte,t0,t1
+
+ make_insert_tlb spc,pte,prot
+
+ f_extend pte,t0
+
+ iitlbt pte,prot
+
+ rfir
+ nop
+
+naitlb_check_alias_20:
+ do_alias spc,t0,t1,va,pte,prot,naitlb_fault
+
+ iitlbt pte,prot
+
+ rfir
+ nop
+
#endif
#ifdef CONFIG_64BIT
@@ -1662,6 +1748,10 @@ nadtlb_fault:
b intr_save
ldi 17,%r8
+naitlb_fault:
+ b intr_save
+ ldi 16,%r8
+
dtlb_fault:
b intr_save
ldi 15,%r8
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 09b77b2..881b287 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -608,93 +608,131 @@ ENTRY(__clear_user_page_asm)
.procend
ENDPROC(__clear_user_page_asm)
-ENTRY(flush_kernel_dcache_page_asm)
+ENTRY(flush_dcache_page_asm)
.proc
.callinfo NO_CALLS
.entry
+ ldil L%(TMPALIAS_MAP_START), %r28
+#ifdef CONFIG_64BIT
+#if (TMPALIAS_MAP_START >= 0x80000000)
+ depdi 0, 31,32, %r28 /* clear any sign extension */
+ /* FIXME: page size dependend */
+#endif
+ extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
+ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
+ depdi 0, 63,12, %r28 /* Clear any offset bits */
+#else
+ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
+ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
+ depwi 0, 31,12, %r28 /* Clear any offset bits */
+#endif
+
+ /* Purge any old translation */
+
+ pdtlb 0(%r28)
+
ldil L%dcache_stride, %r1
- ldw R%dcache_stride(%r1), %r23
+ ldw R%dcache_stride(%r1), %r1
#ifdef CONFIG_64BIT
depdi,z 1, 63-PAGE_SHIFT,1, %r25
#else
depwi,z 1, 31-PAGE_SHIFT,1, %r25
#endif
- add %r26, %r25, %r25
- sub %r25, %r23, %r25
-
-
-1: fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- fdc,m %r23(%r26)
- cmpb,COND(<<) %r26, %r25,1b
- fdc,m %r23(%r26)
+ add %r28, %r25, %r25
+ sub %r25, %r1, %r25
+
+1: fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ fdc,m %r1(%r28)
+ cmpb,COND(<<) %r28, %r25,1b
+ fdc,m %r1(%r28)
+
sync
bv %r0(%r2)
- nop
+ pdtlb (%r25)
.exit
.procend
-ENDPROC(flush_kernel_dcache_page_asm)
-
-ENTRY(flush_user_dcache_page)
+ENDPROC(flush_dcache_page_asm)
+
+ENTRY(flush_icache_page_asm)
.proc
.callinfo NO_CALLS
.entry
- ldil L%dcache_stride, %r1
- ldw R%dcache_stride(%r1), %r23
-
+ ldil L%(TMPALIAS_MAP_START), %r28
#ifdef CONFIG_64BIT
- depdi,z 1,63-PAGE_SHIFT,1, %r25
+#if (TMPALIAS_MAP_START >= 0x80000000)
+ depdi 0, 31,32, %r28 /* clear any sign extension */
+ /* FIXME: page size dependend */
+#endif
+ extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
+ depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
+ depdi 0, 63,12, %r28 /* Clear any offset bits */
#else
- depwi,z 1,31-PAGE_SHIFT,1, %r25
+ extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
+ depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
+ depwi 0, 31,12, %r28 /* Clear any offset bits */
#endif
- add %r26, %r25, %r25
- sub %r25, %r23, %r25
+ /* Purge any old translation */
-1: fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- fdc,m %r23(%sr3, %r26)
- cmpb,COND(<<) %r26, %r25,1b
- fdc,m %r23(%sr3, %r26)
+ pitlb (%sr0,%r28)
+ ldil L%icache_stride, %r1
+ ldw R%icache_stride(%r1), %r1
+
+#ifdef CONFIG_64BIT
+ depdi,z 1, 63-PAGE_SHIFT,1, %r25
+#else
+ depwi,z 1, 31-PAGE_SHIFT,1, %r25
+#endif
+ add %r28, %r25, %r25
+ sub %r25, %r1, %r25
+
+
+1: fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ fic,m %r1(%r28)
+ cmpb,COND(<<) %r28, %r25,1b
+ fic,m %r1(%r28)
+
sync
bv %r0(%r2)
- nop
+ pitlb (%sr0,%r25)
.exit
.procend
-ENDPROC(flush_user_dcache_page)
+ENDPROC(flush_icache_page_asm)
-ENTRY(flush_user_icache_page)
+ENTRY(flush_kernel_dcache_page_asm)
.proc
.callinfo NO_CALLS
.entry
@@ -711,23 +749,23 @@ ENTRY(flush_user_icache_page)
sub %r25, %r23, %r25
-1: fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
- fic,m %r23(%sr3, %r26)
+1: fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
+ fdc,m %r23(%r26)
cmpb,COND(<<) %r26, %r25,1b
- fic,m %r23(%sr3, %r26)
+ fdc,m %r23(%r26)
sync
bv %r0(%r2)
@@ -735,8 +773,7 @@ ENTRY(flush_user_icache_page)
.exit
.procend
-ENDPROC(flush_user_icache_page)
-
+ENDPROC(flush_kernel_dcache_page_asm)
ENTRY(purge_kernel_dcache_page)
.proc
@@ -780,69 +817,6 @@ ENTRY(purge_kernel_dcache_page)
.procend
ENDPROC(purge_kernel_dcache_page)
-#if 0
- /* Currently not used, but it still is a possible alternate
- * solution.
- */
-
-ENTRY(flush_alias_page)
- .proc
- .callinfo NO_CALLS
- .entry
-
- tophys_r1 %r26
-
- ldil L%(TMPALIAS_MAP_START), %r28
-#ifdef CONFIG_64BIT
- extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */
- depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */
- depdi 0, 63,12, %r28 /* Clear any offset bits */
-#else
- extrw,u %r26, 24,25, %r26 /* convert phys addr to tlb insert format */
- depw %r25, 31,22, %r28 /* Form aliased virtual address 'to' */
- depwi 0, 31,12, %r28 /* Clear any offset bits */
-#endif
-
- /* Purge any old translation */
-
- pdtlb 0(%r28)
-
- ldil L%dcache_stride, %r1
- ldw R%dcache_stride(%r1), %r23
-
-#ifdef CONFIG_64BIT
- depdi,z 1, 63-PAGE_SHIFT,1, %r29
-#else
- depwi,z 1, 31-PAGE_SHIFT,1, %r29
-#endif
- add %r28, %r29, %r29
- sub %r29, %r23, %r29
-
-1: fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- fdc,m %r23(%r28)
- cmpb,COND(<<) %r28, %r29, 1b
- fdc,m %r23(%r28)
-
- sync
- bv %r0(%r2)
- nop
- .exit
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-22 16:22 parisc: flush pages through tmpalias space James Bottomley
@ 2010-12-23 0:07 ` Carlos O'Donell
2010-12-23 3:04 ` John David Anglin
` (3 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: Carlos O'Donell @ 2010-12-23 0:07 UTC (permalink / raw)
To: James Bottomley; +Cc: Parisc List
On Wed, Dec 22, 2010 at 11:22 AM, James Bottomley
<James.Bottomley@hansenpartnership.com> wrote:
> The kernel has an 8M tmpailas space (originally designed for copying
> and clearing pages but now only used for clearing). =A0The idea is
> to place zeros into the cache above a physical page rather than into
> the physical page and flush the cache, because often the zeros end up
> being replaced quickly anyway.
>
> We can also use the tmpalias space for flushing a page. =A0The differ=
ence
> here is that we have to do tmpalias processing in the non access data=
and
> instruction traps. =A0The principle is the same: as long as we know t=
he physical
> address and have a virtual address congruent to the real one, the flu=
sh will
> be effective.
>
> In order to use the tmpalias space, the icache miss path has to be en=
hanced to
> check for the alias region to make the fic instruction effective.
James,
Given that you are currently maintaining the parisc tree, do you have
a public branch that we can pull from to test things?
I've normally been using:
git://git.kernel.org/pub/scm/linux/kernel/git/kyle/parisc-2.6.git
I would like to test this patch, and the next one you posted, and I
was wondering if you have them on a public branch.
Cheers,
Carlos.
--
To unsubscribe from this list: send the line "unsubscribe linux-parisc"=
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-22 16:22 parisc: flush pages through tmpalias space James Bottomley
2010-12-23 0:07 ` Carlos O'Donell
@ 2010-12-23 3:04 ` John David Anglin
2010-12-25 21:52 ` Helge Deller
` (2 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: John David Anglin @ 2010-12-23 3:04 UTC (permalink / raw)
To: James Bottomley; +Cc: Parisc List
On Wed, 22 Dec 2010, James Bottomley wrote:
> The kernel has an 8M tmpailas space (originally designed for copying
> and clearing pages but now only used for clearing). The idea is
> to place zeros into the cache above a physical page rather than into
> the physical page and flush the cache, because often the zeros end up
> being replaced quickly anyway.
>
> We can also use the tmpalias space for flushing a page. The difference
> here is that we have to do tmpalias processing in the non access data and
> instruction traps. The principle is the same: as long as we know the physical
> address and have a virtual address congruent to the real one, the flush will
> be effective.
>
> In order to use the tmpalias space, the icache miss path has to be enhanced to
> check for the alias region to make the fic instruction effective.
Very cool. "dependent" is misspelled in a couple places. Will test.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-22 16:22 parisc: flush pages through tmpalias space James Bottomley
2010-12-23 0:07 ` Carlos O'Donell
2010-12-23 3:04 ` John David Anglin
@ 2010-12-25 21:52 ` Helge Deller
2010-12-29 14:49 ` James Bottomley
2010-12-29 4:23 ` John David Anglin
2011-01-09 21:52 ` John David Anglin
4 siblings, 1 reply; 18+ messages in thread
From: Helge Deller @ 2010-12-25 21:52 UTC (permalink / raw)
To: James Bottomley; +Cc: Parisc List
On 12/22/2010 05:22 PM, James Bottomley wrote:
> The kernel has an 8M tmpailas space (originally designed for copying
> and clearing pages but now only used for clearing). The idea is
> to place zeros into the cache above a physical page rather than into
> the physical page and flush the cache, because often the zeros end up
> being replaced quickly anyway.
>
> We can also use the tmpalias space for flushing a page. The difference
> here is that we have to do tmpalias processing in the non access data and
> instruction traps. The principle is the same: as long as we know the physical
> address and have a virtual address congruent to the real one, the flush will
> be effective.
>
> In order to use the tmpalias space, the icache miss path has to be enhanced to
> check for the alias region to make the fic instruction effective.
>
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Hi James,
Cool, I assume this patch intends to fix the "Threads and fork on VIPT-WB machines" bug as described here: http://wiki.parisc-linux.org/TestCases ?
I did some initial testing and it seems to really fix it...
I'll continue testing during the next few days (with 2.6.37-rc7-32bit).
Helge
BTW: compilation gives one small warning:
arch/parisc/kernel/cache.c: In function 'flush_dcache_page':
arch/parisc/kernel/cache.c:310: warning: pointer type mismatch in conditional expression
arch/parisc/kernel/cache.c:310: warning: format '%s' expects type 'char *', but argument 4 has type 'void * const'
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-22 16:22 parisc: flush pages through tmpalias space James Bottomley
` (2 preceding siblings ...)
2010-12-25 21:52 ` Helge Deller
@ 2010-12-29 4:23 ` John David Anglin
2010-12-29 14:51 ` James Bottomley
2011-01-09 21:52 ` John David Anglin
4 siblings, 1 reply; 18+ messages in thread
From: John David Anglin @ 2010-12-29 4:23 UTC (permalink / raw)
To: James Bottomley; +Cc: Parisc List
On Wed, 22 Dec 2010, James Bottomley wrote:
> + if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
> + __flush_cache_page(mpnt, addr, page_to_phys(page));
> + if (old_addr)
> + printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
> + old_addr = addr;
> }
I'm seeing the above kernel error on shutdown:
Dec 26 12:30:56 mx3210 kernel: INEQUIVALENT ALIASES 0x13000 and 0x14000 in file killall5
Dec 26 12:30:56 mx3210 kernel: INEQUIVALENT ALIASES 0x40122000 and 0x40121000 in file ld-2.11.2.so
Dec 26 12:30:57 mx3210 kernel: INEQUIVALENT ALIASES 0x402a7000 and 0x402a6000 in file libc-2.11.2.so
This is with 2.6.36.2 and your two patches on a SMP kernel. I've also seen
these messages with a similar UP build in the gcc guality tests. These
check debug info with gdb.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-25 21:52 ` Helge Deller
@ 2010-12-29 14:49 ` James Bottomley
0 siblings, 0 replies; 18+ messages in thread
From: James Bottomley @ 2010-12-29 14:49 UTC (permalink / raw)
To: Helge Deller; +Cc: Parisc List
On Sat, 2010-12-25 at 22:52 +0100, Helge Deller wrote:
> On 12/22/2010 05:22 PM, James Bottomley wrote:
> > The kernel has an 8M tmpailas space (originally designed for copying
> > and clearing pages but now only used for clearing). The idea is
> > to place zeros into the cache above a physical page rather than into
> > the physical page and flush the cache, because often the zeros end up
> > being replaced quickly anyway.
> >
> > We can also use the tmpalias space for flushing a page. The difference
> > here is that we have to do tmpalias processing in the non access data and
> > instruction traps. The principle is the same: as long as we know the physical
> > address and have a virtual address congruent to the real one, the flush will
> > be effective.
> >
> > In order to use the tmpalias space, the icache miss path has to be enhanced to
> > check for the alias region to make the fic instruction effective.
> >
> > Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
>
>
> Hi James,
>
> Cool, I assume this patch intends to fix the "Threads and fork on
> VIPT-WB machines" bug as described here:
> http://wiki.parisc-linux.org/TestCases ?
Well, not really ... it's meant to provide data to fix that case. The
theory behind them is that if we flush in the wrong place (say after the
mapping has been torn down), then the flush becomes ineffective. The
idea of flushing through the tmpalias space is that the flush becomes
effective regardless of placement. I didn't really think we had any
ineffective flushes, but it's good to demonstrate that.
> I did some initial testing and it seems to really fix it...
> I'll continue testing during the next few days (with 2.6.37-rc7-32bit).
That's an interesting data point ... it certainly doesn't fix the
problem with me on pa8800 SMP.
James
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-29 4:23 ` John David Anglin
@ 2010-12-29 14:51 ` James Bottomley
2010-12-30 15:56 ` John David Anglin
0 siblings, 1 reply; 18+ messages in thread
From: James Bottomley @ 2010-12-29 14:51 UTC (permalink / raw)
To: John David Anglin; +Cc: Parisc List
On Tue, 2010-12-28 at 23:23 -0500, John David Anglin wrote:
> On Wed, 22 Dec 2010, James Bottomley wrote:
>
> > + if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
> > + __flush_cache_page(mpnt, addr, page_to_phys(page));
> > + if (old_addr)
> > + printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
> > + old_addr = addr;
> > }
>
> I'm seeing the above kernel error on shutdown:
>
> Dec 26 12:30:56 mx3210 kernel: INEQUIVALENT ALIASES 0x13000 and 0x14000 in file killall5
> Dec 26 12:30:56 mx3210 kernel: INEQUIVALENT ALIASES 0x40122000 and 0x40121000 in file ld-2.11.2.so
> Dec 26 12:30:57 mx3210 kernel: INEQUIVALENT ALIASES 0x402a7000 and 0x402a6000 in file libc-2.11.2.so
>
> This is with 2.6.36.2 and your two patches on a SMP kernel. I've also seen
> these messages with a similar UP build in the gcc guality tests. These
> check debug info with gdb.
Yes, I still don't know why, but fortunately the one above is the same
one I see, which only occurs when the system goes down. I suspect
something is specifying a fixed offset for the library mappings which
violates our 4MB equivalency rule.
James
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-29 14:51 ` James Bottomley
@ 2010-12-30 15:56 ` John David Anglin
2010-12-30 16:09 ` John David Anglin
0 siblings, 1 reply; 18+ messages in thread
From: John David Anglin @ 2010-12-30 15:56 UTC (permalink / raw)
To: James Bottomley; +Cc: John David Anglin, Parisc List
[-- Attachment #1: Type: text/plain, Size: 1688 bytes --]
On Wed, 29 Dec 2010, James Bottomley wrote:
> > Dec 26 12:30:57 mx3210 kernel: INEQUIVALENT ALIASES 0x402a7000 and 0x402a6000 in file libc-2.11.2.so
> >
> > This is with 2.6.36.2 and your two patches on a SMP kernel. I've also seen
> > these messages with a similar UP build in the gcc guality tests. These
> > check debug info with gdb.
>
> Yes, I still don't know why, but fortunately the one above is the same
> one I see, which only occurs when the system goes down. I suspect
> something is specifying a fixed offset for the library mappings which
> violates our 4MB equivalency rule.
Attached is an application that triggers similar errors:
Dec 29 23:27:02 mx3210 kernel: INEQUIVALENT ALIASES 0x11000 and 0x12000 in file example.exe
If I was to guess, I think the problem is likely caused by the brk system
calls from popen:
...
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40001000
mprotect(0x40518000, 1413120, PROT_READ|PROT_WRITE) = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40002000
mprotect(0x40518000, 1413120, PROT_READ|PROT_EXEC) = 0
munmap(0x40185000, 24154) = 0
brk(0) = 0x13000
brk(0x34000) = 0x34000
pipe2([3, 4], O_CLOEXEC) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x40000a68) = 3035
close(3) = 0
...
It's hard to debug because gdb needs to attach.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
[-- Attachment #2: example.c --]
[-- Type: text/plain, Size: 2187 bytes --]
/* { dg-do run { xfail *-*-* } } */
/* { dg-options "-g" } */
#define GUALITY_DONT_FORCE_LIVE_AFTER -1
#ifndef STATIC_INLINE
#define STATIC_INLINE /*static*/
#endif
#include "guality.h"
#include <assert.h>
/* Test the debug info for the functions used in the VTA
presentation at the GCC Summit 2008. */
typedef struct list {
struct list *n;
int v;
} elt, *node;
STATIC_INLINE node
find_val (node c, int v, node e)
{
while (c < e)
{
GUALCHK (c);
GUALCHK (v);
GUALCHK (e);
if (c->v == v)
return c;
GUALCHK (c);
GUALCHK (v);
GUALCHK (e);
c++;
}
return NULL;
}
STATIC_INLINE node
find_prev (node c, node w)
{
while (c)
{
node o = c;
c = c->n;
GUALCHK (c);
GUALCHK (o);
GUALCHK (w);
if (c == w)
return o;
GUALCHK (c);
GUALCHK (o);
GUALCHK (w);
}
return NULL;
}
STATIC_INLINE node
check_arr (node c, node e)
{
if (c == e)
return NULL;
e--;
while (c < e)
{
GUALCHK (c);
GUALCHK (e);
if (c->v > (c+1)->v)
return c;
GUALCHK (c);
GUALCHK (e);
c++;
}
return NULL;
}
STATIC_INLINE node
check_list (node c, node t)
{
while (c != t)
{
node n = c->n;
GUALCHK (c);
GUALCHK (n);
GUALCHK (t);
if (c->v > n->v)
return c;
GUALCHK (c);
GUALCHK (n);
GUALCHK (t);
c = n;
}
return NULL;
}
struct list testme[] = {
{ &testme[1], 2 },
{ &testme[2], 3 },
{ &testme[3], 5 },
{ &testme[4], 7 },
{ &testme[5], 11 },
{ NULL, 13 },
};
int
main (int argc, char *argv[])
{
int n = sizeof (testme) / sizeof (*testme);
node first, last, begin, end, ret;
GUALCHKXPR (n);
begin = first = &testme[0];
last = &testme[n-1];
end = &testme[n];
GUALCHKXPR (first);
GUALCHKXPR (last);
GUALCHKXPR (begin);
GUALCHKXPR (end);
ret = find_val (begin, 13, end);
GUALCHK (ret);
assert (ret == last);
ret = find_prev (first, last);
GUALCHK (ret);
assert (ret == &testme[n-2]);
ret = check_arr (begin, end);
GUALCHK (ret);
assert (!ret);
ret = check_list (first, last);
GUALCHK (ret);
assert (!ret);
}
[-- Attachment #3: example.exe.gz --]
[-- Type: application/x-gunzip, Size: 10555 bytes --]
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-30 15:56 ` John David Anglin
@ 2010-12-30 16:09 ` John David Anglin
2011-01-01 18:31 ` John David Anglin
0 siblings, 1 reply; 18+ messages in thread
From: John David Anglin @ 2010-12-30 16:09 UTC (permalink / raw)
To: James Bottomley; +Cc: John David Anglin, Parisc List
[-- Attachment #1: Type: text/plain, Size: 380 bytes --]
On Thu, 30 Dec 2010, John David Anglin wrote:
> Attached is an application that triggers similar errors:
Sorry, missed the key bit of code. Hope previous message
isn't blocked. If so, I'll resend without exe.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
[-- Attachment #2: guality.h --]
[-- Type: text/plain, Size: 11754 bytes --]
/* Infrastructure to test the quality of debug information.
Copyright (C) 2008, 2009 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that 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 GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
/* This is a first cut at checking that debug information matches
run-time. The idea is to annotate programs with GUALCHK* macros
that guide the tests.
In the current implementation, all of the macros expand to function
calls. On the one hand, this interferes with optimizations; on the
other hand, it establishes an optimization barrier and a clear
inspection point, where previous operations (as in the abstract
machine) should have been completed and have their effects visible,
and future operations shouldn't have started yet.
In the current implementation of guality_check(), we fork a child
process that runs gdb, attaches to the parent process (the one that
called guality_check), moves up one stack frame (to the caller of
guality_check) and then examines the given expression.
If it matches the expected value, we have a PASS. If it differs,
we have a FAILure. If it is missing, we'll have a FAIL or an
UNRESOLVED depending on whether the variable or expression might be
unavailable at that point, as indicated by the third argument.
We envision a future alternate implementation with two compilation
and execution cycles, say one that runs the program and uses the
macros to log expressions and expected values, another in which the
macros expand to nothing and the logs are used to guide a debug
session that tests the values. How to identify the inspection
points in the second case is yet to be determined. It is
recommended that GUALCHK* macros be by themselves in source lines,
so that __FILE__ and __LINE__ will be usable to identify them.
*/
/* This is the type we use to pass values to guality_check. */
typedef intmax_t gualchk_t;
/* Convert a pointer or integral type to the widest integral type,
as expected by guality_check. */
#ifndef __cplusplus
#define GUALCVT(val) \
((gualchk_t)__builtin_choose_expr \
(__builtin_types_compatible_p (__typeof (val), gualchk_t), \
(val), \
__builtin_choose_expr \
(__builtin_classify_type (val) \
== __builtin_classify_type (&guality_skip), \
(uintptr_t)(val),(intptr_t)(val))))
#else
template <typename T>
inline __attribute__((always_inline)) gualchk_t
gualcvt (T *val)
{
return (uintptr_t) val;
}
template <typename T>
inline __attribute__((always_inline)) gualchk_t
gualcvt (T val)
{
return (intptr_t) val;
}
template <>
inline __attribute__((always_inline)) gualchk_t
gualcvt<gualchk_t> (gualchk_t val)
{
return val;
}
#define GUALCVT(val) gualcvt (val)
#endif
/* Attach a debugger to the current process and verify that the string
EXPR, evaluated by the debugger, yields the gualchk_t number VAL.
If the debugger cannot compute the expression, say because the
variable is unavailable, this will count as an error, unless unkok
is nonzero. */
#define GUALCHKXPRVAL(expr, val, unkok) \
guality_check ((expr), (val), (unkok))
/* Check that a debugger knows that EXPR evaluates to the run-time
value of EXPR. Unknown values are marked as acceptable,
considering that EXPR may die right after this call. This will
affect the generated code in that EXPR will be evaluated and forced
to remain live at least until right before the call to
guality_check, although not necessarily after the call. */
#define GUALCHKXPR(expr) \
GUALCHKXPRVAL (#expr, GUALCVT (expr), 1)
/* Same as GUALCHKXPR, but issue an error if the variable is optimized
away. */
#define GUALCHKVAL(expr) \
GUALCHKXPRVAL (#expr, GUALCVT (expr), 0)
/* Check that a debugger knows that EXPR evaluates to the run-time
value of EXPR. Unknown values are marked as errors, because the
value of EXPR is forced to be available right after the call, for a
range of at least one instruction. This will affect the generated
code, in that EXPR *will* be evaluated before and preserved until
after the call to guality_check. */
#define GUALCHKFLA(expr) do { \
__typeof(expr) volatile __preserve_after; \
__typeof(expr) __preserve_before = (expr); \
GUALCHKXPRVAL (#expr, GUALCVT (__preserve_before), 0); \
__preserve_after = __preserve_before; \
asm ("" : : "m" (__preserve_after)); \
} while (0)
/* GUALCHK is the simplest way to assert that debug information for an
expression matches its run-time value. Whether to force the
expression live after the call, so as to flag incompleteness
errors, can be disabled by defining GUALITY_DONT_FORCE_LIVE_AFTER.
Setting it to -1, an error is issued for optimized out variables,
even though they are not forced live. */
#if ! GUALITY_DONT_FORCE_LIVE_AFTER
#define GUALCHK(var) GUALCHKFLA(var)
#elif GUALITY_DONT_FORCE_LIVE_AFTER < 0
#define GUALCHK(var) GUALCHKVAL(var)
#else
#define GUALCHK(var) GUALCHKXPR(var)
#endif
/* The name of the GDB program, with arguments to make it quiet. This
is GUALITY_GDB_DEFAULT GUALITY_GDB_ARGS by default, but it can be
overridden by setting the GUALITY_GDB environment variable, whereas
GUALITY_GDB_DEFAULT can be overridden by setting the
GUALITY_GDB_NAME environment variable. */
static const char *guality_gdb_command;
#define GUALITY_GDB_DEFAULT "gdb"
#if defined(__unix)
# define GUALITY_GDB_REDIRECT " > /dev/null 2>&1"
#elif defined (_WIN32) || defined (MSDOS)
# define GUALITY_GDB_REDIRECT " > nul"
#else
# define GUALITY_GDB_REDIRECT ""
#endif
#define GUALITY_GDB_ARGS " -nx -nw --quiet" GUALITY_GDB_REDIRECT
/* Kinds of results communicated as exit status from child process
that runs gdb to the parent process that's being monitored. */
enum guality_counter { PASS, INCORRECT, INCOMPLETE };
/* Count of passes and errors. */
static int guality_count[INCOMPLETE+1];
/* If --guality-skip is given in the command line, all the monitoring,
forking and debugger-attaching action will be disabled. This is
useful to run the monitor program within a debugger. */
static int guality_skip;
/* This is a file descriptor to which we'll issue gdb commands to
probe and test. */
FILE *guality_gdb_input;
/* This holds the line number where we're supposed to set a
breakpoint. */
int guality_breakpoint_line;
/* GDB should set this to true once it's connected. */
int volatile guality_attached;
/* This function is the main guality program. It may actually be
defined as main, because we #define main to it afterwards. Because
of this wrapping, guality_main may not have an empty argument
list. */
extern int guality_main (int argc, char *argv[]);
static void __attribute__((noinline))
guality_check (const char *name, gualchk_t value, int unknown_ok);
/* Set things up, run guality_main, then print a summary and quit. */
int
main (int argc, char *argv[])
{
int i;
char *argv0 = argv[0];
guality_gdb_command = getenv ("GUALITY_GDB");
if (!guality_gdb_command)
{
guality_gdb_command = getenv ("GUALITY_GDB_NAME");
if (!guality_gdb_command)
guality_gdb_command = GUALITY_GDB_DEFAULT GUALITY_GDB_ARGS;
else
{
int len = strlen (guality_gdb_command) + sizeof (GUALITY_GDB_ARGS);
char *buf = (char *) __builtin_alloca (len);
strcpy (buf, guality_gdb_command);
strcat (buf, GUALITY_GDB_ARGS);
guality_gdb_command = buf;
}
}
for (i = 1; i < argc; i++)
if (strcmp (argv[i], "--guality-skip") == 0)
guality_skip = 1;
else
break;
if (!guality_skip)
{
guality_gdb_input = popen (guality_gdb_command, "w");
/* This call sets guality_breakpoint_line. */
guality_check (NULL, 0, 0);
if (!guality_gdb_input
|| fprintf (guality_gdb_input, "\
set height 0\n\
attach %i\n\
set guality_attached = 1\n\
b %i\n\
continue\n\
", (int)getpid (), guality_breakpoint_line) <= 0
|| fflush (guality_gdb_input))
{
perror ("gdb");
abort ();
}
}
argv[--i] = argv0;
guality_main (argc - i, argv + i);
i = guality_count[INCORRECT];
fprintf (stderr, "%s: %i PASS, %i FAIL, %i UNRESOLVED\n",
i ? "FAIL" : "PASS",
guality_count[PASS], guality_count[INCORRECT],
guality_count[INCOMPLETE]);
return i;
}
#define main guality_main
/* Tell the GDB child process to evaluate NAME in the caller. If it
matches VALUE, we have a PASS; if it's unknown and UNKNOWN_OK, we
have an UNRESOLVED. Otherwise, it's a FAIL. */
static void __attribute__((noinline))
guality_check (const char *name, gualchk_t value, int unknown_ok)
{
int result;
if (guality_skip)
return;
{
volatile gualchk_t xvalue = -1;
volatile int unavailable = 0;
if (name)
{
/* The sequence below cannot distinguish an optimized away
variable from one mapped to a non-lvalue zero. */
if (fprintf (guality_gdb_input, "\
up\n\
set $value1 = 0\n\
set $value1 = (%s)\n\
set $value2 = -1\n\
set $value2 = (%s)\n\
set $value3 = $value1 - 1\n\
set $value4 = $value1 + 1\n\
set $value3 = (%s)++\n\
set $value4 = --(%s)\n\
down\n\
set xvalue = $value1\n\
set unavailable = $value1 != $value2 ? -1 : $value3 != $value4 ? 1 : 0\n\
continue\n\
", name, name, name, name) <= 0
|| fflush (guality_gdb_input))
{
perror ("gdb");
abort ();
}
else if (!guality_attached)
{
unsigned int timeout = 0;
/* Give GDB some more time to attach. Wrapping around a
32-bit counter takes some seconds, it should be plenty
of time for GDB to get a chance to start up and attach,
but not long enough that, if GDB is unavailable or
broken, we'll take far too long to give up. */
while (--timeout && !guality_attached)
;
if (!timeout && !guality_attached)
{
fprintf (stderr, "gdb: took too long to attach\n");
abort ();
}
}
}
else
{
guality_breakpoint_line = __LINE__ + 5;
return;
}
/* Do NOT add lines between the __LINE__ above and the line below,
without also adjusting the added constant to match. */
if (!unavailable || (unavailable > 0 && xvalue))
{
if (xvalue == value)
result = PASS;
else
result = INCORRECT;
}
else
result = INCOMPLETE;
asm ("" : : "X" (name), "X" (value), "X" (unknown_ok), "m" (xvalue));
switch (result)
{
case PASS:
fprintf (stderr, "PASS: %s is %lli\n", name, value);
break;
case INCORRECT:
fprintf (stderr, "FAIL: %s is %lli, not %lli\n", name, xvalue, value);
break;
case INCOMPLETE:
fprintf (stderr, "%s: %s is %s, expected %lli\n",
unknown_ok ? "UNRESOLVED" : "FAIL", name,
unavailable < 0 ? "not computable" : "optimized away", value);
result = unknown_ok ? INCOMPLETE : INCORRECT;
break;
default:
abort ();
}
}
switch (result)
{
case PASS:
case INCORRECT:
case INCOMPLETE:
++guality_count[result];
break;
default:
abort ();
}
}
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-30 16:09 ` John David Anglin
@ 2011-01-01 18:31 ` John David Anglin
2011-01-01 19:00 ` John David Anglin
2011-01-05 3:49 ` John David Anglin
0 siblings, 2 replies; 18+ messages in thread
From: John David Anglin @ 2011-01-01 18:31 UTC (permalink / raw)
To: James Bottomley; +Cc: John David Anglin, Parisc List
On Thu, 30 Dec 2010, John David Anglin wrote:
> On Thu, 30 Dec 2010, John David Anglin wrote:
>
> > Attached is an application that triggers similar errors:
Here is a simpler testcase:
int main ()
{
asm ("stw %r0,0(%r0)"); /* Generate null pointer exception */
return 0;
}
With the above, I get the following INEQUIVALENT ALIASES messages:
Jan 1 10:23:19 gsyprf11 kernel: [135942.140000] INEQUIVALENT ALIASES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
Jan 1 10:23:19 gsyprf11 kernel: [135942.224000] INEQUIVALENT ALIASES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
Running with strace, I see the following mmap call:
mmap(0x406b1000, 28672, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x158000) = 0x406b1000
This is from glibc.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-01 18:31 ` John David Anglin
@ 2011-01-01 19:00 ` John David Anglin
2011-01-05 3:49 ` John David Anglin
1 sibling, 0 replies; 18+ messages in thread
From: John David Anglin @ 2011-01-01 19:00 UTC (permalink / raw)
To: James Bottomley; +Cc: John David Anglin, Parisc List
On Sat, 01 Jan 2011, John David Anglin wrote:
> mmap(0x406b1000, 28672, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x158000) = 0x406b1000
>
> This is from glibc.
In arch_get_unmapped_area(), it says:
/* Might want to check for cache aliasing issues for MAP_FIXED case
* like ARM or MIPS ??? --BenH.
*/
if (flags & MAP_FIXED)
return addr;
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-01 18:31 ` John David Anglin
2011-01-01 19:00 ` John David Anglin
@ 2011-01-05 3:49 ` John David Anglin
2011-01-05 17:37 ` Carlos O'Donell
1 sibling, 1 reply; 18+ messages in thread
From: John David Anglin @ 2011-01-05 3:49 UTC (permalink / raw)
To: James Bottomley; +Cc: John David Anglin, Parisc List
On Sat, 01 Jan 2011, John David Anglin wrote:
> On Thu, 30 Dec 2010, John David Anglin wrote:
>
> > On Thu, 30 Dec 2010, John David Anglin wrote:
> >
> > > Attached is an application that triggers similar errors:
>
> Here is a simpler testcase:
>
> int main ()
> {
> asm ("stw %r0,0(%r0)"); /* Generate null pointer exception */
> return 0;
> }
>
> With the above, I get the following INEQUIVALENT ALIASES messages:
>
> Jan 1 10:23:19 gsyprf11 kernel: [135942.140000] INEQUIVALENT ALIASES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
> Jan 1 10:23:19 gsyprf11 kernel: [135942.224000] INEQUIVALENT ALIASES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
This is what I see in the tasks maps file in /proc:
00010000-00011000 r-xp 00000000 08:30 6613687 /home2/dave/inequiv/xxx1
00011000-00012000 rwxp 00000000 08:30 6613687 /home2/dave/inequiv/xxx1
40000000-40005000 rw-p 00000000 00:00 0
4002b000-4004b000 r-xp 00000000 08:03 2502157 /lib/ld-2.11.2.so
4004b000-4004f000 rwxp 0001f000 08:03 2502157 /lib/ld-2.11.2.so
4004f000-40050000 rwxp 00000000 00:00 0
40138000-40291000 r-xp 00000000 08:03 2502172 /lib/libc-2.11.2.so
40291000-40298000 rwxp 00158000 08:03 2502172 /lib/libc-2.11.2.so
40298000-4029a000 rwxp 00000000 00:00 0
fe09b000-fe0be000 rwxp 00000000 00:00 0 [stack]
As can be seen, there are duplicate maps with different protections for xxx1,
etc. So, it's clear why we have the inequivalent aliases. The map can
be accessed by the application (probably just for lines in the cache).
I have seen some discussions that even a read may lead to cache corruption.
These inequivalent maps are coming from glibc:
dave@gsyprf11:~/inequiv$ strace /lib/ld-2.11.2.so ./xxx1
execve("/lib/ld-2.11.2.so", ["/lib/ld-2.11.2.so", "./xxx1"], [/* 17 vars */]) = 0
brk(0) = 0x4119a000
open("./xxx1", O_RDONLY) = 3
read(3, "\177ELF\1\2\1\3\0\0\0\0\0\0\0\0\0\2\0\17\0\0\0\1\0\1\3T\0\0\0004"..., 512) = 512
fstat64(3, {st_mode=0, st_size=4380866642020, ...}) = 0
getcwd("/home2/dave/inequiv", 128) = 20
mmap(0x10000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x10000
mmap(0x11000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0) = 0x11000
...
Carlos what do you think? arch_get_unmapped_area() accepts MAP_FIXED
requests even if it would violate cache aliasing constraints. I don't
understand the purpose of the region at 0x11000.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-05 3:49 ` John David Anglin
@ 2011-01-05 17:37 ` Carlos O'Donell
2011-01-05 18:51 ` John David Anglin
2011-01-09 21:27 ` John David Anglin
0 siblings, 2 replies; 18+ messages in thread
From: Carlos O'Donell @ 2011-01-05 17:37 UTC (permalink / raw)
To: John David Anglin; +Cc: James Bottomley, Parisc List
On Tue, Jan 4, 2011 at 10:49 PM, John David Anglin
<dave@hiauly1.hia.nrc.ca> wrote:
> On Sat, 01 Jan 2011, John David Anglin wrote:
>
>> On Thu, 30 Dec 2010, John David Anglin wrote:
>>
>> > On Thu, 30 Dec 2010, John David Anglin wrote:
>> >
>> > > Attached is an application that triggers similar errors:
>>
>> Here is a simpler testcase:
>>
>> int main ()
>> {
>> =A0 asm ("stw %r0,0(%r0)"); /* Generate null pointer exception */
>> =A0 return 0;
>> }
>>
>> With the above, I get the following INEQUIVALENT ALIASES messages:
>>
>> Jan =A01 10:23:19 gsyprf11 kernel: [135942.140000] INEQUIVALENT ALIA=
SES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
>> Jan =A01 10:23:19 gsyprf11 kernel: [135942.224000] INEQUIVALENT ALIA=
SES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
>
> This is what I see in the tasks maps file in /proc:
>
> 00010000-00011000 r-xp 00000000 08:30 6613687 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/home2/dave/inequiv/xxx1
> 00011000-00012000 rwxp 00000000 08:30 6613687 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/home2/dave/inequiv/xxx1
> 40000000-40005000 rw-p 00000000 00:00 0
> 4002b000-4004b000 r-xp 00000000 08:03 2502157 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/ld-2.11.2.so
> 4004b000-4004f000 rwxp 0001f000 08:03 2502157 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/ld-2.11.2.so
> 4004f000-40050000 rwxp 00000000 00:00 0
> 40138000-40291000 r-xp 00000000 08:03 2502172 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/libc-2.11.2.so
> 40291000-40298000 rwxp 00158000 08:03 2502172 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/libc-2.11.2.so
> 40298000-4029a000 rwxp 00000000 00:00 0
> fe09b000-fe0be000 rwxp 00000000 00:00 0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0[stack]
>
> As can be seen, there are duplicate maps with different protections f=
or xxx1,
> etc. =A0So, it's clear why we have the inequivalent aliases. =A0The m=
ap can
> be accessed by the application (probably just for lines in the cache)=
=2E
> I have seen some discussions that even a read may lead to cache corru=
ption.
>
> These inequivalent maps are coming from glibc:
>
> dave@gsyprf11:~/inequiv$ strace /lib/ld-2.11.2.so ./xxx1
> execve("/lib/ld-2.11.2.so", ["/lib/ld-2.11.2.so", "./xxx1"], [/* 17 v=
ars */]) =3D 0
> brk(0) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0=3D 0x4119a000
> open("./xxx1", O_RDONLY) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D 3
> read(3, "\177ELF\1\2\1\3\0\0\0\0\0\0\0\0\0\2\0\17\0\0\0\1\0\1\3T\0\0\=
0004"..., 512) =3D 512
> fstat64(3, {st_mode=3D0, st_size=3D4380866642020, ...}) =3D 0
> getcwd("/home2/dave/inequiv", 128) =A0 =A0 =A0=3D 20
> mmap(0x10000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DE=
NYWRITE, 3, 0) =3D 0x10000
> mmap(0x11000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_F=
IXED|MAP_DENYWRITE, 3, 0) =3D 0x11000
> ...
>
> Carlos what do you think? =A0arch_get_unmapped_area() accepts MAP_FIX=
ED
> requests even if it would violate cache aliasing constraints. =A0I do=
n't
> understand the purpose of the region at 0x11000.
I'm currently on the South Rim of the Grand Canyon with limited access
to my systems. I'll be back in touch near the end of January and look
into this.
What does the application look like e.g. readelf -a?
The 0x11000 region looks like .data?
Cheers,
Carlos.
--
To unsubscribe from this list: send the line "unsubscribe linux-parisc"=
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-05 17:37 ` Carlos O'Donell
@ 2011-01-05 18:51 ` John David Anglin
2011-01-09 21:27 ` John David Anglin
1 sibling, 0 replies; 18+ messages in thread
From: John David Anglin @ 2011-01-05 18:51 UTC (permalink / raw)
To: Carlos O'Donell; +Cc: John David Anglin, James Bottomley, Parisc List
On Wed, 05 Jan 2011, Carlos O'Donell wrote:
> >> With the above, I get the following INEQUIVALENT ALIASES messages:
> >>
> >> Jan =A01 10:23:19 gsyprf11 kernel: [135942.140000] INEQUIVALENT AL=
IASES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
> >> Jan =A01 10:23:19 gsyprf11 kernel: [135942.224000] INEQUIVALENT AL=
IASES 0x406b1000 and 0x406b0000 in file libc-2.11.2.so
> >
> > This is what I see in the tasks maps file in /proc:
> >
> > 00010000-00011000 r-xp 00000000 08:30 6613687 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/home2/dave/inequiv/xxx1
> > 00011000-00012000 rwxp 00000000 08:30 6613687 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/home2/dave/inequiv/xxx1
> > 40000000-40005000 rw-p 00000000 00:00 0
> > 4002b000-4004b000 r-xp 00000000 08:03 2502157 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/ld-2.11.2.so
> > 4004b000-4004f000 rwxp 0001f000 08:03 2502157 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/ld-2.11.2.so
> > 4004f000-40050000 rwxp 00000000 00:00 0
> > 40138000-40291000 r-xp 00000000 08:03 2502172 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/libc-2.11.2.so
> > 40291000-40298000 rwxp 00158000 08:03 2502172 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/lib/libc-2.11.2.so
> > 40298000-4029a000 rwxp 00000000 00:00 0
> > fe09b000-fe0be000 rwxp 00000000 00:00 0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0[stack]
> >
> > As can be seen, there are duplicate maps with different protections=
for xxx1,
> > etc. =A0So, it's clear why we have the inequivalent aliases. =A0The=
map can
> > be accessed by the application (probably just for lines in the cach=
e).
> > I have seen some discussions that even a read may lead to cache cor=
ruption.
> >
> > These inequivalent maps are coming from glibc:
> >
> > dave@gsyprf11:~/inequiv$ strace /lib/ld-2.11.2.so ./xxx1
> > execve("/lib/ld-2.11.2.so", ["/lib/ld-2.11.2.so", "./xxx1"], [/* 17=
vars */]) =3D 0
> > brk(0) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0=3D 0x4119a000
> > open("./xxx1", O_RDONLY) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=3D 3
> > read(3, "\177ELF\1\2\1\3\0\0\0\0\0\0\0\0\0\2\0\17\0\0\0\1\0\1\3T\0\=
0\0004"..., 512) =3D 512
> > fstat64(3, {st_mode=3D0, st_size=3D4380866642020, ...}) =3D 0
> > getcwd("/home2/dave/inequiv", 128) =A0 =A0 =A0=3D 20
> > mmap(0x10000, 4096, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_=
DENYWRITE, 3, 0) =3D 0x10000
> > mmap(0x11000, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP=
_FIXED|MAP_DENYWRITE, 3, 0) =3D 0x11000
> > ...
> >
> > Carlos what do you think? =A0arch_get_unmapped_area() accepts MAP_F=
IXED
> > requests even if it would violate cache aliasing constraints. =A0I =
don't
> > understand the purpose of the region at 0x11000.
>=20
> I'm currently on the South Rim of the Grand Canyon with limited acces=
s
> to my systems. I'll be back in touch near the end of January and look
> into this.
Nice!
> What does the application look like e.g. readelf -a?
See below.
> The 0x11000 region looks like .data?
Yes. However, the 0x11000 region also maps to the same physical
address as the region at 0x10000. Thus, the inequivalent mapping.
The data starts at 0x11890. It appears the linker has rounded up
the start of the data by 4KB (one page).
Maybe the fix is to round up the start of the data to the next 4GB
boundary in the linker. This would make the alias boundaries
equivalent.
Dave
--=20
J. David Anglin dave.anglin@nrc-cnrc.g=
c.ca
National Research Council of Canada (613) 990-0752 (FAX: 9=
52-6602)
ELF Header:
Magic: 7f 45 4c 46 01 02 01 03 00 00 00 00 00 00 00 00=20
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - Linux
ABI Version: 0
Type: EXEC (Executable file)
Machine: HPPA
Version: 0x1
Entry point address: 0x10354
Start of program headers: 52 (bytes into file)
Start of section headers: 2884 (bytes into file)
Flags: 0x210, PA-RISC 1.1
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 7
Size of section headers: 40 (bytes)
Number of section headers: 31
Section header string table index: 28
Section Headers:
[Nr] Name Type Addr Off Size ES Flg =
Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 =
0 0 0
[ 1] .interp PROGBITS 00010114 000114 00000d 00 A =
0 0 1
[ 2] .note.ABI-tag NOTE 00010124 000124 000020 00 A =
0 0 4
[ 3] .note.gnu.build-i NOTE 00010144 000144 000000 00 A =
0 0 4
[ 4] .hash HASH 00010144 000144 000034 04 A =
5 0 4
[ 5] .dynsym DYNSYM 00010178 000178 000080 10 A =
6 1 4
[ 6] .dynstr STRTAB 000101f8 0001f8 000080 00 A =
0 0 1
[ 7] .gnu.version VERSYM 00010278 000278 000010 02 A =
5 0 2
[ 8] .gnu.version_r VERNEED 00010288 000288 000020 00 A =
6 1 4
[ 9] .rela.dyn RELA 000102a8 0002a8 00000c 0c A =
5 0 4
[10] .rela.plt RELA 000102b4 0002b4 000048 0c A =
5 23 4
[11] .init PROGBITS 000102fc 0002fc 000048 00 AX =
0 0 4
[12] .text PROGBITS 00010344 000344 0003e4 00 AX =
0 0 4
[13] .fini PROGBITS 00010728 000728 000028 00 AX =
0 0 4
[14] .rodata PROGBITS 00010750 000750 000018 00 A =
0 0 4
[15] .PARISC.unwind PROGBITS 00010768 000768 0000e0 04 A =
0 12 4
[16] .eh_frame_hdr PROGBITS 00010848 000848 000014 00 A =
0 0 4
[17] .eh_frame PROGBITS 0001085c 00085c 000034 00 A =
0 0 4
[18] .ctors PROGBITS 00011890 000890 000008 00 WA =
0 0 4
[19] .dtors PROGBITS 00011898 000898 000008 00 WA =
0 0 4
[20] .jcr PROGBITS 000118a0 0008a0 000004 00 WA =
0 0 4
[21] .dynamic DYNAMIC 000118a4 0008a4 0000c8 08 WA =
6 0 4
[22] .data PROGBITS 0001196c 00096c 000008 00 WA =
0 0 4
[23] .plt PROGBITS 00011974 000974 00004c 08 WAX =
0 0 4
[24] .got PROGBITS 000119c0 0009c0 00001c 04 WA =
0 0 4
[25] .bss NOBITS 000119dc 0009dc 000014 00 WA =
0 0 4
[26] .note NOTE 00000000 0009dc 000028 00 =
0 0 1
[27] .comment PROGBITS 00000000 000a04 000038 01 MS =
0 0 1
[28] .shstrtab STRTAB 00000000 000a3c 000106 00 =
0 0 1
[29] .symtab SYMTAB 00000000 00101c 0004c0 10 =
30 56 4
[30] .strtab STRTAB 00000000 0014dc 0002b1 00 =
0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown=
)
O (extra OS processing required) o (OS specific), p (processor specif=
ic)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Ali=
gn
PHDR 0x000034 0x00010034 0x00010034 0x000e0 0x000e0 R E 0x4
INTERP 0x000114 0x00010114 0x00010114 0x0000d 0x0000d R 0x1
[Requesting program interpreter: /lib/ld.so.1]
LOAD 0x000000 0x00010000 0x00010000 0x00890 0x00890 R E 0x1=
000
LOAD 0x000890 0x00011890 0x00011890 0x0014c 0x00160 RWE 0x1=
000
DYNAMIC 0x0008a4 0x000118a4 0x000118a4 0x000c8 0x000c8 RW 0x4
NOTE 0x000124 0x00010124 0x00010124 0x00020 0x00020 R 0x4
GNU_EH_FRAME 0x000848 0x00010848 0x00010848 0x00014 0x00014 R 0x4
Section to Segment mapping:
Segment Sections...
00 =20
01 .interp=20
02 .interp .note.ABI-tag .note.gnu.build-id .hash .dynsym .dynst=
r .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .text .fini .ro=
data .PARISC.unwind .eh_frame_hdr .eh_frame=20
03 .ctors .dtors .jcr .dynamic .data .plt .got .bss=20
04 .dynamic=20
05 .note.ABI-tag=20
06 .eh_frame_hdr=20
Dynamic section at offset 0x8a4 contains 20 entries:
Tag Type Name/Value
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x0000000c (INIT) 0x1030c
0x0000000d (FINI) 0x10728
0x00000004 (HASH) 0x10144
0x00000005 (STRTAB) 0x101f8
0x00000006 (SYMTAB) 0x10178
0x0000000a (STRSZ) 128 (bytes)
0x0000000b (SYMENT) 16 (bytes)
0x00000003 (PLTGOT) 0x1196c
0x00000015 (DEBUG) 0x0
0x00000002 (PLTRELSZ) 72 (bytes)
0x00000014 (PLTREL) RELA
0x00000017 (JMPREL) 0x102b4
0x00000007 (RELA) 0x102a8
0x00000008 (RELASZ) 12 (bytes)
0x00000009 (RELAENT) 12 (bytes)
0x6ffffffe (VERNEED) 0x10288
0x6fffffff (VERNEEDNUM) 1
0x6ffffff0 (VERSYM) 0x10278
0x00000000 (NULL) 0x0
Relocation section '.rela.dyn' at offset 0x2a8 contains 1 entries:
Offset Info Type Sym.Value Sym. Name + Addend
000119d0 00000401 R_PARISC_DIR32 000119c0 _GLOBAL_OFFSET_TABLE_ +=
0
Relocation section '.rela.plt' at offset 0x2b4 contains 6 entries:
Offset Info Type Sym.Value Sym. Name + Addend
00011974 00000181 R_PARISC_IPLT 000105ec __libc_csu_fini + 0
0001197c 00000281 R_PARISC_IPLT 00010724 __gmon_start__ + 0
00011984 00000381 R_PARISC_IPLT 00000000 _Jv_RegisterClasses + 0
0001198c 00000581 R_PARISC_IPLT 000105f0 __libc_csu_init + 0
00011994 00000681 R_PARISC_IPLT 00000000 __libc_start_main + 0
0001199c 00000781 R_PARISC_IPLT 000104a0 main + 0
Unwind section '.PARISC.unwind' at offset 0x768 contains 14 entries:
<_init>: [0x1030c-0x10340]
Entry_GR=3D1 Save_RP Total_frame_size=3D8=20
<__do_global_dtors_aux>: [0x103a8-0x10438]
Entry_GR=3D4 Save_RP Total_frame_size=3D8=20
<call___do_global_dtors_aux>: [0x1043c-0x1044c]
Save_RP Total_frame_size=3D8=20
<frame_dummy>: [0x10450-0x10488]
Save_RP Total_frame_size=3D8=20
<call_frame_dummy>: [0x1048c-0x1049c]
Save_RP Total_frame_size=3D8=20
<main>: [0x104a0-0x104bc]
Entry_GR=3D1 Save_SP Total_frame_size=3D8=20
<main+20>: [0x104c0-0x104d4]
Millicode=20
<__canonicalize_funcptr_for_compare>: [0x104d8-0x105e8]
Entry_GR=3D2 Save_RP Total_frame_size=3D8=20
<__libc_csu_fini>: [0x105ec-0x105ec]
=09
<__libc_csu_init>: [0x105f0-0x10694]
Entry_GR=3D7 Save_RP Total_frame_size=3D16=20
<__do_global_ctors_aux>: [0x10698-0x1070c]
Entry_GR=3D3 Save_RP Total_frame_size=3D16=20
<call___do_global_ctors_aux>: [0x10710-0x10720]
Save_RP Total_frame_size=3D8=20
<__gmon_start__>: [0x10724-0x10724]
=09
<_fini>: [0x10728-0x1074c]
Entry_GR=3D1 Save_RP Total_frame_size=3D8=20
Symbol table '.dynsym' contains 8 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND=20
1: 000105ec 4 FUNC GLOBAL DEFAULT 12 __libc_csu_fini
2: 00010724 4 FUNC WEAK DEFAULT 12 __gmon_start__
3: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
4: 000119c0 0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE=
_
5: 000105f0 168 FUNC GLOBAL DEFAULT 12 __libc_csu_init
6: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GL=
IBC_2.2 (2)
7: 000104a0 32 FUNC GLOBAL DEFAULT 12 main
Symbol table '.symtab' contains 76 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND=20
1: 00010114 0 SECTION LOCAL DEFAULT 1=20
2: 00010124 0 SECTION LOCAL DEFAULT 2=20
3: 00010144 0 SECTION LOCAL DEFAULT 3=20
4: 00010144 0 SECTION LOCAL DEFAULT 4=20
5: 00010178 0 SECTION LOCAL DEFAULT 5=20
6: 000101f8 0 SECTION LOCAL DEFAULT 6=20
7: 00010278 0 SECTION LOCAL DEFAULT 7=20
8: 00010288 0 SECTION LOCAL DEFAULT 8=20
9: 000102a8 0 SECTION LOCAL DEFAULT 9=20
10: 000102b4 0 SECTION LOCAL DEFAULT 10=20
11: 000102fc 0 SECTION LOCAL DEFAULT 11=20
12: 00010344 0 SECTION LOCAL DEFAULT 12=20
13: 00010728 0 SECTION LOCAL DEFAULT 13=20
14: 00010750 0 SECTION LOCAL DEFAULT 14=20
15: 00010768 0 SECTION LOCAL DEFAULT 15=20
16: 00010848 0 SECTION LOCAL DEFAULT 16=20
17: 0001085c 0 SECTION LOCAL DEFAULT 17=20
18: 00011890 0 SECTION LOCAL DEFAULT 18=20
19: 00011898 0 SECTION LOCAL DEFAULT 19=20
20: 000118a0 0 SECTION LOCAL DEFAULT 20=20
21: 000118a4 0 SECTION LOCAL DEFAULT 21=20
22: 0001196c 0 SECTION LOCAL DEFAULT 22=20
23: 00011974 0 SECTION LOCAL DEFAULT 23=20
24: 000119c0 0 SECTION LOCAL DEFAULT 24=20
25: 000119dc 0 SECTION LOCAL DEFAULT 25=20
26: 00000000 0 SECTION LOCAL DEFAULT 26=20
27: 00000000 0 SECTION LOCAL DEFAULT 27=20
28: 00010750 0 NOTYPE LOCAL DEFAULT 14 .Lpmain
29: 0001075c 0 NOTYPE LOCAL DEFAULT 14 .Lp__libc_csu_init
30: 00010758 0 NOTYPE LOCAL DEFAULT 14 .Lp__libc_csu_fini
31: 00011890 0 OBJECT LOCAL DEFAULT 18 __CTOR_LIST__
32: 00011898 0 OBJECT LOCAL DEFAULT 19 __DTOR_LIST__
33: 000118a0 0 OBJECT LOCAL DEFAULT 20 __JCR_LIST__
34: 000103a8 148 FUNC LOCAL DEFAULT 12 __do_global_dtors_au=
x
35: 000119dc 1 OBJECT LOCAL DEFAULT 25 completed.5625
36: 000119e0 4 OBJECT LOCAL DEFAULT 25 dtor_idx.5627
37: 0001043c 20 FUNC LOCAL DEFAULT 12 call___do_global_dto=
rs_au
38: 00010450 60 FUNC LOCAL DEFAULT 12 frame_dummy
39: 0001048c 20 FUNC LOCAL DEFAULT 12 call_frame_dummy
40: 00011894 0 OBJECT LOCAL DEFAULT 18 __CTOR_END__
41: 0001088c 0 OBJECT LOCAL DEFAULT 17 __FRAME_END__
42: 000118a0 0 OBJECT LOCAL DEFAULT 20 __JCR_END__
43: 00010698 120 FUNC LOCAL DEFAULT 12 __do_global_ctors_au=
x
44: 00010710 20 FUNC LOCAL DEFAULT 12 call___do_global_cto=
rs_au
45: 00010340 0 NOTYPE LOCAL DEFAULT 11 _end_init
46: 0001074c 0 NOTYPE LOCAL DEFAULT 13 _end_fini
47: ffffffec 0 NOTYPE LOCAL DEFAULT ABS r31_slot
48: fffffff0 0 NOTYPE LOCAL DEFAULT ABS sr0_slot
49: ffffffec 0 NOTYPE LOCAL DEFAULT ABS mrp_slot
50: 000119e4 4 OBJECT LOCAL DEFAULT 25 fixup.1200
51: 000119e8 8 OBJECT LOCAL DEFAULT 25 fixup_plabel.1199
52: 00011890 0 NOTYPE LOCAL DEFAULT 18 __init_array_end
53: 000104c0 24 PARISC_MILLI LOCAL DEFAULT 12 $$dyncall
54: 00011890 0 NOTYPE LOCAL DEFAULT 18 __init_array_start
55: 000118a4 0 OBJECT LOCAL DEFAULT 21 _DYNAMIC
56: 0001196c 0 NOTYPE WEAK DEFAULT 22 data_start
57: 000105ec 4 FUNC GLOBAL DEFAULT 12 __libc_csu_fini
58: 00010354 80 FUNC GLOBAL DEFAULT 12 _start
59: 00010724 4 FUNC WEAK DEFAULT 12 __gmon_start__
60: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
61: 00010728 0 FUNC GLOBAL DEFAULT 13 _fini
62: 000119c0 0 OBJECT GLOBAL DEFAULT ABS _GLOBAL_OFFSET_TABLE=
_
63: 00010760 4 OBJECT GLOBAL DEFAULT 14 _IO_stdin_used
64: 0001196c 0 NOTYPE GLOBAL DEFAULT 22 __data_start
65: 0001196c 0 OBJECT GLOBAL DEFAULT 22 $global$
66: 00011970 0 OBJECT GLOBAL HIDDEN 22 __dso_handle
67: 0001189c 0 OBJECT GLOBAL HIDDEN 19 __DTOR_END__
68: 000105f0 168 FUNC GLOBAL DEFAULT 12 __libc_csu_init
69: 000119dc 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
70: 000104d8 276 FUNC GLOBAL HIDDEN 12 __canonicalize_funcp=
tr_fo
71: 00000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@G=
LIBC_
72: 000119f0 0 NOTYPE GLOBAL DEFAULT ABS _end
73: 000119dc 0 NOTYPE GLOBAL DEFAULT ABS _edata
74: 000104a0 32 FUNC GLOBAL DEFAULT 12 main
75: 0001030c 0 FUNC GLOBAL DEFAULT 11 _init
Histogram for bucket list length (total of 3 buckets):
Length Number % of total Coverage
0 0 ( 0.0%)
1 1 ( 33.3%) 14.3%
2 0 ( 0.0%) 14.3%
3 2 ( 66.7%) 100.0%
Version symbols section '.gnu.version' contains 8 entries:
Addr: 0000000000010278 Offset: 0x000278 Link: 5 (.dynsym)
000: 0 (*local*) 1 (*global*) 1 (*global*) 0 (*loca=
l*) =20
004: 1 (*global*) 1 (*global*) 2 (GLIBC_2.2) 1 (*glob=
al*) =20
Version needs section '.gnu.version_r' contains 1 entries:
Addr: 0x0000000000010288 Offset: 0x000288 Link: 6 (.dynstr)
000000: Version: 1 File: libc.so.6 Cnt: 1
0x0010: Name: GLIBC_2.2 Flags: none Version: 2
Notes at offset 0x00000124 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
Notes at offset 0x000009dc with length 0x00000028:
Owner Data size Description
01.01 0x00000000 NT_VERSION (version)
01.01 0x00000000 NT_VERSION (version)
--
To unsubscribe from this list: send the line "unsubscribe linux-parisc"=
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-05 17:37 ` Carlos O'Donell
2011-01-05 18:51 ` John David Anglin
@ 2011-01-09 21:27 ` John David Anglin
1 sibling, 0 replies; 18+ messages in thread
From: John David Anglin @ 2011-01-09 21:27 UTC (permalink / raw)
To: Carlos O'Donell; +Cc: John David Anglin, James Bottomley, Parisc List
I filed a binutils bug report for this problem:
http://sourceware.org/bugzilla/show_bug.cgi?id=12376
However, I now think the problem can't be fixed reliably by a change
to binutils. See comments #2 and #3 in the bug report.
James, would using different file descriptors for the mmap'd PT_LOAD
segments in an executable result in different pages being used for
"code" and "data" in the overlap region of the executable file, and
thereby avoid the inequivalent aliases?
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2010-12-22 16:22 parisc: flush pages through tmpalias space James Bottomley
` (3 preceding siblings ...)
2010-12-29 4:23 ` John David Anglin
@ 2011-01-09 21:52 ` John David Anglin
2011-01-10 20:44 ` James Bottomley
4 siblings, 1 reply; 18+ messages in thread
From: John David Anglin @ 2011-01-09 21:52 UTC (permalink / raw)
To: James Bottomley; +Cc: Parisc List
[-- Attachment #1: Type: text/plain, Size: 1912 bytes --]
On Wed, 22 Dec 2010, James Bottomley wrote:
> The kernel has an 8M tmpailas space (originally designed for copying
> and clearing pages but now only used for clearing). The idea is
> to place zeros into the cache above a physical page rather than into
> the physical page and flush the cache, because often the zeros end up
> being replaced quickly anyway.
>
> We can also use the tmpalias space for flushing a page. The difference
> here is that we have to do tmpalias processing in the non access data and
> instruction traps. The principle is the same: as long as we know the physical
> address and have a virtual address congruent to the real one, the flush will
> be effective.
>
> In order to use the tmpalias space, the icache miss path has to be enhanced to
> check for the alias region to make the fic instruction effective.
Since I began testing this change, I have started seeing problems with the
console input on gsyprf11 and my rp3440. If I HUP getty, the console works
for awhile and then stops working again. Suspect the "INEQIVALENT ALIAS"
messages somehow kill the console. I get a lot of these doing make check
for GCC from the tests that intentionally generate a segv to test exception
support.
I have also had at least one console related HPMC. Analysis is attached.
I don't fully understand the actual cause of the HPMC (buffer overrun?).
The kernel was built with GCC 4.5.3. The faulting instruction appears
to have the base and index interchanged, although this shouldn't affect
linux. I thought this issue was fixed as a fair bit of work on this was
done in the middle-end.
I have to say that gsyprf11 running a SMP kernel built with 4.5.3 is
more stable with your change than it has been for a long time.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
[-- Attachment #2: hpmc-jeb.txt --]
[-- Type: text/plain, Size: 5804 bytes --]
Timestamp = Mon Jan 3 08:35:03 GMT 2011 (20:11:01:03:08:35:03)
HPMC Chassis Codes
Chassis Code Extension
------------ ---------
0xe800035c00e00000 0x000000004033fde8
0x57000f7300e00000 0x8040004000000000
0x5600100b00e00000 0x0000000000000194
0x5600106400e00000 0xfffffff0f0435110
General Registers 0 - 31
00-03 0000000000000000 0000000040530a90 00000000403439ec 0000000040530b40
04-07 0000000040668a80 000000004061bd60 0000000000000000 0000000040530a60
08-11 0000000000000001 0000000040534080 0000000040530988 0000000000200200
12-15 0000000040677280 0000000040534100 00000000405fe0e0 00000000405fe4e0
16-19 00000000405fe8e0 00000000405fece0 0000000000000001 0000000040530988
20-23 0000000000000000 ffffffffffffffff 00000000405d7110 8000000000000000
24-27 0000000102208072 0000000000000001 000000004061bd60 0000000040668a80
28-31 0000000004082000 0000000040530b10 0000000040530b80 0000000000000000
Control Registers 0 - 31
00-03 0000000000000000 0000000000000000 0000000000000000 0000000000000000
04-07 0000000000000000 0000000000000000 0000000000000000 0000000000000000
08-11 0000000000000b12 0000000000000000 00000000000000c0 000000000000003f
12-15 0000000000000000 0000000000000000 0000000000103000 ffe0000000000000
16-19 00006827228e3750 0000000000000000 000000004033fde8 000000000f3c001c
20-23 00000000a607ffd0 0000000014082001 000000ff0804ff0f 0000000000000000
24-27 00000000005bd000 000000003ce22000 fffdffffffdfffef 0000000040000b80
28-31 0000000040000b80 ffffffffffffff7f 0000000040530000 886904b488140042
Space Registers 0 - 7
00-03 00000000002c4800 0000000000000000 0000000000000000 00000000002c4800
04-07 0000000000000000 0000000000000000 0000000000000000 0000000000000000
IIA Space (back entry) = 0x0000000000000000
IIA Offset (back entry) = 0x000000004033fdec
Check Type = 0x20000000
Cpu State = 0x9e000000
Cache Check = 0x00000000
TLB Check = 0x00000000
Bus Check = 0x00000000
Assists Check = 0x002c4800
Assist State = 0x00000000
Path Info = 0x00000000
System Responder Address = 0x0000000000000000
System Requestor Address = 0x0000000000000000
Floating Point Registers 0 - 31
00-03 0000000000000000 0000000000000000 0000000000000000 0000000000000000
04-07 000f000000000000 0000000000000001 00000000406bd000 0000000040688000
08-11 00000000406bd000 0000000040668a80 0000000000000000 0000000040668a80
12-15 0000000000000000 0000000000000000 0000000000000000 0000000000000000
16-19 0000000000000000 0000000000000000 0000000000000000 0000000000000000
20-23 0000000000000000 0000000000000000 0000000000000000 000000000000000f
24-27 0000000000000000 0000000000000000 0000000000000000 ffffffffc0000000
28-31 000000000000002f 00000000405651cc 0000000000000001 0000000000000001
PIM Revision = 0x0000000000000001
CPU ID = 0x0000000000000014
CPU Revision = 0x0000000000000031
Cpu Serial Number = 0x46100b89e43f0503
Check Summary = 0x8040004000000000
SAL Timestamp = 0x000000004d218a37
System Firmware Rev. = 0x00000ba20000121a
PDC Relocation Address = 0xfffffff0f0c00000
Available Memory = 0x000000027fe00000
CPU Diagnose Register 2 = 0x3112022000002008
MIB_STAT = 0x0040000000200000
MIB_LOG1 = 0x0000000000555500
MIB_LOG2 = 0x0000800000000000
MIB_ECC_DATA = 0x808800007fffbfd8
ICache Info = 0x0000000000000000
DCache Info = 0x0000000000000000
Sharedcache Info1 = 0x0000000000000000
Sharedcache Info2 = 0x00000000000000c0
MIB_RSLOG1 = 0x0000000000000004
MIB_RSLOG2 = 0x0000010000000000
MIB_RQLOG = 0x02921405fffe1510
MIB_REQLOGa = 0x8000000000000200
MIB_REQLOGb = 0x01000aa400000000
Reserved = 0x0000000000000000
Cache Repair Detail = 0x0000000000000000
PIM Detail Text:
000000004033fdc8 <mem_serial_in>:
4033fdc8: 08 03 02 41 copy r3,r1
4033fdcc: 08 1e 02 43 copy sp,r3
4033fdd0: 73 c1 00 88 std,ma r1,40(sp)
4033fdd4: 43 5f 00 92 ldb 49(r26),r31
4033fdd8: 53 5c 00 20 ldd 10(r26),ret0
4033fddc: 01 7f 18 c0 mtsarcm r31
4033fde0: d7 39 00 00 depw,z r25,sar,32,r25
4033fde4: db 39 0f e0 extrd,s r25,63,32,r25
==> 4033fde8: 0f 3c 00 1c ldb ret0(r25),ret0
4033fdec: 34 7e 00 80 ldo 40(r3),sp
4033fdf0: e8 40 d0 00 bve (rp)
4033fdf4: 53 c3 3f 8d ldd,mb -40(sp),r3
r25 = 0000000000000001
r31 = 0000000000000000
ret0= 0000000004082000
rp = 00000000403439ec
drivers/serial/8250.c:
static unsigned int mem_serial_in(struct uart_port *p, int offset)
{
offset = map_8250_in_reg(p, offset) << p->regshift;
return readb(p->membase + offset);
}
It appears the base and offset are interchanged in ldb.
0000000040343818 <serial8250_backup_timeout>:
40343818: 08 03 02 41 copy r3,r1
4034381c: 0f c2 12 c1 std rp,-10(sp)
...
403439d0: 08 1b 02 44 copy dp,r4
403439d4: 34 19 00 02 ldi 1,r25
403439d8: 53 5c 00 30 ldd 18(r26),ret0
403439dc: 37 dd 3f a1 ldo -30(sp),ret1
403439e0: 53 82 00 20 ldd 10(ret0),rp
403439e4: e8 40 f0 00 bve,l (rp),rp
403439e8: 53 9b 00 30 ldd 18(ret0),dp
==> 403439ec: 08 04 02 5b copy r4,dp
403439f0: 08 1c 02 46 copy ret0,r6
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-09 21:52 ` John David Anglin
@ 2011-01-10 20:44 ` James Bottomley
2011-01-10 22:18 ` John David Anglin
0 siblings, 1 reply; 18+ messages in thread
From: James Bottomley @ 2011-01-10 20:44 UTC (permalink / raw)
To: John David Anglin; +Cc: Parisc List
On Sun, 2011-01-09 at 16:52 -0500, John David Anglin wrote:
> On Wed, 22 Dec 2010, James Bottomley wrote:
> > The kernel has an 8M tmpailas space (originally designed for copying
> > and clearing pages but now only used for clearing). The idea is
> > to place zeros into the cache above a physical page rather than into
> > the physical page and flush the cache, because often the zeros end up
> > being replaced quickly anyway.
> >
> > We can also use the tmpalias space for flushing a page. The difference
> > here is that we have to do tmpalias processing in the non access data and
> > instruction traps. The principle is the same: as long as we know the physical
> > address and have a virtual address congruent to the real one, the flush will
> > be effective.
> >
> > In order to use the tmpalias space, the icache miss path has to be enhanced to
> > check for the alias region to make the fic instruction effective.
>
> Since I began testing this change, I have started seeing problems with the
> console input on gsyprf11 and my rp3440. If I HUP getty, the console works
> for awhile and then stops working again. Suspect the "INEQIVALENT ALIAS"
> messages somehow kill the console. I get a lot of these doing make check
> for GCC from the tests that intentionally generate a segv to test exception
> support.
In theory, the patch is actually stricter than our original flushing
support because it eliminates the ineffective flushes and detects
inequvalent aliases (and flushes all inequivalent addresses).
> I have also had at least one console related HPMC. Analysis is attached.
> I don't fully understand the actual cause of the HPMC (buffer overrun?).
> The kernel was built with GCC 4.5.3. The faulting instruction appears
> to have the base and index interchanged, although this shouldn't affect
> linux. I thought this issue was fixed as a fair bit of work on this was
> done in the middle-end.
>
> I have to say that gsyprf11 running a SMP kernel built with 4.5.3 is
> more stable with your change than it has been for a long time.
So I'm not sure what to make of this ... any memory fault shouldn't
result in a HPMC ... I probably need to decode the HPMC to see what its
saying ... I'll get around to that on the Weekend, hopefully.
James
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: parisc: flush pages through tmpalias space
2011-01-10 20:44 ` James Bottomley
@ 2011-01-10 22:18 ` John David Anglin
0 siblings, 0 replies; 18+ messages in thread
From: John David Anglin @ 2011-01-10 22:18 UTC (permalink / raw)
To: James Bottomley; +Cc: John David Anglin, Parisc List
On Mon, 10 Jan 2011, James Bottomley wrote:
> > Since I began testing this change, I have started seeing problems with the
> > console input on gsyprf11 and my rp3440. If I HUP getty, the console works
> > for awhile and then stops working again. Suspect the "INEQIVALENT ALIAS"
> > messages somehow kill the console. I get a lot of these doing make check
> > for GCC from the tests that intentionally generate a segv to test exception
> > support.
>
> In theory, the patch is actually stricter than our original flushing
> support because it eliminates the ineffective flushes and detects
> inequvalent aliases (and flushes all inequivalent addresses).
It might be that I only became aware of the console issue while
testing your patch. Probably, I should retest without the patch.
It might just have to do with console messages and not cache flushing.
The stricter flushing would definitely appear to be an improvement
and indeed the messages have been useful in locating inequivalent
aliases.
As I have found, we have inequivalent aliases for almost every executable
when the boundary between text and data isn't exactly on a page boundary.
I would think this would be an issue for all machines with a VIPT
architecture, so I'm surprised that it hasn't come up before.
I'm a bit worried about the ordering of the flushes on processors that
don't support inequivalent aliases. It would appear we generally flush
the text page first with the current code.
I can still cause random segvs on rp3440 if I use make -j4 or higher
building GCC ;(
> > I have also had at least one console related HPMC. Analysis is attached.
> > I don't fully understand the actual cause of the HPMC (buffer overrun?).
> > The kernel was built with GCC 4.5.3. The faulting instruction appears
> > to have the base and index interchanged, although this shouldn't affect
> > linux. I thought this issue was fixed as a fair bit of work on this was
> > done in the middle-end.
> >
> > I have to say that gsyprf11 running a SMP kernel built with 4.5.3 is
> > more stable with your change than it has been for a long time.
>
> So I'm not sure what to make of this ... any memory fault shouldn't
> result in a HPMC ... I probably need to decode the HPMC to see what its
> saying ... I'll get around to that on the Weekend, hopefully.
That would be great. I don't have the documentation needed to decode
HPMCs.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2011-01-10 22:18 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-22 16:22 parisc: flush pages through tmpalias space James Bottomley
2010-12-23 0:07 ` Carlos O'Donell
2010-12-23 3:04 ` John David Anglin
2010-12-25 21:52 ` Helge Deller
2010-12-29 14:49 ` James Bottomley
2010-12-29 4:23 ` John David Anglin
2010-12-29 14:51 ` James Bottomley
2010-12-30 15:56 ` John David Anglin
2010-12-30 16:09 ` John David Anglin
2011-01-01 18:31 ` John David Anglin
2011-01-01 19:00 ` John David Anglin
2011-01-05 3:49 ` John David Anglin
2011-01-05 17:37 ` Carlos O'Donell
2011-01-05 18:51 ` John David Anglin
2011-01-09 21:27 ` John David Anglin
2011-01-09 21:52 ` John David Anglin
2011-01-10 20:44 ` James Bottomley
2011-01-10 22:18 ` John David Anglin
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.