All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joakim Tjernlund <joakim.tjernlund@transmode.se>
To: Scott Wood <scottwood@freescale.com>
Cc: Rex Feany <RFeany@mrv.com>,
	"linuxppc-dev@ozlabs.org" <linuxppc-dev@ozlabs.org>
Subject: Re: [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite
Date: Sat, 3 Oct 2009 10:05:46 +0200	[thread overview]
Message-ID: <OF4175DD8E.796930EB-ONC1257644.002A7135-C1257644.002C7929@transmode.se> (raw)
In-Reply-To: <20091002214949.GA20514@b07421-ec1.am.freescale.net>

Scott Wood <scottwood@freescale.com> wrote on 02/10/2009 23:49:49:
>
> On Thu, Oct 01, 2009 at 08:35:59AM +1000, Benjamin Herrenschmidt wrote:
> > >From what I can see, the TLB miss code will check _PAGE_PRESENT, and
> > when not set, it will -still- insert something into the TLB (unlike
> > all other CPU types that go straight to data access faults from there).
> >
> > So we end up populating with those unpopulated entries that will then
> > cause us to take a DSI (or ISI) instead of a TLB miss the next time
> > around ... and so we need to remove them once we do that, no ? IE. Once
> > we have actually put a valid PTE in.
> >
> > At least that's my understanding and why I believe we should always have
> > tlbil_va() in set_pte() and ptep_set_access_flags(), which boils down
> > in putting it into the 2 "filter" functions in the new code.
> >
> > Well.. actually, the ptep_set_access_flags() will already do a
> > flush_tlb_page_nohash() when the PTE is changed. So I suppose all we
> > really need here would be in set_pte_filter(), to do the same if we are
> > writing a PTE that has _PAGE_PRESENT, at least on 8xx.
> >
> > But just unconditionally doing a tlbil_va() in both the filter functions
> > shouldn't harm and also fix the problem, though Rex seems to indicate
> > that is not the case.
>
> Adding a tlbil_va to do_page_fault makes the problem go away for me (on
> top of your "merge" branch) -- none of the other changes in this thread
> do (assuming I didn't miss any).  FWIW, when it gets stuck on a fault,
> DSISR is 0xc0000000, and handle_mm_fault returns zero.

OK, that is a no translation error for a load (assuming trap is 0x400)
Do you know what insn this is? I am adding a patch last in this mail
for catching dcbX insn in do_page_fault()

You need the patch I posted yesterday too:

>From c5f1a70561730b8a443f7081fbd9c5b023147043 Mon Sep 17 00:00:00 2001
From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
Date: Fri, 2 Oct 2009 14:59:21 +0200
Subject: [PATCH] powerpc, 8xx: DTLB Error must check for more errors.

DataTLBError currently does:
 if ((err & 0x02000000) == 0)
    DSI();
This won't handle a store with no valid translation.
Change this to
 if ((err & 0x48000000) != 0)
    DSI();
that is, branch to DSI if either !permission or
!translation.
---
 arch/powerpc/kernel/head_8xx.S |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 52ff8c5..118bb05 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -472,8 +472,8 @@ DataTLBError:
 	/* First, make sure this was a store operation.
 	*/
 	mfspr	r10, SPRN_DSISR
-	andis.	r11, r10, 0x0200	/* If set, indicates store op */
-	beq	2f
+	andis.	r11, r10, 0x4800 /* no translation, no permission. */
+	bne	2f	/* branch if either is set */

 	/* The EA of a data TLB miss is automatically stored in the MD_EPN
 	 * register.  The EA of a data TLB error is automatically stored in
--
1.6.4.4


Cannot shake the feeling that it this snip of code that causes it
	lwz	r11, 0(r10)	/* Get the level 1 entry */
	rlwinm.	r10, r11,0,0,19	/* Extract page descriptor page address */
	beq	2f		/* If zero, don't try to find a pte */
Perhaps we can do something better? I still feel that we need to
force a TLB Error as the TLBMiss does not set DSISR so we have no way of
knowing if it is an load or store.

 Jocke

diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 7699394..c33c6de 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -139,6 +139,88 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
 #else
 	is_write = error_code & ESR_DST;
 #endif /* CONFIG_4xx || CONFIG_BOOKE */
+#if 1 /* defined(CONFIG_8xx)*/
+#define DEBUG_DCBX
+/*
+ Work around DTLB Miss/Error, as these do not update
+ DAR for dcbf, dcbi, dcbst, dcbz and icbi instructions
+ This relies on every exception tagging DAR with 0xf0
+ before returning (rfi)
+ DAR is passed as 'address' to this function.
+ */
+	{
+		unsigned long ra, rb, dar, insn;
+#ifdef DEBUG_DCBX
+		const char *istr = NULL;
+
+		insn = *((unsigned long *)regs->nip);
+		if (((insn >> (31-5)) & 0x3f) == 31) {
+			if (((insn >> 1) & 0x3ff) == 1014) /* dcbz ? 0x3f6 */
+				istr = "dcbz";
+			if (((insn >> 1) & 0x3ff) == 86) /* dcbf ? 0x56 */
+				istr = "dcbf";
+			if (((insn >> 1) & 0x3ff) == 470) /* dcbi ? 0x1d6 */
+				istr = "dcbi";
+			if (((insn >> 1) & 0x3ff) == 54) /* dcbst ? 0x36 */
+				istr = "dcbst";
+			if (((insn >> 1) & 0x3ff) == 982) /* icbi ? 0x3d6 */
+				istr = "icbi";
+			if (istr) {
+				ra = (insn >> (31-15)) & 0x1f; /* Reg RA */
+				rb = (insn >> (31-20)) & 0x1f; /* Reg RB */
+				dar = regs->gpr[rb];
+				if (ra)
+					dar += regs->gpr[ra];
+				if (dar != address && address != 0x00f0 && trap == 0x300)
+					printk(KERN_CRIT "%s: address:%lx, dar:%lx!\n", istr, address, dar);
+				if (!strcmp(istr, "dcbst") && is_write) {
+					printk(KERN_CRIT "dcbst R%ld,R%ld = %lx as a store, fixing!\n",
+					       ra, rb, dar);
+					is_write = 0;
+				}
+
+				if (trap == 0x300 && address != dar) {
+					__asm__ ("mtdar %0" : : "r" (dar));
+					return 0;
+				}
+			}
+		}
+#endif
+		if (address == 0x00f0 && trap == 0x300) {
+			pte_t *ptep;
+
+			/* This is from a dcbX or icbi insn gone bad, these
+			 * insn do not set DAR so we have to do it here instead */
+			insn = *((unsigned long *)regs->nip);
+
+			ra = (insn >> (31-15)) & 0x1f; /* Reg RA */
+			rb = (insn >> (31-20)) & 0x1f; /* Reg RB */
+			dar = regs->gpr[rb];
+			if (ra)
+				dar += regs->gpr[ra];
+			/* Set DAR to correct address for the DTLB Miss/Error handler
+			 * to redo the TLB exception. This time with correct address */
+			__asm__ ("mtdar %0" : : "r" (dar));
+#ifdef DEBUG_DCBX
+			printk(KERN_CRIT "trap:%x address:%lx, dar:%lx,err:%lx %s\n",
+			       trap, address, dar, error_code, istr);
+#endif
+			address = dar;
+#if 1
+			if (is_write && get_pteptr(mm, dar, &ptep, NULL)) {
+				pte_t my_pte = *ptep;
+
+				if (pte_present(my_pte) && pte_write(my_pte)) {
+					pte_val(my_pte) |= _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE;
+					set_pte_at(mm, dar, ptep, my_pte);
+				}
+			}
+#else
+			return 0;
+#endif
+		}
+	}
+#endif

 	if (notify_page_fault(regs))
 		return 0;

  parent reply	other threads:[~2009-10-03  8:09 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-24  0:45 [PATCH] powerpc/8xx: fix regression introduced by cache coherency rewrite Rex Feany
2009-09-24  6:44 ` Benjamin Herrenschmidt
2009-09-24 23:33   ` Rex Feany
2009-09-24 23:52     ` Benjamin Herrenschmidt
2009-09-25  1:35       ` Rex Feany
2009-09-25  1:51         ` Benjamin Herrenschmidt
2009-09-25  3:03           ` Benjamin Herrenschmidt
2009-09-25  8:31             ` Joakim Tjernlund
2009-09-25  9:47               ` Benjamin Herrenschmidt
2009-09-25 10:21                 ` Joakim Tjernlund
2009-09-25 21:18             ` Rex Feany
2009-09-27 13:22               ` Joakim Tjernlund
2009-09-28  3:21                 ` Benjamin Herrenschmidt
2009-09-28  7:22                   ` Joakim Tjernlund
2009-09-28  7:34                     ` Benjamin Herrenschmidt
2009-09-28  7:39                       ` Joakim Tjernlund
2009-09-28 10:02                     ` Joakim Tjernlund
2009-09-29  1:21           ` Rex Feany
2009-09-29  6:26             ` Joakim Tjernlund
2009-09-29  7:07               ` Benjamin Herrenschmidt
2009-09-29  8:13                 ` Joakim Tjernlund
2009-09-29  8:16                   ` Benjamin Herrenschmidt
2009-09-29  8:24                     ` Joakim Tjernlund
2009-09-29 11:56                     ` Joakim Tjernlund
2009-09-29 21:03                       ` Rex Feany
2009-09-30  7:59                         ` Joakim Tjernlund
2009-09-30  8:19                           ` Joakim Tjernlund
2009-09-30  9:00                             ` Rex Feany
2009-09-30  9:58                               ` Joakim Tjernlund
2009-09-30 11:18                               ` Joakim Tjernlund
2009-09-30 17:23                                 ` Joakim Tjernlund
2009-09-30 22:35                                   ` Benjamin Herrenschmidt
2009-10-01  7:05                                     ` Joakim Tjernlund
2009-10-02 13:06                                     ` Joakim Tjernlund
2009-10-02 18:10                                       ` Joakim Tjernlund
2009-10-02 21:49                                     ` Scott Wood
2009-10-02 22:04                                       ` Benjamin Herrenschmidt
2009-10-05 19:28                                         ` Scott Wood
2009-10-05 20:29                                           ` Benjamin Herrenschmidt
2009-10-05 21:04                                             ` Scott Wood
2009-10-03  8:05                                       ` Joakim Tjernlund [this message]
2009-10-03  8:31                                         ` Benjamin Herrenschmidt
2009-10-03  9:24                                           ` Joakim Tjernlund
2009-10-03 10:57                                             ` Benjamin Herrenschmidt
2009-10-03 11:47                                               ` Joakim Tjernlund
2009-10-04  8:35                                               ` Joakim Tjernlund
2009-10-04 20:26                                                 ` Benjamin Herrenschmidt
2009-10-04 20:38                                                   ` Joakim Tjernlund
2009-10-05 18:24                                         ` Scott Wood
2009-10-05 18:50                                           ` Joakim Tjernlund
2009-10-04 20:10                                       ` Joakim Tjernlund
2009-10-04 20:28                                         ` Benjamin Herrenschmidt
2009-10-04 20:45                                           ` Joakim Tjernlund
2009-10-05  7:28                                           ` Joakim Tjernlund
2009-10-05 19:16                                           ` Joakim Tjernlund
2009-10-05 20:28                                             ` Benjamin Herrenschmidt
2009-09-29  7:07             ` Benjamin Herrenschmidt
2009-09-29 21:09               ` Rex Feany

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=OF4175DD8E.796930EB-ONC1257644.002A7135-C1257644.002C7929@transmode.se \
    --to=joakim.tjernlund@transmode.se \
    --cc=RFeany@mrv.com \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=scottwood@freescale.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.