linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@c-s.fr>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Michael Ellerman <mpe@ellerman.id.au>,
	aneesh.kumar@linux.vnet.ibm.com
Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
Subject: [PATCH v5 21/22] powerpc/nohash32: allow setting GUARDED attribute in the PMD directly
Date: Tue, 25 Sep 2018 16:51:20 +0000 (UTC)	[thread overview]
Message-ID: <0dc7d683dfd155c85b9472bd2e24e7bea5907ca2.1537892499.git.christophe.leroy@c-s.fr> (raw)
In-Reply-To: <cover.1537892498.git.christophe.leroy@c-s.fr>

On the 8xx, the GUARDED attribute of the pages is managed in the
L1 entry, therefore to avoid having to copy it into L1 entry
at each TLB miss, we have to set it in the PMD

In order to allow this, this patch splits the VM alloc space in two
parts, one for VM alloc and non Guarded IO, and one for Guarded IO.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/book3s/32/pgalloc.h |  2 +-
 arch/powerpc/include/asm/book3s/32/pgtable.h |  2 ++
 arch/powerpc/include/asm/nohash/32/pgalloc.h | 19 ++++++++--
 arch/powerpc/include/asm/nohash/32/pgtable.h | 19 ++++++++--
 arch/powerpc/mm/dump_linuxpagetables.c       | 21 +++++++++--
 arch/powerpc/mm/mem.c                        |  7 ++++
 arch/powerpc/mm/pgtable_32.c                 | 52 +++++++++++++++++++++++++---
 arch/powerpc/platforms/Kconfig.cputype       |  2 ++
 8 files changed, 112 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgalloc.h b/arch/powerpc/include/asm/book3s/32/pgalloc.h
index 711a8b84e3ee..9097cfd4ce43 100644
--- a/arch/powerpc/include/asm/book3s/32/pgalloc.h
+++ b/arch/powerpc/include/asm/book3s/32/pgalloc.h
@@ -139,7 +139,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 	pgtable_free_tlb(tlb, page_address(table), 0);
 }
 
