Skip to content

Commit 5306d76

Browse files
committed
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
2 parents 4340fa5 + 7cc8510 commit 5306d76

File tree

6 files changed

+68
-38
lines changed

6 files changed

+68
-38
lines changed

arch/powerpc/include/asm/reg.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@
717717
#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
718718
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
719719
#define SPRN_MMCR1 798
720-
#define SPRN_MMCR2 769
720+
#define SPRN_MMCR2 785
721721
#define SPRN_MMCRA 0x312
722722
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
723723
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
@@ -754,13 +754,13 @@
754754
#define SPRN_PMC6 792
755755
#define SPRN_PMC7 793
756756
#define SPRN_PMC8 794
757-
#define SPRN_SIAR 780
758-
#define SPRN_SDAR 781
759757
#define SPRN_SIER 784
760758
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
761759
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
762760
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
763761
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
762+
#define SPRN_SIAR 796
763+
#define SPRN_SDAR 797
764764
#define SPRN_TACR 888
765765
#define SPRN_TCSCR 889
766766
#define SPRN_CSIGR 890

arch/powerpc/kernel/prom_init.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ unsigned char ibm_architecture_vec[] = {
656656
W(0xffff0000), W(0x003e0000), /* POWER6 */
657657
W(0xffff0000), W(0x003f0000), /* POWER7 */
658658
W(0xffff0000), W(0x004b0000), /* POWER8E */
659+
W(0xffff0000), W(0x004c0000), /* POWER8NVL */
659660
W(0xffff0000), W(0x004d0000), /* POWER8 */
660661
W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
661662
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */

arch/powerpc/mm/hash_utils_64.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,19 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
159159
},
160160
};
161161

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+
*/
162175
unsigned long htab_convert_pte_flags(unsigned long pteflags)
163176
{
164177
unsigned long rflags = 0;
@@ -186,9 +199,14 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
186199
rflags |= 0x1;
187200
}
188201
/*
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
190205
*/
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;
192210
/*
193211
* Add in WIG bits
194212
*/

arch/powerpc/mm/pgtable-book3s64.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
3333
changed = !pmd_same(*(pmdp), entry);
3434
if (changed) {
3535
__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
36-
/*
37-
* Since we are not supporting SW TLB systems, we don't
38-
* have any thing similar to flush_tlb_page_nohash()
39-
*/
36+
flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
4037
}
4138
return changed;
4239
}

arch/powerpc/mm/pgtable-radix.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -296,11 +296,6 @@ static void __init radix_init_page_sizes(void)
296296
void __init radix__early_init_mmu(void)
297297
{
298298
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);
304299

305300
#ifdef CONFIG_PPC_64K_PAGES
306301
/* PAGE_SIZE mappings */
@@ -343,8 +338,11 @@ void __init radix__early_init_mmu(void)
343338
__pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
344339

345340
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);
347344
radix_init_partition_table();
345+
}
348346

349347
radix_init_pgtable();
350348
}
@@ -353,16 +351,15 @@ void radix__early_init_mmu_secondary(void)
353351
{
354352
unsigned long lpcr;
355353
/*
356-
* setup LPCR UPRT based on mmu_features
354+
* update partition table control register and UPRT
357355
*/
358-
lpcr = mfspr(SPRN_LPCR);
359-
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
360-
/*
361-
* update partition table control register, 64 K size.
362-
*/
363-
if (!firmware_has_feature(FW_FEATURE_LPAR))
356+
if (!firmware_has_feature(FW_FEATURE_LPAR)) {
357+
lpcr = mfspr(SPRN_LPCR);
358+
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
359+
364360
mtspr(SPRN_PTCR,
365361
__pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
362+
}
366363
}
367364

368365
void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,

arch/powerpc/platforms/pseries/eeh_pseries.c

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ static int ibm_read_slot_reset_state2;
5353
static int ibm_slot_error_detail;
5454
static int ibm_get_config_addr_info;
5555
static int ibm_get_config_addr_info2;
56-
static int ibm_configure_bridge;
5756
static int ibm_configure_pe;
5857

5958
/*
@@ -81,7 +80,14 @@ static int pseries_eeh_init(void)
8180
ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
8281
ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
8382
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");
8591

8692
/*
8793
* Necessary sanity check. We needn't check "get-config-addr-info"
@@ -93,8 +99,7 @@ static int pseries_eeh_init(void)
9399
(ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
94100
ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
95101
ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
96-
(ibm_configure_pe == RTAS_UNKNOWN_SERVICE &&
97-
ibm_configure_bridge == RTAS_UNKNOWN_SERVICE)) {
102+
ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
98103
pr_info("EEH functionality not supported\n");
99104
return -EINVAL;
100105
}
@@ -615,29 +620,41 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
615620
{
616621
int config_addr;
617622
int ret;
623+
/* Waiting 0.2s maximum before skipping configuration */
624+
int max_wait = 200;
618625

619626
/* Figure out the PE address */
620627
config_addr = pe->config_addr;
621628
if (pe->addr)
622629
config_addr = pe->addr;
623630

624-
/* Use new configure-pe function, if supported */
625-
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
631+
while (max_wait > 0) {
626632
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
627633
config_addr, BUID_HI(pe->phb->buid),
628634
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-
}
636635

637-
if (ret)
638-
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
639-
__func__, pe->phb->global_number, pe->addr, ret);
636+
if (!ret)
637+
return 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+
}
640655

656+
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
657+
__func__, pe->phb->global_number, pe->addr, ret);
641658
return ret;
642659
}
643660

0 commit comments

Comments
 (0)