Linux-parisc archive mirror
 help / color / mirror / Atom feed
From: John David Anglin <dave@parisc-linux.org>
To: linux-parisc@vger.kernel.org
Cc: Helge Deller <deller@gmx.de>,
	James Bottomley <James.Bottomley@hansenpartnership.com>
Subject: [PATCH v2] parisc: Add nop instructions after TLB inserts
Date: Wed, 18 Oct 2023 22:34:14 +0000	[thread overview]
Message-ID: <ZTBdZt01UgujpG2h@mx3210.localdomain> (raw)

[-- Attachment #1: Type: text/plain, Size: 4389 bytes --]

An excerpt from the PA8800 ERS states:

o The PA8800 violates the seven instruction pipeline rule when performing
  TLB inserts or PxTLBE instructions with the PSW C bit on. The instruction
  will take effect by the 12th instruction after the insert or purge.

I believe we have a problem with handling TLB misses. We don't fill
the pipeline following TLB inserts. As a result, we likely fault again
after returning from the interruption.

The above statement indicates that we need at least seven instructions
after the insert on pre PA8800 processors and we need 12 instructions
on PA8800/PA8900 processors.

Here we add macros and code to provide the required number instructions
after a TLB insert.

Tested on c8000.

v2: Revise per Helge's suggestions. Applies to master 6.6.0-rc6.

Signed-off-by: John David Anglin <dave.anglin@bell.net>
Suggested-by: Helge Deller <deller@gmx.de>
---

diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index ae03b8679696..4a848a928238 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -36,6 +36,24 @@
 	.level 2.0
 #endif
 
+/*
+ * We need seven instructions after a TLB insert for it to take effect.
+ * The PA8800/PA8900 processors are an exception and need 12 instructions.
+ * The RFI changes both IAOQ_Back and IAOQ_Front, so it counts as one.
+ */
+#ifdef CONFIG_64BIT
+#define NUM_INSNS    12
+#else
+#define NUM_INSNS    7
+#endif
+
+	/* Insert num nops */
+	.macro	insert_nops num
+	.rept \num
+	nop
+	.endr
+	.endm
+
 	/* Get aligned page_table_lock address for this mm from cr28/tr4 */
 	.macro  get_ptl reg
 	mfctl	%cr28,\reg
@@ -415,25 +433,38 @@
 3:
 	.endm
 
-	/* Release page_table_lock without reloading lock address.
-	   We use an ordered store to ensure all prior accesses are
-	   performed prior to releasing the lock. */
-	.macro		ptl_unlock0	spc,tmp,tmp2
-#ifdef CONFIG_TLB_PTLOCK
-98:	ldi		__ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
+	/* Release page_table_lock if for user space. We use an ordered
+	   store to ensure all prior accesses are performed prior to
+	   releasing the lock. */
+	.macro		ptl_unlock	spc,tmp,tmp2
+	ldi		__ARCH_SPIN_LOCK_UNLOCKED_VAL, \tmp2
 	or,COND(=)	%r0,\spc,%r0
 	stw,ma		\tmp2,0(\tmp)
+	.endm
+
+	/* Release page_table_lock without reloading lock address. */
+	.macro		ptl_unlock0	spc,tmp,tmp2
+#ifdef CONFIG_TLB_PTLOCK
+98:	ptl_unlock	\spc,\tmp,\tmp2
 99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+#else
+	insert_nops	3
 #endif
+	/* Insert nops so we don't return before TLB insert takes effect. */
+	insert_nops	NUM_INSNS - 4
 	.endm
 
-	/* Release page_table_lock. */
+	/* Reload lock address and release page_table_lock. */
 	.macro		ptl_unlock1	spc,tmp,tmp2
 #ifdef CONFIG_TLB_PTLOCK
 98:	get_ptl		\tmp
-	ptl_unlock0	\spc,\tmp,\tmp2
+	ptl_unlock	\spc,\tmp,\tmp2
 99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+#else
+	insert_nops	4
 #endif
+	/* Insert nops so we don't return before TLB insert takes effect. */
+	insert_nops	NUM_INSNS - 5
 	.endm
 
 	/* Set the _PAGE_ACCESSED bit of the PTE.  Be clever and
@@ -1133,6 +1164,7 @@ dtlb_check_alias_20w:
 
 	idtlbt          pte,prot
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1159,6 +1191,7 @@ nadtlb_check_alias_20w:
 
 	idtlbt          pte,prot
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1194,6 +1227,7 @@ dtlb_check_alias_11:
 	idtlba          pte,(va)
 	idtlbp          prot,(va)
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1227,6 +1261,7 @@ nadtlb_check_alias_11:
 	idtlba          pte,(va)
 	idtlbp          prot,(va)
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1255,6 +1290,7 @@ dtlb_check_alias_20:
 	
 	idtlbt          pte,prot
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1283,6 +1319,7 @@ nadtlb_check_alias_20:
 
 	idtlbt          pte,prot
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1352,6 +1389,7 @@ naitlb_check_alias_20w:
 
 	iitlbt		pte,prot
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1411,6 +1449,7 @@ naitlb_check_alias_11:
 	iitlba          pte,(%sr0, va)
 	iitlbp          prot,(%sr0, va)
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 
@@ -1460,6 +1499,7 @@ naitlb_check_alias_20:
 
 	iitlbt          pte,prot
 
+	insert_nops	NUM_INSNS - 1
 	rfir
 	nop
 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

                 reply	other threads:[~2023-10-18 22:34 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=ZTBdZt01UgujpG2h@mx3210.localdomain \
    --to=dave@parisc-linux.org \
    --cc=James.Bottomley@hansenpartnership.com \
    --cc=deller@gmx.de \
    --cc=linux-parisc@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).