-static inline pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va)
+static inline pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va, bool is_g)
 {
 	if (!pmd_present(*pmdp)) {
 		pte_t *ptep = __va(memblock_alloc(PAGE_SIZE, PAGE_SIZE));
diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 7a8a590f6b4c..28001d5eaa89 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -156,6 +156,8 @@ static inline bool pte_user(pte_t pte)
 #define IOREMAP_TOP	KVIRT_TOP
 #endif
 
+#define IOREMAP_BASE	VMALLOC_START
+
 /*
  * Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 16MB value just means that there will be a 64MB "hole" after the
diff --git a/arch/powerpc/include/asm/nohash/32/pgalloc.h b/arch/powerpc/include/asm/nohash/32/pgalloc.h
index 77c09bef3122..bfb26c385dac 100644
--- a/arch/powerpc/include/asm/nohash/32/pgalloc.h
+++ b/arch/powerpc/include/asm/nohash/32/pgalloc.h
@@ -60,6 +60,14 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
 	*pmdp = __pmd(__pa(pte) | _PMD_PRESENT);
 }
 
+#ifdef CONFIG_PPC_PMD_GUARDED
+static inline void pmd_populate_kernel_g(struct mm_struct *mm, pmd_t *pmdp,
+					 pte_t *pte)
+{
+	*pmdp = __pmd(__pa(pte) | _PMD_PRESENT | _PMD_GUARDED);
+}
+#endif
+
 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
 				pgtable_t pte_page)
 {
@@ -84,6 +92,10 @@ static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
 #define pmd_pgtable(pmd) ((pgtable_t)pmd_page_vaddr(pmd))
 #endif
 
+#ifndef CONFIG_PPC_PMD_GUARDED
+#define pmd_populate_kernel_g			pmd_populate_kernel
+#endif
+
 static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
 					  unsigned long address)
 {
@@ -151,7 +163,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
 	pgtable_free_tlb(tlb, table, 0);
 }
 
-static inline pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va)
+static inline pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va, bool is_g)
 {
 	if (!pmd_present(*pmdp)) {
 		pte_t *ptep = __va(memblock_alloc(PTE_FRAG_SIZE, PTE_FRAG_SIZE));
@@ -164,7 +176,10 @@ static inline pte_t *early_pte_alloc_kernel(pmd_t *pmdp, unsigned long va)
 		else
 			memset(ptep, 0, PTE_FRAG_SIZE);
 
-		pmd_populate_kernel(&init_mm, pmdp, ptep);
+		if (is_g)
+			pmd_populate_kernel_g(&init_mm, pmdp, ptep);
+		else
+			pmd_populate_kernel(&init_mm, pmdp, ptep);
 	}
 	return pte_offset_kernel(pmdp, va);
 }
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index dc82c10383d5..fccc5620a988 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -84,9 +84,14 @@ extern int icache_44x_need_flush;
  * virtual space that goes below PKMAP and FIXMAP
  */
 #ifdef CONFIG_HIGHMEM
-#define KVIRT_TOP	PKMAP_BASE
+#define _KVIRT_TOP	PKMAP_BASE
 #else
-#define KVIRT_TOP	(0xfe000000UL)	/* for now, could be FIXMAP_BASE ? */
+#define _KVIRT_TOP	(0xfe000000UL)	/* for now, could be FIXMAP_BASE ? */
+#endif
+#ifdef CONFIG_PPC_PMD_GUARDED
+#define KVIRT_TOP	_ALIGN_DOWN(_KVIRT_TOP, PGDIR_SIZE)
+#else
+#define KVIRT_TOP	_KVIRT_TOP
 #endif
 
 /*
@@ -99,6 +104,12 @@ extern int icache_44x_need_flush;
 #else
 #define IOREMAP_TOP	KVIRT_TOP
 #endif
+#ifdef CONFIG_PPC_PMD_GUARDED
+#define IOREMAP_BASE	_ALIGN_UP(VMALLOC_START + (IOREMAP_TOP - VMALLOC_START) / 2, \
+				  PGDIR_SIZE)
+#else
+#define IOREMAP_BASE	VMALLOC_START
+#endif
 
 /*
  * Just any arbitrary offset to the start of the vmalloc VM area: the
@@ -123,7 +134,11 @@ extern int icache_44x_need_flush;
 #else
 #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
 #endif
+#ifdef CONFIG_PPC_PMD_GUARDED
+#define VMALLOC_END	IOREMAP_BASE
+#else
 #define VMALLOC_END	ioremap_bot
+#endif
 
 /*
  * Bits in a linux-style PTE.  These match the bits in the
diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c
index e60aa6d7456d..105d0118f735 100644
--- a/arch/powerpc/mm/dump_linuxpagetables.c
+++ b/arch/powerpc/mm/dump_linuxpagetables.c
@@ -76,9 +76,9 @@ struct addr_marker {
 
 static struct addr_marker address_markers[] = {
 	{ 0,	"Start of kernel VM" },
+#ifdef CONFIG_PPC64
 	{ 0,	"vmalloc() Area" },
 	{ 0,	"vmalloc() End" },
-#ifdef CONFIG_PPC64
 	{ 0,	"isa I/O start" },
 	{ 0,	"isa I/O end" },
 	{ 0,	"phb I/O start" },
@@ -87,8 +87,19 @@ static struct addr_marker address_markers[] = {
 	{ 0,	"I/O remap end" },
 	{ 0,	"vmemmap start" },
 #else
+#ifdef CONFIG_PPC_PMD_GUARDED
+	{ 0,	"vmalloc() Area" },
+	{ 0,	"vmalloc() End" },
+	{ 0,	"Early I/O remap start" },
+	{ 0,	"Early I/O remap end" },
+	{ 0,	"I/O remap start" },
+	{ 0,	"I/O remap end" },
+#else
 	{ 0,	"Early I/O remap start" },
 	{ 0,	"Early I/O remap end" },
+	{ 0,	"vmalloc() I/O remap start" },
+	{ 0,	"vmalloc() I/O remap end" },
+#endif
 #ifdef CONFIG_NOT_COHERENT_CACHE
 	{ 0,	"Consistent mem start" },
 	{ 0,	"Consistent mem end" },
@@ -286,9 +297,9 @@ static void populate_markers(void)
 	int i = 0;
 
 	address_markers[i++].start_address = PAGE_OFFSET;
+#ifdef CONFIG_PPC64
 	address_markers[i++].start_address = VMALLOC_START;
 	address_markers[i++].start_address = VMALLOC_END;
-#ifdef CONFIG_PPC64
 	address_markers[i++].start_address = ISA_IO_BASE;
 	address_markers[i++].start_address = ISA_IO_END;
 	address_markers[i++].start_address = PHB_IO_BASE;
@@ -301,6 +312,12 @@ static void populate_markers(void)
 	address_markers[i++].start_address =  VMEMMAP_BASE;
 #endif
 #else /* !CONFIG_PPC64 */
+#ifdef CONFIG_PPC_PMD_GUARDED
+	address_markers[i++].start_address = VMALLOC_START;
+	address_markers[i++].start_address = VMALLOC_END;
+#endif
+	address_markers[i++].start_address = IOREMAP_BASE;
+	address_markers[i++].start_address = ioremap_bot;
 	address_markers[i++].start_address = ioremap_bot;
 	address_markers[i++].start_address = IOREMAP_TOP;
 #ifdef CONFIG_NOT_COHERENT_CACHE
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index dd949d6649a2..1a4a20a95eaf 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -388,8 +388,15 @@ void __init mem_init(void)
 #endif /* CONFIG_NOT_COHERENT_CACHE */
 	pr_info("  * 0x%08lx..0x%08lx  : early ioremap\n",
 		ioremap_bot, IOREMAP_TOP);
+#ifdef CONFIG_PPC_PMD_GUARDED
+	pr_info("  * 0x%08lx..0x%08lx  : ioremap\n",
+		IOREMAP_BASE, ioremap_bot);
+	pr_info("  * 0x%08lx..0x%08lx  : vmalloc\n",
+		VMALLOC_START, VMALLOC_END);
+#else
 	pr_info("  * 0x%08lx..0x%08lx  : vmalloc & ioremap\n",
 		VMALLOC_START, VMALLOC_END);
+#endif
 #endif /* CONFIG_PPC32 */
 }
 
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 745f2f30d4e9..ce78c06db660 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -151,7 +151,14 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, pgprot_t prot, void *call
 
 	if (slab_is_available()) {
 		struct vm_struct *area;
-		area = get_vm_area_caller(size, VM_IOREMAP, caller);
+		bool is_g = pgprot_val(prot) & _PAGE_GUARDED;
+
+		if (IS_ENABLED(CONFIG_PPC_PMD_GUARDED) && is_g)
+			area = __get_vm_area_caller(size, VM_IOREMAP, IOREMAP_BASE,
+						    ioremap_bot, caller);
+		else
+			area = get_vm_area_caller(size, VM_IOREMAP, caller);
+
 		if (area == 0)
 			return NULL;
 		area->phys_addr = p;
@@ -192,19 +199,54 @@ void iounmap(volatile void __iomem *addr)
 }
 EXPORT_SYMBOL(iounmap);
 
+#ifdef CONFIG_PPC_PMD_GUARDED
+static int __pte_alloc_kernel_g(pmd_t *pmd, unsigned long address)
+{
+	pte_t *new = pte_alloc_one_kernel(&init_mm, address);
+	if (!new)
+		return -ENOMEM;
+
+	smp_wmb(); /* See comment in __pte_alloc */
+
+	spin_lock(&init_mm.page_table_lock);
+	if (likely(pmd_none(*pmd))) {	/* Has another populated it ? */
+		pmd_populate_kernel_g(&init_mm, pmd, new);
+		new = NULL;
+	}
+	spin_unlock(&init_mm.page_table_lock);
+	if (new)
+		pte_free_kernel(&init_mm, new);
+	return 0;
+}
+
+static pte_t *pte_alloc_kernel_g(pmd_t *pmd, unsigned long address)
+{
+	if (unlikely(pmd_none(*(pmd))) && __pte_alloc_kernel_g(pmd, address))
+		return NULL;
+	return pte_offset_kernel(pmd, address);
+}
+#else
+#define pte_alloc_kernel_g(pmd, address)	pte_alloc_kernel(pmd, address)
+#endif
+
 __ref int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
 {
 	pmd_t *pd;
 	pte_t *pg;
 	int err = -ENOMEM;
+	bool is_g = pgprot_val(prot) & _PAGE_GUARDED;
 
 	/* Use upper 10 bits of VA to index the first level map */
 	pd = pmd_offset(pud_offset(pgd_offset_k(va), va), va);
 	/* Use middle 10 bits of VA to index the second-level map */
-	if (slab_is_available())
-		pg = pte_alloc_kernel(pd, va);
-	else
-		pg = early_pte_alloc_kernel(pd, va);
+	if (slab_is_available()) {
+		if (is_g)
+			pg = pte_alloc_kernel_g(pd, va);
+		else
+			pg = pte_alloc_kernel(pd, va);
+	} else {
+		pg = early_pte_alloc_kernel(pd, va, is_g);
+	}
 	if (pg != 0) {
 		err = 0;
 		/* The PTE should never be already set nor present in the
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 6c6a7c72cae4..d0984546fbec 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -355,6 +355,8 @@ config ARCH_ENABLE_HUGEPAGE_MIGRATION
 	def_bool y
 	depends on PPC_BOOK3S_64 && HUGETLB_PAGE && MIGRATION
 
+config PPC_PMD_GUARDED
+	bool
 
 config PPC_MMU_NOHASH
 	def_bool y
-- 
2.13.3

  parent reply	other threads:[~2018-09-25 16:51 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-25 16:50 [PATCH v5 00/22] Implement use of HW assistance on TLB table walk on 8xx Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 01/22] Revert "powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for CONFIG_SWAP" Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 02/22] powerpc/code-patching: add a helper to get the address of a patch_site Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 03/22] powerpc/8xx: Use patch_site for memory setup patching Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 04/22] powerpc/8xx: Use patch_site for perf counters setup Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 05/22] powerpc/8xx: Move SW perf counters in first 32kb of memory Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 06/22] powerpc/8xx: Temporarily disable 16k pages and 512k hugepages Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 07/22] powerpc/mm: Use hardware assistance in TLB handlers on the 8xx Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 08/22] powerpc/mm: Enable 512k hugepage support with HW assistance " Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 09/22] powerpc/8xx: don't use r12/SPRN_SPRG_SCRATCH2 in TLB Miss handlers Christophe Leroy
2018-09-25 16:50 ` [PATCH v5 10/22] powerpc/8xx: regroup TLB handler routines Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 11/22] powerpc/mm: don't use pte_alloc_one_kernel() before slab is available Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 12/22] powerpc/mm: inline pte_alloc_one() and pte_alloc_one_kernel() in PPC32 Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 13/22] powerpc/book3s32: Remove CONFIG_BOOKE dependent code Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 14/22] powerpc/mm: Move pte_fragment_alloc() to a common location Christophe Leroy
2018-09-26  2:43   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 15/22] powerpc/mm: Avoid useless lock with single page fragments Christophe Leroy
2018-09-26  2:43   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 16/22] powerpc/mm: move platform specific mmu-xxx.h in platform directories Christophe Leroy
2018-09-26  2:44   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 17/22] powerpc/mm: Move pgtable_t into platform headers Christophe Leroy
2018-09-26  2:44   ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 18/22] powerpc/mm: Extend pte_fragment functionality to nohash/32 Christophe Leroy
2018-09-26  2:48   ` Aneesh Kumar K.V
2018-09-26  8:10     ` Christophe LEROY
2018-09-26  9:01       ` Aneesh Kumar K.V
2018-09-25 16:51 ` [PATCH v5 19/22] powerpc/8xx: Remove PTE_ATOMIC_UPDATES Christophe Leroy
2018-09-25 16:51 ` [PATCH v5 20/22] powerpc/mm: reintroduce 16K pages with HW assistance on 8xx Christophe Leroy
2018-09-25 16:51 ` Christophe Leroy [this message]
2018-10-17 11:51   ` [PATCH v5 21/22] powerpc/nohash32: allow setting GUARDED attribute in the PMD directly Christophe LEROY
2018-09-25 16:51 ` [PATCH v5 22/22] powerpc/8xx: set " Christophe Leroy

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=0dc7d683dfd155c85b9472bd2e24e7bea5907ca2.1537892499.git.christophe.leroy@c-s.fr \
    --to=christophe.leroy@c-s.fr \
    --cc=aneesh.kumar@linux.vnet.ibm.com \
    --cc=benh@kernel.crashing.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.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 NNTP newsgroup(s).