* [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.