aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-03 17:20:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-03 17:20:22 -0400
commit5306d766f15e72bc79c61d88f77e5a6b1fcc0e68 (patch)
tree14798d3026bb8b168b7d55d6090acedd55f69e23
parent4340fa55298d17049e71c7a34e04647379c269f3 (diff)
parent7cc851039d643a2ee7df4d18177150f2c3a484f5 (diff)
Merge tag 'powerpc-4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - Handle RTAS delay requests in configure_bridge from Russell Currey - Refactor the configure_bridge RTAS tokens from Russell Currey - Fix definition of SIAR and SDAR registers from Thomas Huth - Use privileged SPR number for MMCR2 from Thomas Huth - Update LPCR only if it is powernv from Aneesh Kumar K.V - Fix the reference bit update when handling hash fault from Aneesh Kumar K.V - Add missing tlb flush from Aneesh Kumar K.V - Add POWER8NVL support to ibm,client-architecture-support call from Thomas Huth * tag 'powerpc-4.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/pseries: Add POWER8NVL support to ibm,client-architecture-support call powerpc/mm/radix: Add missing tlb flush powerpc/mm/hash: Fix the reference bit update when handling hash fault powerpc/mm/radix: Update LPCR only if it is powernv powerpc: Use privileged SPR number for MMCR2 powerpc: Fix definition of SIAR and SDAR registers powerpc/pseries/eeh: Refactor the configure_bridge RTAS tokens powerpc/pseries/eeh: Handle RTAS delay requests in configure_bridge
-rw-r--r--arch/powerpc/include/asm/reg.h6
-rw-r--r--arch/powerpc/kernel/prom_init.c1
-rw-r--r--arch/powerpc/mm/hash_utils_64.c22
-rw-r--r--arch/powerpc/mm/pgtable-book3s64.c5
-rw-r--r--arch/powerpc/mm/pgtable-radix.c23
-rw-r--r--arch/powerpc/platforms/pseries/eeh_pseries.c49
6 files changed, 68 insertions, 38 deletions
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index c1e82e968506..a0948f40bc7b 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -717,7 +717,7 @@
717#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */ 717#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
718#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */ 718#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
719#define SPRN_MMCR1 798 719#define SPRN_MMCR1 798
720#define SPRN_MMCR2 769 720#define SPRN_MMCR2 785
721#define SPRN_MMCRA 0x312 721#define SPRN_MMCRA 0x312
722#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */ 722#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
723#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL 723#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
@@ -754,13 +754,13 @@
754#define SPRN_PMC6 792 754#define SPRN_PMC6 792
755#define SPRN_PMC7 793 755#define SPRN_PMC7 793
756#define SPRN_PMC8 794 756#define SPRN_PMC8 794
757#define SPRN_SIAR 780
758#define SPRN_SDAR 781
759#define SPRN_SIER 784 757#define SPRN_SIER 784
760#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */ 758#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
761#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */ 759#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
762#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */ 760#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
763#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */ 761#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
762#define SPRN_SIAR 796
763#define SPRN_SDAR 797
764#define SPRN_TACR 888 764#define SPRN_TACR 888
765#define SPRN_TCSCR 889 765#define SPRN_TCSCR 889
766#define SPRN_CSIGR 890 766#define SPRN_CSIGR 890
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index da5192590c44..ccd2037c797f 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -656,6 +656,7 @@ unsigned char ibm_architecture_vec[] = {
656 W(0xffff0000), W(0x003e0000), /* POWER6 */ 656 W(0xffff0000), W(0x003e0000), /* POWER6 */
657 W(0xffff0000), W(0x003f0000), /* POWER7 */ 657 W(0xffff0000), W(0x003f0000), /* POWER7 */
658 W(0xffff0000), W(0x004b0000), /* POWER8E */ 658 W(0xffff0000), W(0x004b0000), /* POWER8E */
659 W(0xffff0000), W(0x004c0000), /* POWER8NVL */
659 W(0xffff0000), W(0x004d0000), /* POWER8 */ 660 W(0xffff0000), W(0x004d0000), /* POWER8 */
660 W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */ 661 W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
661 W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */ 662 W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 59268969a0bc..b2740c67e172 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -159,6 +159,19 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
159 }, 159 },
160}; 160};
161 161
162/*
163 * 'R' and 'C' update notes:
164 * - Under pHyp or KVM, the updatepp path will not set C, thus it *will*
165 * create writeable HPTEs without C set, because the hcall H_PROTECT
166 * that we use in that case will not update C
167 * - The above is however not a problem, because we also don't do that
168 * fancy "no flush" variant of eviction and we use H_REMOVE which will
169 * do the right thing and thus we don't have the race I described earlier
170 *
171 * - Under bare metal, we do have the race, so we need R and C set
172 * - We make sure R is always set and never lost
173 * - C is _PAGE_DIRTY, and *should* always be set for a writeable mapping
174 */
162unsigned long htab_convert_pte_flags(unsigned long pteflags) 175unsigned long htab_convert_pte_flags(unsigned long pteflags)
163{ 176{
164 unsigned long rflags = 0; 177 unsigned long rflags = 0;
@@ -186,9 +199,14 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
186 rflags |= 0x1; 199 rflags |= 0x1;
187 } 200 }
188 /* 201 /*
189 * Always add "C" bit for perf. Memory coherence is always enabled 202 * We can't allow hardware to update hpte bits. Hence always
203 * set 'R' bit and set 'C' if it is a write fault
204 * Memory coherence is always enabled
190 */ 205 */
191 rflags |= HPTE_R_C | HPTE_R_M; 206 rflags |= HPTE_R_R | HPTE_R_M;
207
208 if (pteflags & _PAGE_DIRTY)
209 rflags |= HPTE_R_C;
192 /* 210 /*
193 * Add in WIG bits 211 * Add in WIG bits
194 */ 212 */
diff --git a/arch/powerpc/mm/pgtable-book3s64.c b/arch/powerpc/mm/pgtable-book3s64.c
index eb4451144746..670318766545 100644
--- a/arch/powerpc/mm/pgtable-book3s64.c
+++ b/arch/powerpc/mm/pgtable-book3s64.c
@@ -33,10 +33,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
33 changed = !pmd_same(*(pmdp), entry); 33 changed = !pmd_same(*(pmdp), entry);
34 if (changed) { 34 if (changed) {
35 __ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry)); 35 __ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
36 /* 36 flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
37 * Since we are not supporting SW TLB systems, we don't
38 * have any thing similar to flush_tlb_page_nohash()
39 */
40 } 37 }
41 return changed; 38 return changed;
42} 39}
diff --git a/arch/powerpc/mm/pgtable-radix.c b/arch/powerpc/mm/pgtable-radix.c
index 18b2c11604fa..c939e6e57a9e 100644
--- a/arch/powerpc/mm/pgtable-radix.c
+++ b/arch/powerpc/mm/pgtable-radix.c
@@ -296,11 +296,6 @@ found:
296void __init radix__early_init_mmu(void) 296void __init radix__early_init_mmu(void)
297{ 297{
298 unsigned long lpcr; 298 unsigned long lpcr;
299 /*
300 * setup LPCR UPRT based on mmu_features
301 */
302 lpcr = mfspr(SPRN_LPCR);
303 mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
304 299
305#ifdef CONFIG_PPC_64K_PAGES 300#ifdef CONFIG_PPC_64K_PAGES
306 /* PAGE_SIZE mappings */ 301 /* PAGE_SIZE mappings */
@@ -343,8 +338,11 @@ void __init radix__early_init_mmu(void)
343 __pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT; 338 __pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
344 339
345 radix_init_page_sizes(); 340 radix_init_page_sizes();
346 if (!firmware_has_feature(FW_FEATURE_LPAR)) 341 if (!firmware_has_feature(FW_FEATURE_LPAR)) {
342 lpcr = mfspr(SPRN_LPCR);
343 mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
347 radix_init_partition_table(); 344 radix_init_partition_table();
345 }
348 346
349 radix_init_pgtable(); 347 radix_init_pgtable();
350} 348}
@@ -353,16 +351,15 @@ void radix__early_init_mmu_secondary(void)
353{ 351{
354 unsigned long lpcr; 352 unsigned long lpcr;
355 /* 353 /*
356 * setup LPCR UPRT based on mmu_features 354 * update partition table control register and UPRT
357 */ 355 */
358 lpcr = mfspr(SPRN_LPCR); 356 if (!firmware_has_feature(FW_FEATURE_LPAR)) {
359 mtspr(SPRN_LPCR, lpcr | LPCR_UPRT); 357 lpcr = mfspr(SPRN_LPCR);
360 /* 358 mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
361 * update partition table control register, 64 K size. 359
362 */
363 if (!firmware_has_feature(FW_FEATURE_LPAR))
364 mtspr(SPRN_PTCR, 360 mtspr(SPRN_PTCR,
365 __pa(partition_tb) | (PATB_SIZE_SHIFT - 12)); 361 __pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
362 }
366} 363}
367 364
368void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base, 365void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
index ac3ffd97e059..3998e0f9a03b 100644
--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
+++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
@@ -53,7 +53,6 @@ static int ibm_read_slot_reset_state2;
53static int ibm_slot_error_detail; 53static int ibm_slot_error_detail;
54static int ibm_get_config_addr_info; 54static int ibm_get_config_addr_info;
55static int ibm_get_config_addr_info2; 55static int ibm_get_config_addr_info2;
56static int ibm_configure_bridge;
57static int ibm_configure_pe; 56static int ibm_configure_pe;
58 57
59/* 58/*
@@ -81,7 +80,14 @@ static int pseries_eeh_init(void)
81 ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2"); 80 ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
82 ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info"); 81 ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
83 ibm_configure_pe = rtas_token("ibm,configure-pe"); 82 ibm_configure_pe = rtas_token("ibm,configure-pe");
84 ibm_configure_bridge = rtas_token("ibm,configure-bridge"); 83
84 /*
85 * ibm,configure-pe and ibm,configure-bridge have the same semantics,
86 * however ibm,configure-pe can be faster. If we can't find
87 * ibm,configure-pe then fall back to using ibm,configure-bridge.
88 */
89 if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
90 ibm_configure_pe = rtas_token("ibm,configure-bridge");
85 91
86 /* 92 /*
87 * Necessary sanity check. We needn't check "get-config-addr-info" 93 * Necessary sanity check. We needn't check "get-config-addr-info"
@@ -93,8 +99,7 @@ static int pseries_eeh_init(void)
93 (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE && 99 (ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
94 ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) || 100 ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
95 ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE || 101 ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
96 (ibm_configure_pe == RTAS_UNKNOWN_SERVICE && 102 ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
97 ibm_configure_bridge == RTAS_UNKNOWN_SERVICE)) {
98 pr_info("EEH functionality not supported\n"); 103 pr_info("EEH functionality not supported\n");
99 return -EINVAL; 104 return -EINVAL;
100 } 105 }
@@ -615,29 +620,41 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
615{ 620{
616 int config_addr; 621 int config_addr;
617 int ret; 622 int ret;
623 /* Waiting 0.2s maximum before skipping configuration */
624 int max_wait = 200;
618 625
619 /* Figure out the PE address */ 626 /* Figure out the PE address */
620 config_addr = pe->config_addr; 627 config_addr = pe->config_addr;
621 if (pe->addr) 628 if (pe->addr)
622 config_addr = pe->addr; 629 config_addr = pe->addr;
623 630
624 /* Use new configure-pe function, if supported */ 631 while (max_wait > 0) {
625 if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
626 ret = rtas_call(ibm_configure_pe, 3, 1, NULL, 632 ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
627 config_addr, BUID_HI(pe->phb->buid), 633 config_addr, BUID_HI(pe->phb->buid),
628 BUID_LO(pe->phb->buid)); 634 BUID_LO(pe->phb->buid));
629 } else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
630 ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
631 config_addr, BUID_HI(pe->phb->buid),
632 BUID_LO(pe->phb->buid));
633 } else {
634 return -EFAULT;
635 }
636 635
637 if (ret) 636 if (!ret)
638 pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n", 637 return ret;
639 __func__, pe->phb->global_number, pe->addr, ret); 638
639 /*
640 * If RTAS returns a delay value that's above 100ms, cut it
641 * down to 100ms in case firmware made a mistake. For more
642 * on how these delay values work see rtas_busy_delay_time
643 */
644 if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
645 ret <= RTAS_EXTENDED_DELAY_MAX)
646 ret = RTAS_EXTENDED_DELAY_MIN+2;
647
648 max_wait -= rtas_busy_delay_time(ret);
649
650 if (max_wait < 0)
651 break;
652
653 rtas_busy_delay(ret);
654 }
640 655
656 pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
657 __func__, pe->phb->global_number, pe->addr, ret);
641 return ret; 658 return ret;
642} 659}
643 660