From: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
To: linuxppc-dev <linuxppc-dev@ozlabs.org>,
Scott Wood <scottwood@freescale.com>, Willy Tarreau <w@1wt.eu>,
Dan Malek <ppc6dev@digitaldans.com>
Subject: [PATCH 06/14] 8xx: Fixup DAR from buggy dcbX instructions.
Date: Mon, 10 Oct 2011 13:30:12 +0200 [thread overview]
Message-ID: <1318246220-4839-7-git-send-email-Joakim.Tjernlund@transmode.se> (raw)
In-Reply-To: <1318246220-4839-1-git-send-email-Joakim.Tjernlund@transmode.se>
This is an assembler version to fixup DAR not being set
by dcbX, icbi instructions. There are two versions, one
uses selfmodifing code, the other uses a
jump table but is much bigger(default).
Signed-off-by: Joakim Tjernlund <Joakim.Tjernlund@transmode.se>
---
arch/ppc/kernel/head_8xx.S | 149 +++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 146 insertions(+), 3 deletions(-)
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index c9770b6..0891b96 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -511,8 +511,17 @@ DataTLBError:
stw r20, 0(r0)
stw r21, 4(r0)
- mfspr r20, DSISR
- andis. r21, r20, 0x4800 /* !translation or protection */
+ mfspr r20, DAR
+ cmpwi cr0, r20, 0x00f0
+ beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
+DARFixed:
+ /* As the DAR fixup may clear store we may have all 3 states zero.
+ * Make sure only 0x0200(store) falls down into DIRTY handling
+ */
+ mfspr r21, DSISR
+ andis. r21, r21, 0x4a00 /* !translation, protection or store */
+ srwi r21, r21, 16
+ cmpwi cr0, r21, 0x0200 /* just store ? */
bne- 2f
/* Only Change bit left now, do it here as it is faster
* than trapping to the C fault handler.
@@ -534,7 +543,7 @@ DataTLBError:
* are initialized in mapin_ram(). This will avoid the problem,
* assuming we only use the dcbi instruction on kernel addresses.
*/
- mfspr r20, DAR
+ /* DAR is in r20 already */
rlwinm r21, r20, 0, 0, 19
ori r21, r21, MD_EVALID
mfspr r20, M_CASID
@@ -618,6 +627,140 @@ DataTLBError:
STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
. = 0x2000
+/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
+ * by decoding the registers used by the dcbx instruction and adding them.
+ * DAR is set to the calculated address and r10 also holds the EA on exit.
+ */
+ /* define if you don't want to use self modifying code */
+#define NO_SELF_MODIFYING_CODE
+FixupDAR:/* Entry point for dcbx workaround. */
+ /* fetch instruction from memory. */
+ mfspr r20, SRR0
+ andis. r21, r20, 0x8000 /* Address >= 0x80000000 */
+ DO_8xx_CPU6(0x3780, r3)
+ mtspr MD_EPN, r20
+ mfspr r21, M_TWB /* Get level 1 table entry address */
+ beq- 3f /* Branch if user space */
+ lis r21, (swapper_pg_dir-PAGE_OFFSET)@h
+ ori r21, r21, (swapper_pg_dir-PAGE_OFFSET)@l
+ rlwimi r21, r20, 32-20, 0xffc /* r21 = r21&~0xffc|(r20>>20)&0xffc */
+3: lwz r21, 0(r21) /* Get the level 1 entry */
+ tophys (r21, r21)
+ DO_8xx_CPU6(0x3b80, r3)
+ mtspr MD_TWC, r21 /* Load pte table base address */
+ mfspr r21, MD_TWC /* ....and get the pte address */
+ lwz r21, 0(r21) /* Get the pte */
+ /* concat physical page address(r21) and page offset(r20) */
+ rlwimi r21, r20, 0, 20, 31
+ lwz r21,0(r21)
+/* Check if it really is a dcbx instruction. */
+/* dcbt and dcbtst does not generate DTLB Misses/Errors,
+ * no need to include them here */
+ srwi r20, r21, 26 /* check if major OP code is 31 */
+ cmpwi cr0, r20, 31
+ bne- 141f
+ rlwinm r20, r21, 0, 21, 30
+ cmpwi cr0, r20, 2028 /* Is dcbz? */
+ beq+ 142f
+ cmpwi cr0, r20, 940 /* Is dcbi? */
+ beq+ 142f
+ cmpwi cr0, r20, 108 /* Is dcbst? */
+ beq+ 144f /* Fix up store bit! */
+ cmpwi cr0, r20, 172 /* Is dcbf? */
+ beq+ 142f
+ cmpwi cr0, r20, 1964 /* Is icbi? */
+ beq+ 142f
+141: mfspr r20, DAR /* r20 must hold DAR at exit */
+ b DARFixed /* Nope, go back to normal TLB processing */
+
+144: mfspr r20, DSISR
+ rlwinm r20, r20,0,7,5 /* Clear store bit for buggy dcbst insn */
+ mtspr DSISR, r20
+142: /* continue, it was a dcbx, dcbi instruction. */
+#ifdef CONFIG_8xx_CPU6
+ lwz r3, 8(r0) /* restore r3 from memory */
+#endif
+#ifndef NO_SELF_MODIFYING_CODE
+ andis. r20,r21,0x1f /* test if reg RA is r0 */
+ li r20,modified_instr@l
+ dcbtst r0,r20 /* touch for store */
+ rlwinm r21,r21,0,0,20 /* Zero lower 10 bits */
+ oris r21,r21,640 /* Transform instr. to a "add r20,RA,RB" */
+ ori r21,r21,532
+ stw r21,0(r20) /* store add/and instruction */
+ dcbf 0,r20 /* flush new instr. to memory. */
+ icbi 0,r20 /* invalidate instr. cache line */
+ lwz r21, 4(r0) /* restore r21 from memory */
+ mfspr r20, M_TW /* restore r20 from M_TW */
+ isync /* Wait until new instr is loaded from memory */
+modified_instr:
+ .space 4 /* this is where the add instr. is stored */
+ bne+ 143f
+ subf r20,r0,r20 /* r20=r20-r0, only if reg RA is r0 */
+143: mtdar r20 /* store faulting EA in DAR */
+ b DARFixed /* Go back to normal TLB handling */
+#else
+ mfctr r20
+ mtdar r20 /* save ctr reg in DAR */
+ rlwinm r20, r21, 24, 24, 28 /* offset into jump table for reg RB */
+ addi r20, r20, 150f@l /* add start of table */
+ mtctr r20 /* load ctr with jump address */
+ xor r20, r20, r20 /* sum starts at zero */
+ bctr /* jump into table */
+150:
+ add r20, r20, r0 ;b 151f
+ add r20, r20, r1 ;b 151f
+ add r20, r20, r2 ;b 151f
+ add r20, r20, r3 ;b 151f
+ add r20, r20, r4 ;b 151f
+ add r20, r20, r5 ;b 151f
+ add r20, r20, r6 ;b 151f
+ add r20, r20, r7 ;b 151f
+ add r20, r20, r8 ;b 151f
+ add r20, r20, r9 ;b 151f
+ add r20, r20, r10 ;b 151f
+ add r20, r20, r11 ;b 151f
+ add r20, r20, r12 ;b 151f
+ add r20, r20, r13 ;b 151f
+ add r20, r20, r14 ;b 151f
+ add r20, r20, r15 ;b 151f
+ add r20, r20, r16 ;b 151f
+ add r20, r20, r17 ;b 151f
+ add r20, r20, r18 ;b 151f
+ add r20, r20, r19 ;b 151f
+ mtctr r21 ;b 154f /* r20 needs special handling */
+ mtctr r21 ;b 153f /* r21 needs special handling */
+ add r20, r20, r22 ;b 151f
+ add r20, r20, r23 ;b 151f
+ add r20, r20, r24 ;b 151f
+ add r20, r20, r25 ;b 151f
+ add r20, r20, r26 ;b 151f
+ add r20, r20, r27 ;b 151f
+ add r20, r20, r28 ;b 151f
+ add r20, r20, r29 ;b 151f
+ add r20, r20, r30 ;b 151f
+ add r20, r20, r31
+151:
+ rlwinm. r21,r21,19,24,28 /* offset into jump table for reg RA */
+ beq 152f /* if reg RA is zero, don't add it */
+ addi r21, r21, 150b@l /* add start of table */
+ mtctr r21 /* load ctr with jump address */
+ rlwinm r21,r21,0,16,10 /* make sure we don't execute this more than once */
+ bctr /* jump into table */
+152:
+ mfdar r21
+ mtctr r21 /* restore ctr reg from DAR */
+ mtdar r20 /* save fault EA to DAR */
+ b DARFixed /* Go back to normal TLB handling */
+
+ /* special handling for r20,r21 since these are modified already */
+153: lwz r21, 4(r0) /* load r21 from memory */
+ b 155f
+154: mfspr r21, M_TW /* load r20 from M_TW */
+155: add r20, r20, r21 /* add it */
+ mfctr r21 /* restore r21 */
+ b 151b
+#endif
/*
* This code finishes saving the registers to the exception frame
--
1.7.3.4
next prev parent reply other threads:[~2011-10-10 11:30 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-10 11:30 [PATCH 00/14] Backport 8xx TLB to 2.4 Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 01/14] 8xx: Use a macro to simpliy CPU6 errata code Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 02/14] 8xx: Tag DAR with 0x00f0 to catch buggy instructions Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 03/14] 8xx: invalidate non present TLBs Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 04/14] 8xx: Fix CONFIG_PIN_TLB Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 05/14] 8xx: Update TLB asm so it behaves as linux mm expects Joakim Tjernlund
2011-10-10 11:30 ` Joakim Tjernlund [this message]
2011-10-10 11:30 ` [PATCH 07/14] 8xx: CPU6 errata make DTLB error too big to fit Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 08/14] 8xx: Add missing Guarded setting in DTLB Error Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 09/14] 8xx: Restore _PAGE_WRITETHRU Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 10/14] 8xx: Set correct HW pte flags in DTLB Error too Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 11/14] 8xx: start using dcbX instructions in various copy routines Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 12/14] 8xx: Use symbolic constants in TLB asm Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 13/14] 8xx: Optimize TLB Miss handlers Joakim Tjernlund
2011-10-10 11:30 ` [PATCH 14/14] 8xx: The TLB miss handler manages ACCESSED correctly Joakim Tjernlund
2011-10-10 12:30 ` [PATCH 00/14] Backport 8xx TLB to 2.4 Willy Tarreau
2011-12-11 17:19 ` Joakim Tjernlund
2011-12-11 17:33 ` Willy Tarreau
2012-02-08 8:44 ` Joakim Tjernlund
2012-02-08 9:44 ` Willy Tarreau
2012-02-08 11:39 ` Joakim Tjernlund
2012-02-08 12:26 ` Willy Tarreau
2012-04-09 13:08 ` Willy Tarreau
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=1318246220-4839-7-git-send-email-Joakim.Tjernlund@transmode.se \
--to=joakim.tjernlund@transmode.se \
--cc=linuxppc-dev@ozlabs.org \
--cc=ppc6dev@digitaldans.com \
--cc=scottwood@freescale.com \
--cc=w@1wt.eu \
/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.