All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs
@ 2016-08-24  9:33 Aneesh Kumar K.V
  2016-08-24  9:33 ` [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding " Aneesh Kumar K.V
                   ` (4 more replies)
  0 siblings, 5 replies; 9+ messages in thread
From: Aneesh Kumar K.V @ 2016-08-24  9:33 UTC (permalink / raw)
  To: benh, paulus, mpe; +Cc: linuxppc-dev, Aneesh Kumar K.V

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/cputable.h |  4 +++-
 arch/powerpc/kernel/cputable.c      | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 82026b419341..f752e6f7cfbe 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -212,6 +212,7 @@ enum {
 #define CPU_FTR_DABRX			LONG_ASM_CONST(0x0800000000000000)
 #define CPU_FTR_PMAO_BUG		LONG_ASM_CONST(0x1000000000000000)
 #define CPU_FTR_SUBCORE			LONG_ASM_CONST(0x2000000000000000)
+#define CPU_FTR_POWER9_DD1		LONG_ASM_CONST(0x4000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -472,6 +473,7 @@ enum {
 	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
 	    CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_FTR_ARCH_300)
+#define CPU_FTRS_POWER9_DD1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -490,7 +492,7 @@ enum {
 	    (CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | \
 	     CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | \
 	     CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD1 | CPU_FTRS_CELL | \
-	     CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9)
+	     CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_POWER9 | CPU_FTRS_POWER9_DD1)
 #endif
 #else
 enum {
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 74248ab18e98..6c4646ac9234 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -506,6 +506,25 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.machine_check_early	= __machine_check_early_realmode_p8,
 		.platform		= "power8",
 	},
