All of lore.kernel.org
 help / color / mirror / Atom feed
* 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.