+	{	/* Power9 DD1*/
+		.pvr_mask		= 0xffffff00,
+		.pvr_value		= 0x004e0100,
+		.cpu_name		= "POWER9 (raw)",
+		.cpu_features		= CPU_FTRS_POWER9_DD1,
+		.cpu_user_features	= COMMON_USER_POWER9,
+		.cpu_user_features2	= COMMON_USER2_POWER9,
+		.mmu_features		= MMU_FTRS_POWER9,
+		.icache_bsize		= 128,
+		.dcache_bsize		= 128,
+		.num_pmcs		= 6,
+		.pmc_type		= PPC_PMC_IBM,
+		.oprofile_cpu_type	= "ppc64/power9",
+		.oprofile_type		= PPC_OPROFILE_INVALID,
+		.cpu_setup		= __setup_cpu_power9,
+		.cpu_restore		= __restore_cpu_power9,
+		.flush_tlb		= __flush_tlb_power9,
+		.platform		= "power9",
+	},
 	{	/* Power9 */
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x004e0000,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding for different POWER9 revs
  2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
@ 2016-08-24  9:33 ` Aneesh Kumar K.V
  2016-09-06  1:11   ` Michael Neuling
  2016-08-24  9:33 ` [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence " Aneesh Kumar K.V
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Aneesh Kumar K.V @ 2016-08-24  9:33 UTC (permalink / raw)
  To: benh, paulus, mpe; +Cc: linuxppc-dev, Aneesh Kumar K.V

POWER9 DD1 uses RTS - 28 for the RTS value but other revisions use
RTS - 31.  This makes this distinction for the different revisions

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/64/radix.h | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index df294224e280..a2fe8fbfbd3d 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -233,14 +233,19 @@ static inline unsigned long radix__get_tree_size(void)
 {
 	unsigned long rts_field;
 	/*
-	 * we support 52 bits, hence 52-31 = 21, 0b10101
+	 * We support 52 bits, hence:
+	 *  DD1    52-28 = 24, 0b11000
+	 *  Others 52-31 = 21, 0b10101
 	 * RTS encoding details
 	 * bits 0 - 3 of rts -> bits 6 - 8 unsigned long
 	 * bits 4 - 5 of rts -> bits 62 - 63 of unsigned long
 	 */
-	rts_field = (0x5UL << 5); /* 6 - 8 bits */
-	rts_field |= (0x2UL << 61);
-
+	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
+		rts_field = (0x3UL << 61);
+	else {
+		rts_field = (0x5UL << 5); /* 6 - 8 bits */
+		rts_field |= (0x2UL << 61);
+	}
 	return rts_field;
 }
 #endif /* __ASSEMBLY__ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence for different POWER9 revs
  2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
  2016-08-24  9:33 ` [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding " Aneesh Kumar K.V
@ 2016-08-24  9:33 ` Aneesh Kumar K.V
  2016-09-06  1:12   ` Michael Neuling
  2016-08-24  9:33 ` [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash Aneesh Kumar K.V
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 9+ messages in thread
From: Aneesh Kumar K.V @ 2016-08-24  9:33 UTC (permalink / raw)
  To: benh, paulus, mpe; +Cc: linuxppc-dev, Aneesh Kumar K.V

POWER9 DD1 requires pte to be marked invalid (V=0) before updating
it with the new value. This makes this distinction for the different
revisions.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/book3s/32/pgtable.h |  3 +-
 arch/powerpc/include/asm/book3s/64/pgtable.h |  5 +-
 arch/powerpc/include/asm/book3s/64/radix.h   | 75 ++++++++++++++++++++++------
 arch/powerpc/include/asm/nohash/32/pgtable.h |  3 +-
 arch/powerpc/include/asm/nohash/64/pgtable.h |  3 +-
 arch/powerpc/mm/pgtable-book3s64.c           |  2 +-
 arch/powerpc/mm/pgtable.c                    |  2 +-
 7 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/include/asm/book3s/32/pgtable.h
index 38b33dcfcc9d..6b8b2d57fdc8 100644
--- a/arch/powerpc/include/asm/book3s/32/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
@@ -223,7 +223,8 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 }
 
 
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+static inline void __ptep_set_access_flags(struct mm_struct *mm,
+					   pte_t *ptep, pte_t entry)
 {
 	unsigned long set = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
index 263bf39ced40..8ec8be9495ba 100644
--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
+++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
@@ -565,10 +565,11 @@ static inline bool check_pte_access(unsigned long access, unsigned long ptev)
  * Generic functions with hash/radix callbacks
  */
 
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+static inline void __ptep_set_access_flags(struct mm_struct *mm,
+					   pte_t *ptep, pte_t entry)
 {
 	if (radix_enabled())
-		return radix__ptep_set_access_flags(ptep, entry);
+		return radix__ptep_set_access_flags(mm, ptep, entry);
 	return hash__ptep_set_access_flags(ptep, entry);
 }
 
diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h
index a2fe8fbfbd3d..2a46dea8e1b1 100644
--- a/arch/powerpc/include/asm/book3s/64/radix.h
+++ b/arch/powerpc/include/asm/book3s/64/radix.h
@@ -11,6 +11,11 @@
 #include <asm/book3s/64/radix-4k.h>
 #endif
 
+#ifndef __ASSEMBLY__
+#include <asm/book3s/64/tlbflush-radix.h>
+#include <asm/cpu_has_feature.h>
+#endif
+
 /* An empty PTE can still have a R or C writeback */
 #define RADIX_PTE_NONE_MASK		(_PAGE_DIRTY | _PAGE_ACCESSED)
 
@@ -105,11 +110,8 @@
 #define RADIX_PUD_TABLE_SIZE	(sizeof(pud_t) << RADIX_PUD_INDEX_SIZE)
 #define RADIX_PGD_TABLE_SIZE	(sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE)
 
-static inline unsigned long radix__pte_update(struct mm_struct *mm,
-					unsigned long addr,
-					pte_t *ptep, unsigned long clr,
-					unsigned long set,
-					int huge)
+static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned long clr,
+					       unsigned long set)
 {
 	pte_t pte;
 	unsigned long old_pte, new_pte;
@@ -121,9 +123,39 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
 
 	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
 
-	/* We already do a sync in cmpxchg, is ptesync needed ?*/
+	return old_pte;
+}
+
+
+static inline unsigned long radix__pte_update(struct mm_struct *mm,
+					unsigned long addr,
+					pte_t *ptep, unsigned long clr,
+					unsigned long set,
+					int huge)
+{
+	unsigned long old_pte;
+
+	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
+
+		unsigned long new_pte;
+
+		old_pte = __radix_pte_update(ptep, ~0, 0);
+		asm volatile("ptesync" : : : "memory");
+		/*
+		 * new value of pte
+		 */
+		new_pte = (old_pte | set) & ~clr;
+
+		/*
+		 * For now let's do heavy pid flush
+		 * radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
+		 */
+		radix__flush_tlb_mm(mm);
+
+		__radix_pte_update(ptep, 0, new_pte);
+	} else
+		old_pte = __radix_pte_update(ptep, clr, set);
 	asm volatile("ptesync" : : : "memory");
-	/* huge pages use the old page table lock */
 	if (!huge)
 		assert_pte_locked(mm, addr);
 
@@ -134,20 +166,33 @@ static inline unsigned long radix__pte_update(struct mm_struct *mm,
  * Set the dirty and/or accessed bits atomically in a linux PTE, this
  * function doesn't need to invalidate tlb.
  */
-static inline void radix__ptep_set_access_flags(pte_t *ptep, pte_t entry)
+static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
+						pte_t *ptep, pte_t entry)
 {
-	pte_t pte;
-	unsigned long old_pte, new_pte;
+
 	unsigned long set = pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESSED |
 					      _PAGE_RW | _PAGE_EXEC);
-	do {
-		pte = READ_ONCE(*ptep);
-		old_pte = pte_val(pte);
+
+	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
+
+		unsigned long old_pte, new_pte;
+
+		old_pte = __radix_pte_update(ptep, ~0, 0);
+		asm volatile("ptesync" : : : "memory");
+		/*
+		 * new value of pte
+		 */
 		new_pte = old_pte | set;
 
-	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
+		/*
+		 * For now let's do heavy pid flush
+		 * radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
+		 */
+		radix__flush_tlb_mm(mm);
 
-	/* We already do a sync in cmpxchg, is ptesync needed ?*/
+		__radix_pte_update(ptep, 0, new_pte);
+	} else
+		__radix_pte_update(ptep, 0, set);
 	asm volatile("ptesync" : : : "memory");
 }
 
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 780847597514..c219ef7be53b 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -267,7 +267,8 @@ static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 }
 
 
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+static inline void __ptep_set_access_flags(struct mm_struct *mm,
+					   pte_t *ptep, pte_t entry)
 {
 	unsigned long set = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/include/asm/nohash/64/pgtable.h
index d4d808cf905e..653a1838469d 100644
--- a/arch/powerpc/include/asm/nohash/64/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
@@ -300,7 +300,8 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
 /* Set the dirty and/or accessed bits atomically in a linux PTE, this
  * function doesn't need to flush the hash entry
  */
-static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
+static inline void __ptep_set_access_flags(struct mm_struct *mm,
+					   pte_t *ptep, pte_t entry)
 {
 	unsigned long bits = pte_val(entry) &
 		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
index 34079302cc17..7328886bca4c 100644
--- a/arch/powerpc/mm/pgtable-book3s64.c
+++ b/arch/powerpc/mm/pgtable-book3s64.c
@@ -35,7 +35,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 #endif
 	changed = !pmd_same(*(pmdp), entry);
 	if (changed) {
-		__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
+		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry));
 		flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
 	}
 	return changed;
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index 0b6fb244d0a1..911fdfb63ec1 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -224,7 +224,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long address,
 	if (changed) {
 		if (!is_vm_hugetlb_page(vma))
 			assert_pte_locked(vma->vm_mm, address);
-		__ptep_set_access_flags(ptep, entry);
+		__ptep_set_access_flags(vma->vm_mm, ptep, entry);
 		flush_tlb_page(vma, address);
 	}
 	return changed;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash
  2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
  2016-08-24  9:33 ` [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding " Aneesh Kumar K.V
  2016-08-24  9:33 ` [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence " Aneesh Kumar K.V
@ 2016-08-24  9:33 ` Aneesh Kumar K.V
  2016-09-06  1:18   ` Michael Neuling
  2016-09-06  1:10 ` [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Michael Neuling
  2016-09-13 12:16 ` [1/4] " Michael Ellerman
  4 siblings, 1 reply; 9+ messages in thread
From: Aneesh Kumar K.V @ 2016-08-24  9:33 UTC (permalink / raw)
  To: benh, paulus, mpe; +Cc: linuxppc-dev, Aneesh Kumar K.V

Power9 DD1 requires to update the hid0 register when switching from
hash to radix.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/reg.h  |  3 +++
 arch/powerpc/mm/hash_utils_64.c | 25 +++++++++++++++++++++++++
 arch/powerpc/mm/pgtable-radix.c | 28 ++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index f69f40f1519a..9dddabc2fced 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -475,6 +475,9 @@
 #define HID0_POWER8_1TO4LPAR	__MASK(51)
 #define HID0_POWER8_DYNLPARDIS	__MASK(48)
 
+/* POWER9 HID0 bits */
+#define HID0_POWER9_RADIX	__MASK(63 - 8)
+
 #define SPRN_HID1	0x3F1		/* Hardware Implementation Register 1 */
 #ifdef CONFIG_6xx
 #define HID1_EMCP	(1<<31)		/* 7450 Machine Check Pin Enable */
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 0821556e16f4..35a6721b3d25 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -711,6 +711,29 @@ int remove_section_mapping(unsigned long start, unsigned long end)
 }
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
+static void update_hid_for_hash(void)
+{
+	unsigned long hid0;
+	unsigned long rb = 3UL << PPC_BITLSHIFT(53); /* IS = 3 */
+
+	asm volatile("ptesync": : :"memory");
+	/* prs = 0, ric = 2, rs = 0, r = 1 is = 3 */
+	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+		     : : "r"(rb), "i"(0), "i"(0), "i"(2), "r"(0) : "memory");
+	asm volatile("eieio; tlbsync; ptesync; isync; slbia": : :"memory");
+	/*
+	 * now switch the HID
+	 */
+	hid0  = mfspr(SPRN_HID0);
+	hid0 &= ~HID0_POWER9_RADIX;
+	mtspr(SPRN_HID0, hid0);
+	asm volatile("isync": : :"memory");
+
+	/* Wait for it to happen */
+	while ((mfspr(SPRN_HID0) & HID0_POWER9_RADIX))
+		cpu_relax();
+}
+
 static void __init hash_init_partition_table(phys_addr_t hash_table,
 					     unsigned long htab_size)
 {
@@ -737,6 +760,8 @@ static void __init hash_init_partition_table(phys_addr_t hash_table,
 	 */
 	partition_tb->patb1 = 0;
 	pr_info("Partition table %p\n", partition_tb);
+	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
+		update_hid_for_hash();
 	/*
 	 * update partition table control register,
 	 * 64 K size.
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index af897d91d09f..8f086352e421 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -294,6 +294,32 @@ found:
 	return;
 }
 
+static void update_hid_for_radix(void)
+{
+	unsigned long hid0;
+	unsigned long rb = 3UL << PPC_BITLSHIFT(53); /* IS = 3 */
+
+	asm volatile("ptesync": : :"memory");
+	/* prs = 0, ric = 2, rs = 0, r = 1 is = 3 */
+	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+		     : : "r"(rb), "i"(1), "i"(0), "i"(2), "r"(0) : "memory");
+	/* prs = 1, ric = 2, rs = 0, r = 1 is = 3 */
+	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
+		     : : "r"(rb), "i"(1), "i"(1), "i"(2), "r"(0) : "memory");
+	asm volatile("eieio; tlbsync; ptesync; isync; slbia": : :"memory");
+	/*
+	 * now switch the HID
+	 */
+	hid0  = mfspr(SPRN_HID0);
+	hid0 |= HID0_POWER9_RADIX;
+	mtspr(SPRN_HID0, hid0);
+	asm volatile("isync": : :"memory");
+
+	/* Wait for it to happen */
+	while (!(mfspr(SPRN_HID0) & HID0_POWER9_RADIX))
+		cpu_relax();
+}
+
 void __init radix__early_init_mmu(void)
 {
 	unsigned long lpcr;
@@ -345,6 +371,8 @@ void __init radix__early_init_mmu(void)
 
 	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
 		radix_init_native();
+		if (cpu_has_feature(CPU_FTR_POWER9_DD1))
+			update_hid_for_radix();
 		lpcr = mfspr(SPRN_LPCR);
 		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
 		radix_init_partition_table();
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs
  2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
                   ` (2 preceding siblings ...)
  2016-08-24  9:33 ` [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash Aneesh Kumar K.V
@ 2016-09-06  1:10 ` Michael Neuling
  2016-09-13 12:16 ` [1/4] " Michael Ellerman
  4 siblings, 0 replies; 9+ messages in thread
From: Michael Neuling @ 2016-09-06  1:10 UTC (permalink / raw)
  To: Aneesh Kumar K.V, benh, paulus, mpe; +Cc: linuxppc-dev

On Wed, 2016-08-24 at 15:03 +0530, Aneesh Kumar K.V wrote:
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Acked-by: Michael Neuling <mikey@neuling.org>

> ---
> =C2=A0arch/powerpc/include/asm/cputable.h |=C2=A0=C2=A04 +++-
> =C2=A0arch/powerpc/kernel/cputable.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=
 19 +++++++++++++++++++
> =C2=A02 files changed, 22 insertions(+), 1 deletion(-)
>=20
> diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/a=
sm/cputable.h
> index 82026b419341..f752e6f7cfbe 100644
> --- a/arch/powerpc/include/asm/cputable.h
> +++ b/arch/powerpc/include/asm/cputable.h
> @@ -212,6 +212,7 @@ enum {
> =C2=A0#define CPU_FTR_DABRX			LONG_ASM_CONST(0x0800000000000000)
> =C2=A0#define CPU_FTR_PMAO_BUG		LONG_ASM_CONST(0x1000000000000000)
> =C2=A0#define CPU_FTR_SUBCORE			LONG_ASM_CONST(0x2000000000000000)
> +#define CPU_FTR_POWER9_DD1		LONG_ASM_CONST(0x4000000000000000)
> =C2=A0
> =C2=A0#ifndef __ASSEMBLY__
> =C2=A0
> @@ -472,6 +473,7 @@ enum {
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVM=
ODE | CPU_FTR_VMX_COPY | \
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_=
DAWR | \
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP | CPU_=
FTR_ARCH_300)
> +#define CPU_FTRS_POWER9_DD1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD1)
> =C2=A0#define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU=
_FTR_SMT | \
> @@ -490,7 +492,7 @@ enum {
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0(CPU_FTRS_POWER4 | CPU_FTRS_PPC970 | CPU_F=
TRS_POWER5 | \
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTRS_POWER6 | CPU_FTRS_POWER7 | =
CPU_FTRS_POWER8E | \
> =C2=A0	=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTRS_POWER8 | CPU_FTRS_POWER8_DD=
1 | CPU_FTRS_CELL | \
> -	=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_PO=
WER9)
> +	=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0CPU_FTRS_PA6T | CPU_FTR_VSX | CPU_FTRS_PO=
WER9 | CPU_FTRS_POWER9_DD1)
> =C2=A0#endif
> =C2=A0#else
> =C2=A0enum {
> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputabl=
e.c
> index 74248ab18e98..6c4646ac9234 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -506,6 +506,25 @@ static struct cpu_spec __initdata cpu_specs[] =3D {
> =C2=A0		.machine_check_early	=3D __machine_check_early_realmode_p8,
> =C2=A0		.platform		=3D "power8",
> =C2=A0	},
> +	{	/* Power9 DD1*/
> +		.pvr_mask		=3D 0xffffff00,
> +		.pvr_value		=3D 0x004e0100,
> +		.cpu_name		=3D "POWER9 (raw)",
> +		.cpu_features		=3D CPU_FTRS_POWER9_DD1,
> +		.cpu_user_features	=3D COMMON_USER_POWER9,
> +		.cpu_user_features2	=3D COMMON_USER2_POWER9,
> +		.mmu_features		=3D MMU_FTRS_POWER9,
> +		.icache_bsize		=3D 128,
> +		.dcache_bsize		=3D 128,
> +		.num_pmcs		=3D 6,
> +		.pmc_type		=3D PPC_PMC_IBM,
> +		.oprofile_cpu_type	=3D "ppc64/power9",
> +		.oprofile_type		=3D PPC_OPROFILE_INVALID,
> +		.cpu_setup		=3D __setup_cpu_power9,
> +		.cpu_restore		=3D __restore_cpu_power9,
> +		.flush_tlb		=3D __flush_tlb_power9,
> +		.platform		=3D "power9",
> +	},
> =C2=A0	{	/* Power9 */
> =C2=A0		.pvr_mask		=3D 0xffff0000,
> =C2=A0		.pvr_value		=3D 0x004e0000,

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding for different POWER9 revs
  2016-08-24  9:33 ` [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding " Aneesh Kumar K.V
@ 2016-09-06  1:11   ` Michael Neuling
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Neuling @ 2016-09-06  1:11 UTC (permalink / raw)
  To: Aneesh Kumar K.V, benh, paulus, mpe; +Cc: linuxppc-dev

On Wed, 2016-08-24 at 15:03 +0530, Aneesh Kumar K.V wrote:
> POWER9 DD1 uses RTS - 28 for the RTS value but other revisions use
> RTS - 31.=C2=A0=C2=A0This makes this distinction for the different revisi=
ons
>=20
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Acked-by: Michael Neuling <mikey@neuling.org>

> ---
> =C2=A0arch/powerpc/include/asm/book3s/64/radix.h | 13 +++++++++----
> =C2=A01 file changed, 9 insertions(+), 4 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/in=
clude/asm/book3s/64/radix.h
> index df294224e280..a2fe8fbfbd3d 100644
> --- a/arch/powerpc/include/asm/book3s/64/radix.h
> +++ b/arch/powerpc/include/asm/book3s/64/radix.h
> @@ -233,14 +233,19 @@ static inline unsigned long radix__get_tree_size(vo=
id)
> =C2=A0{
> =C2=A0	unsigned long rts_field;
> =C2=A0	/*
> -	=C2=A0* we support 52 bits, hence 52-31 =3D 21, 0b10101
> +	=C2=A0* We support 52 bits, hence:
> +	=C2=A0*=C2=A0=C2=A0DD1=C2=A0=C2=A0=C2=A0=C2=A052-28 =3D 24, 0b11000
> +	=C2=A0*=C2=A0=C2=A0Others 52-31 =3D 21, 0b10101
> =C2=A0	=C2=A0* RTS encoding details
> =C2=A0	=C2=A0* bits 0 - 3 of rts -> bits 6 - 8 unsigned long
> =C2=A0	=C2=A0* bits 4 - 5 of rts -> bits 62 - 63 of unsigned long
> =C2=A0	=C2=A0*/
> -	rts_field =3D (0x5UL << 5); /* 6 - 8 bits */
> -	rts_field |=3D (0x2UL << 61);
> -
> +	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
> +		rts_field =3D (0x3UL << 61);
> +	else {
> +		rts_field =3D (0x5UL << 5); /* 6 - 8 bits */
> +		rts_field |=3D (0x2UL << 61);
> +	}
> =C2=A0	return rts_field;
> =C2=A0}
> =C2=A0#endif /* __ASSEMBLY__ */

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence for different POWER9 revs
  2016-08-24  9:33 ` [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence " Aneesh Kumar K.V
@ 2016-09-06  1:12   ` Michael Neuling
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Neuling @ 2016-09-06  1:12 UTC (permalink / raw)
  To: Aneesh Kumar K.V, benh, paulus, mpe; +Cc: linuxppc-dev

On Wed, 2016-08-24 at 15:03 +0530, Aneesh Kumar K.V wrote:
> POWER9 DD1 requires pte to be marked invalid (V=3D0) before updating
> it with the new value. This makes this distinction for the different
> revisions.
>=20
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Acked-by: Michael Neuling <mikey@neuling.org>

> ---
> =C2=A0arch/powerpc/include/asm/book3s/32/pgtable.h |=C2=A0=C2=A03 +-
> =C2=A0arch/powerpc/include/asm/book3s/64/pgtable.h |=C2=A0=C2=A05 +-
> =C2=A0arch/powerpc/include/asm/book3s/64/radix.h=C2=A0=C2=A0=C2=A0| 75 ++=
++++++++++++++++++++------
> =C2=A0arch/powerpc/include/asm/nohash/32/pgtable.h |=C2=A0=C2=A03 +-
> =C2=A0arch/powerpc/include/asm/nohash/64/pgtable.h |=C2=A0=C2=A03 +-
> =C2=A0arch/powerpc/mm/pgtable-book3s64.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A02 +-
> =C2=A0arch/powerpc/mm/pgtable.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0|=C2=A0=C2=A02 +-
> =C2=A07 files changed, 71 insertions(+), 22 deletions(-)
>=20
> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h b/arch/powerpc/=
include/asm/book3s/32/pgtable.h
> index 38b33dcfcc9d..6b8b2d57fdc8 100644
> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h
> @@ -223,7 +223,8 @@ static inline void huge_ptep_set_wrprotect(struct mm_=
struct *mm,
> =C2=A0}
> =C2=A0
> =C2=A0
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	unsigned long set =3D pte_val(entry) &
> =C2=A0		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/=
include/asm/book3s/64/pgtable.h
> index 263bf39ced40..8ec8be9495ba 100644
> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h
> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
> @@ -565,10 +565,11 @@ static inline bool check_pte_access(unsigned long a=
ccess, unsigned long ptev)
> =C2=A0 * Generic functions with hash/radix callbacks
> =C2=A0 */
> =C2=A0
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	if (radix_enabled())
> -		return radix__ptep_set_access_flags(ptep, entry);
> +		return radix__ptep_set_access_flags(mm, ptep, entry);
> =C2=A0	return hash__ptep_set_access_flags(ptep, entry);
> =C2=A0}
> =C2=A0
> diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/in=
clude/asm/book3s/64/radix.h
> index a2fe8fbfbd3d..2a46dea8e1b1 100644
> --- a/arch/powerpc/include/asm/book3s/64/radix.h
> +++ b/arch/powerpc/include/asm/book3s/64/radix.h
> @@ -11,6 +11,11 @@
> =C2=A0#include=20
> =C2=A0#endif
> =C2=A0
> +#ifndef __ASSEMBLY__
> +#include=20
> +#include=20
> +#endif
> +
> =C2=A0/* An empty PTE can still have a R or C writeback */
> =C2=A0#define RADIX_PTE_NONE_MASK		(_PAGE_DIRTY | _PAGE_ACCESSED)
> =C2=A0
> @@ -105,11 +110,8 @@
> =C2=A0#define RADIX_PUD_TABLE_SIZE	(sizeof(pud_t) << RADIX_PUD_INDEX_SIZE=
)
> =C2=A0#define RADIX_PGD_TABLE_SIZE	(sizeof(pgd_t) << RADIX_PGD_INDEX_SIZE=
)
> =C2=A0
> -static inline unsigned long radix__pte_update(struct mm_struct *mm,
> -					unsigned long addr,
> -					pte_t *ptep, unsigned long clr,
> -					unsigned long set,
> -					int huge)
> +static inline unsigned long __radix_pte_update(pte_t *ptep, unsigned lon=
g clr,
> +					=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0unsigned long set)
> =C2=A0{
> =C2=A0	pte_t pte;
> =C2=A0	unsigned long old_pte, new_pte;
> @@ -121,9 +123,39 @@ static inline unsigned long radix__pte_update(struct=
 mm_struct *mm,
> =C2=A0
> =C2=A0	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
> =C2=A0
> -	/* We already do a sync in cmpxchg, is ptesync needed ?*/
> +	return old_pte;
> +}
> +
> +
> +static inline unsigned long radix__pte_update(struct mm_struct *mm,
> +					unsigned long addr,
> +					pte_t *ptep, unsigned long clr,
> +					unsigned long set,
> +					int huge)
> +{
> +	unsigned long old_pte;
> +
> +	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
> +
> +		unsigned long new_pte;
> +
> +		old_pte =3D __radix_pte_update(ptep, ~0, 0);
> +		asm volatile("ptesync" : : : "memory");
> +		/*
> +		=C2=A0* new value of pte
> +		=C2=A0*/
> +		new_pte =3D (old_pte | set) & ~clr;
> +
> +		/*
> +		=C2=A0* For now let's do heavy pid flush
> +		=C2=A0* radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
> +		=C2=A0*/
> +		radix__flush_tlb_mm(mm);
> +
> +		__radix_pte_update(ptep, 0, new_pte);
> +	} else
> +		old_pte =3D __radix_pte_update(ptep, clr, set);
> =C2=A0	asm volatile("ptesync" : : : "memory");
> -	/* huge pages use the old page table lock */
> =C2=A0	if (!huge)
> =C2=A0		assert_pte_locked(mm, addr);
> =C2=A0
> @@ -134,20 +166,33 @@ static inline unsigned long radix__pte_update(struc=
t mm_struct *mm,
> =C2=A0 * Set the dirty and/or accessed bits atomically in a linux PTE, th=
is
> =C2=A0 * function doesn't need to invalidate tlb.
> =C2=A0 */
> -static inline void radix__ptep_set_access_flags(pte_t *ptep, pte_t entry=
)
> +static inline void radix__ptep_set_access_flags(struct mm_struct *mm,
> +						pte_t *ptep, pte_t entry)
> =C2=A0{
> -	pte_t pte;
> -	unsigned long old_pte, new_pte;
> +
> =C2=A0	unsigned long set =3D pte_val(entry) & (_PAGE_DIRTY | _PAGE_ACCESS=
ED |
> =C2=A0					=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0_PAGE_RW | _PAGE_EXEC);
> -	do {
> -		pte =3D READ_ONCE(*ptep);
> -		old_pte =3D pte_val(pte);
> +
> +	if (cpu_has_feature(CPU_FTR_POWER9_DD1)) {
> +
> +		unsigned long old_pte, new_pte;
> +
> +		old_pte =3D __radix_pte_update(ptep, ~0, 0);
> +		asm volatile("ptesync" : : : "memory");
> +		/*
> +		=C2=A0* new value of pte
> +		=C2=A0*/
> =C2=A0		new_pte =3D old_pte | set;
> =C2=A0
> -	} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
> +		/*
> +		=C2=A0* For now let's do heavy pid flush
> +		=C2=A0* radix__flush_tlb_page_psize(mm, addr, mmu_virtual_psize);
> +		=C2=A0*/
> +		radix__flush_tlb_mm(mm);
> =C2=A0
> -	/* We already do a sync in cmpxchg, is ptesync needed ?*/
> +		__radix_pte_update(ptep, 0, new_pte);
> +	} else
> +		__radix_pte_update(ptep, 0, set);
> =C2=A0	asm volatile("ptesync" : : : "memory");
> =C2=A0}
> =C2=A0
> diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/=
include/asm/nohash/32/pgtable.h
> index 780847597514..c219ef7be53b 100644
> --- a/arch/powerpc/include/asm/nohash/32/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
> @@ -267,7 +267,8 @@ static inline void huge_ptep_set_wrprotect(struct mm_=
struct *mm,
> =C2=A0}
> =C2=A0
> =C2=A0
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	unsigned long set =3D pte_val(entry) &
> =C2=A0		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
> diff --git a/arch/powerpc/include/asm/nohash/64/pgtable.h b/arch/powerpc/=
include/asm/nohash/64/pgtable.h
> index d4d808cf905e..653a1838469d 100644
> --- a/arch/powerpc/include/asm/nohash/64/pgtable.h
> +++ b/arch/powerpc/include/asm/nohash/64/pgtable.h
> @@ -300,7 +300,8 @@ static inline void pte_clear(struct mm_struct *mm, un=
signed long addr,
> =C2=A0/* Set the dirty and/or accessed bits atomically in a linux PTE, th=
is
> =C2=A0 * function doesn't need to flush the hash entry
> =C2=A0 */
> -static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
> +static inline void __ptep_set_access_flags(struct mm_struct *mm,
> +					=C2=A0=C2=A0=C2=A0pte_t *ptep, pte_t entry)
> =C2=A0{
> =C2=A0	unsigned long bits =3D pte_val(entry) &
> =C2=A0		(_PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_RW | _PAGE_EXEC);
> diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable=
-book3s64.c
> index 34079302cc17..7328886bca4c 100644
> --- a/arch/powerpc/mm/pgtable-book3s64.c
> +++ b/arch/powerpc/mm/pgtable-book3s64.c
> @@ -35,7 +35,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, u=
nsigned long address,
> =C2=A0#endif
> =C2=A0	changed =3D !pmd_same(*(pmdp), entry);
> =C2=A0	if (changed) {
> -		__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
> +		__ptep_set_access_flags(vma->vm_mm, pmdp_ptep(pmdp), pmd_pte(entry));
> =C2=A0		flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
> =C2=A0	}
> =C2=A0	return changed;
> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index 0b6fb244d0a1..911fdfb63ec1 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -224,7 +224,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,=
 unsigned long address,
> =C2=A0	if (changed) {
> =C2=A0		if (!is_vm_hugetlb_page(vma))
> =C2=A0			assert_pte_locked(vma->vm_mm, address);
> -		__ptep_set_access_flags(ptep, entry);
> +		__ptep_set_access_flags(vma->vm_mm, ptep, entry);
> =C2=A0		flush_tlb_page(vma, address);
> =C2=A0	}
> =C2=A0	return changed;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash
  2016-08-24  9:33 ` [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash Aneesh Kumar K.V
@ 2016-09-06  1:18   ` Michael Neuling
  0 siblings, 0 replies; 9+ messages in thread
From: Michael Neuling @ 2016-09-06  1:18 UTC (permalink / raw)
  To: Aneesh Kumar K.V, benh, paulus, mpe; +Cc: linuxppc-dev

On Wed, 2016-08-24 at 15:03 +0530, Aneesh Kumar K.V wrote:
> Power9 DD1 requires to update the hid0 register when switching from
> hash to radix.

One minor nit. =C2=A0This is bidirectional not just "hash to radix"

Could just be:

powerpc/mm: Update the HID bit when switching MMU modes

Power9 DD1 requires an update to the HID0 register when switching=C2=A0
MMU modes ie. radix <-> hash.

Otherwise...

> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>

Acked-by: Michael Neuling <mikey@neuling.org>

> ---
> =C2=A0arch/powerpc/include/asm/reg.h=C2=A0=C2=A0|=C2=A0=C2=A03 +++
> =C2=A0arch/powerpc/mm/hash_utils_64.c | 25 +++++++++++++++++++++++++
> =C2=A0arch/powerpc/mm/pgtable-radix.c | 28 ++++++++++++++++++++++++++++
> =C2=A03 files changed, 56 insertions(+)
>=20
> diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/re=
g.h
> index f69f40f1519a..9dddabc2fced 100644
> --- a/arch/powerpc/include/asm/reg.h
> +++ b/arch/powerpc/include/asm/reg.h
> @@ -475,6 +475,9 @@
> =C2=A0#define HID0_POWER8_1TO4LPAR	__MASK(51)
> =C2=A0#define HID0_POWER8_DYNLPARDIS	__MASK(48)
> =C2=A0
> +/* POWER9 HID0 bits */
> +#define HID0_POWER9_RADIX	__MASK(63 - 8)
> +
> =C2=A0#define SPRN_HID1	0x3F1		/* Hardware Implementation Register 1 */
> =C2=A0#ifdef CONFIG_6xx
> =C2=A0#define HID1_EMCP	(1<<31)		/* 7450 Machine Check Pin Enable */
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils=
_64.c
> index 0821556e16f4..35a6721b3d25 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -711,6 +711,29 @@ int remove_section_mapping(unsigned long start, unsi=
gned long end)
> =C2=A0}
> =C2=A0#endif /* CONFIG_MEMORY_HOTPLUG */
> =C2=A0
> +static void update_hid_for_hash(void)
> +{
> +	unsigned long hid0;
> +	unsigned long rb =3D 3UL << PPC_BITLSHIFT(53); /* IS =3D 3 */
> +
> +	asm volatile("ptesync": : :"memory");
> +	/* prs =3D 0, ric =3D 2, rs =3D 0, r =3D 1 is =3D 3 */
> +	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
> +		=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0: : "r"(rb), "i"(0), "i"(0), "i"(2), "r"=
(0) : "memory");
> +	asm volatile("eieio; tlbsync; ptesync; isync; slbia": : :"memory");
> +	/*
> +	=C2=A0* now switch the HID
> +	=C2=A0*/
> +	hid0=C2=A0=C2=A0=3D mfspr(SPRN_HID0);
> +	hid0 &=3D ~HID0_POWER9_RADIX;
> +	mtspr(SPRN_HID0, hid0);
> +	asm volatile("isync": : :"memory");
> +
> +	/* Wait for it to happen */
> +	while ((mfspr(SPRN_HID0) & HID0_POWER9_RADIX))
> +		cpu_relax();
> +}
> +
> =C2=A0static void __init hash_init_partition_table(phys_addr_t hash_table=
,
> =C2=A0					=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0unsigned long htab_size)
> =C2=A0{
> @@ -737,6 +760,8 @@ static void __init hash_init_partition_table(phys_add=
r_t hash_table,
> =C2=A0	=C2=A0*/
> =C2=A0	partition_tb->patb1 =3D 0;
> =C2=A0	pr_info("Partition table %p\n", partition_tb);
> +	if (cpu_has_feature(CPU_FTR_POWER9_DD1))
> +		update_hid_for_hash();
> =C2=A0	/*
> =C2=A0	=C2=A0* update partition table control register,
> =C2=A0	=C2=A0* 64 K size.
> diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-ra=
dix.c
> index af897d91d09f..8f086352e421 100644
> --- a/arch/powerpc/mm/pgtable-radix.c
> +++ b/arch/powerpc/mm/pgtable-radix.c
> @@ -294,6 +294,32 @@ found:
> =C2=A0	return;
> =C2=A0}
> =C2=A0
> +static void update_hid_for_radix(void)
> +{
> +	unsigned long hid0;
> +	unsigned long rb =3D 3UL << PPC_BITLSHIFT(53); /* IS =3D 3 */
> +
> +	asm volatile("ptesync": : :"memory");
> +	/* prs =3D 0, ric =3D 2, rs =3D 0, r =3D 1 is =3D 3 */
> +	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
> +		=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0: : "r"(rb), "i"(1), "i"(0), "i"(2), "r"=
(0) : "memory");
> +	/* prs =3D 1, ric =3D 2, rs =3D 0, r =3D 1 is =3D 3 */
> +	asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1)
> +		=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0: : "r"(rb), "i"(1), "i"(1), "i"(2), "r"=
(0) : "memory");
> +	asm volatile("eieio; tlbsync; ptesync; isync; slbia": : :"memory");
> +	/*
> +	=C2=A0* now switch the HID
> +	=C2=A0*/
> +	hid0=C2=A0=C2=A0=3D mfspr(SPRN_HID0);
> +	hid0 |=3D HID0_POWER9_RADIX;
> +	mtspr(SPRN_HID0, hid0);
> +	asm volatile("isync": : :"memory");
> +
> +	/* Wait for it to happen */
> +	while (!(mfspr(SPRN_HID0) & HID0_POWER9_RADIX))
> +		cpu_relax();
> +}
> +
> =C2=A0void __init radix__early_init_mmu(void)
> =C2=A0{
> =C2=A0	unsigned long lpcr;
> @@ -345,6 +371,8 @@ void __init radix__early_init_mmu(void)
> =C2=A0
> =C2=A0	if (!firmware_has_feature(FW_FEATURE_LPAR)) {
> =C2=A0		radix_init_native();
> +		if (cpu_has_feature(CPU_FTR_POWER9_DD1))
> +			update_hid_for_radix();
> =C2=A0		lpcr =3D mfspr(SPRN_LPCR);
> =C2=A0		mtspr(SPRN_LPCR, lpcr | LPCR_UPRT | LPCR_HR);
> =C2=A0		radix_init_partition_table();

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs
  2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
                   ` (3 preceding siblings ...)
  2016-09-06  1:10 ` [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Michael Neuling
@ 2016-09-13 12:16 ` Michael Ellerman
  4 siblings, 0 replies; 9+ messages in thread
From: Michael Ellerman @ 2016-09-13 12:16 UTC (permalink / raw)
  To: Aneesh Kumar K.V, benh, paulus; +Cc: linuxppc-dev, Aneesh Kumar K.V

On Wed, 2016-24-08 at 09:33:36 UTC, "Aneesh Kumar K.V" wrote:
> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> Acked-by: Michael Neuling <mikey@neuling.org>

Series applied to powerpc next, thanks.

https://git.kernel.org/powerpc/c/7dccfbc325bb59f94521d544a8

cheers

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-09-13 12:16 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-24  9:33 [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Aneesh Kumar K.V
2016-08-24  9:33 ` [PATCH 2/4] powerpc/mm/radix: Use different RTS encoding " Aneesh Kumar K.V
2016-09-06  1:11   ` Michael Neuling
2016-08-24  9:33 ` [PATCH 3/4] powerpc/mm/radix: Use different pte update sequence " Aneesh Kumar K.V
2016-09-06  1:12   ` Michael Neuling
2016-08-24  9:33 ` [PATCH 4/4] powerpc/mm: Update the HID bit when switching from radix to hash Aneesh Kumar K.V
2016-09-06  1:18   ` Michael Neuling
2016-09-06  1:10 ` [PATCH 1/4] powerpc/book3s: Add a cpu table entry for different POWER9 revs Michael Neuling
2016-09-13 12:16 ` [1/4] " Michael Ellerman

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.