powerpc fixes for 4.7
- 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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXUWmzAAoJEFHr6jzI4aWAuEAQAKAWjT4JCIQMzc2Qk0LbBFhD Mw3xIt618g0PLRLN431rqk9xE1phh9ecSNt40kQV0UYypCwQyYaOzAAHq7QibRFh wFDLyrO10aiqTVBI9Dl7l6ZDespGP4ufOyj4GF3vIndTQ8CLT6+Jj/cfaT8lNIna vOp0Q8RKoSuqJu7wOZwxGHc9vhdpDftBOi2Yl2KHWrWUMTVtyDzgRwmFiCk/9SvX +xYVGfbCRkU1b05X9RgbsbMdiAzC7odzAC8e4VNHqB+YHgBFenlOKcx6uuz5Oubv /0dGJq1OEKxKgkEWZsXMhfcezI1i6H1qa5gwqO2pJn/mQiWUx/IxxC5j1tGMcgXJ tU4cJtMccUmB22bOTqJsGhQJyHh09UDql2PIAHdvTZplYBj34R+2fr6LMRC5TUyY yXsk/26CAh1ihPK8juytK8D2f7CfFJVe96HXMz8yGWNy2MeaJHh3Nz7E2/hA6L6B GzT08EBGmGU/1/L4xJi1uuRLQXMgvWkuo0C65m9jqFah7y82gHetypTBSbLOBcUX +pJRcWouZlksbEHydMlbvNrqmJz1zPx9JJFJJrfDzkYUB/O61NxOpaQPZHfhMt01 Bd8n0wt7OPW9bZL9WrW5W11OhOxNZfuxcr5GmVnzsaALPazFThQm1gZH2NOp6Wr/ 9aWy/lZAuDOrtOnmfcZm =OkUs -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
5306d766f1
@ -717,7 +717,7 @@
|
|||||||
#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
|
#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
|
||||||
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
||||||
#define SPRN_MMCR1 798
|
#define SPRN_MMCR1 798
|
||||||
#define SPRN_MMCR2 769
|
#define SPRN_MMCR2 785
|
||||||
#define SPRN_MMCRA 0x312
|
#define SPRN_MMCRA 0x312
|
||||||
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
||||||
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
|
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
|
||||||
@ -754,13 +754,13 @@
|
|||||||
#define SPRN_PMC6 792
|
#define SPRN_PMC6 792
|
||||||
#define SPRN_PMC7 793
|
#define SPRN_PMC7 793
|
||||||
#define SPRN_PMC8 794
|
#define SPRN_PMC8 794
|
||||||
#define SPRN_SIAR 780
|
|
||||||
#define SPRN_SDAR 781
|
|
||||||
#define SPRN_SIER 784
|
#define SPRN_SIER 784
|
||||||
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
|
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
|
||||||
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
|
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
|
||||||
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
|
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
|
||||||
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
|
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
|
||||||
|
#define SPRN_SIAR 796
|
||||||
|
#define SPRN_SDAR 797
|
||||||
#define SPRN_TACR 888
|
#define SPRN_TACR 888
|
||||||
#define SPRN_TCSCR 889
|
#define SPRN_TCSCR 889
|
||||||
#define SPRN_CSIGR 890
|
#define SPRN_CSIGR 890
|
||||||
|
@ -656,6 +656,7 @@ unsigned char ibm_architecture_vec[] = {
|
|||||||
W(0xffff0000), W(0x003e0000), /* POWER6 */
|
W(0xffff0000), W(0x003e0000), /* POWER6 */
|
||||||
W(0xffff0000), W(0x003f0000), /* POWER7 */
|
W(0xffff0000), W(0x003f0000), /* POWER7 */
|
||||||
W(0xffff0000), W(0x004b0000), /* POWER8E */
|
W(0xffff0000), W(0x004b0000), /* POWER8E */
|
||||||
|
W(0xffff0000), W(0x004c0000), /* POWER8NVL */
|
||||||
W(0xffff0000), W(0x004d0000), /* POWER8 */
|
W(0xffff0000), W(0x004d0000), /* POWER8 */
|
||||||
W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
|
W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
|
||||||
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
|
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
|
||||||
|
@ -159,6 +159,19 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'R' and 'C' update notes:
|
||||||
|
* - Under pHyp or KVM, the updatepp path will not set C, thus it *will*
|
||||||
|
* create writeable HPTEs without C set, because the hcall H_PROTECT
|
||||||
|
* that we use in that case will not update C
|
||||||
|
* - The above is however not a problem, because we also don't do that
|
||||||
|
* fancy "no flush" variant of eviction and we use H_REMOVE which will
|
||||||
|
* do the right thing and thus we don't have the race I described earlier
|
||||||
|
*
|
||||||
|
* - Under bare metal, we do have the race, so we need R and C set
|
||||||
|
* - We make sure R is always set and never lost
|
||||||
|
* - C is _PAGE_DIRTY, and *should* always be set for a writeable mapping
|
||||||
|
*/
|
||||||
unsigned long htab_convert_pte_flags(unsigned long pteflags)
|
unsigned long htab_convert_pte_flags(unsigned long pteflags)
|
||||||
{
|
{
|
||||||
unsigned long rflags = 0;
|
unsigned long rflags = 0;
|
||||||
@ -186,9 +199,14 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
|
|||||||
rflags |= 0x1;
|
rflags |= 0x1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Always add "C" bit for perf. Memory coherence is always enabled
|
* We can't allow hardware to update hpte bits. Hence always
|
||||||
|
* set 'R' bit and set 'C' if it is a write fault
|
||||||
|
* Memory coherence is always enabled
|
||||||
*/
|
*/
|
||||||
rflags |= HPTE_R_C | HPTE_R_M;
|
rflags |= HPTE_R_R | HPTE_R_M;
|
||||||
|
|
||||||
|
if (pteflags & _PAGE_DIRTY)
|
||||||
|
rflags |= HPTE_R_C;
|
||||||
/*
|
/*
|
||||||
* Add in WIG bits
|
* Add in WIG bits
|
||||||
*/
|
*/
|
||||||
|
@ -33,10 +33,7 @@ int pmdp_set_access_flags(struct vm_area_struct *vma, unsigned long address,
|
|||||||
changed = !pmd_same(*(pmdp), entry);
|
changed = !pmd_same(*(pmdp), entry);
|
||||||
if (changed) {
|
if (changed) {
|
||||||
__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
|
__ptep_set_access_flags(pmdp_ptep(pmdp), pmd_pte(entry));
|
||||||
/*
|
flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
|
||||||
* Since we are not supporting SW TLB systems, we don't
|
|
||||||
* have any thing similar to flush_tlb_page_nohash()
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
@ -296,11 +296,6 @@ found:
|
|||||||
void __init radix__early_init_mmu(void)
|
void __init radix__early_init_mmu(void)
|
||||||
{
|
{
|
||||||
unsigned long lpcr;
|
unsigned long lpcr;
|
||||||
/*
|
|
||||||
* setup LPCR UPRT based on mmu_features
|
|
||||||
*/
|
|
||||||
lpcr = mfspr(SPRN_LPCR);
|
|
||||||
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_64K_PAGES
|
#ifdef CONFIG_PPC_64K_PAGES
|
||||||
/* PAGE_SIZE mappings */
|
/* PAGE_SIZE mappings */
|
||||||
@ -343,8 +338,11 @@ void __init radix__early_init_mmu(void)
|
|||||||
__pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
|
__pte_frag_size_shift = H_PTE_FRAG_SIZE_SHIFT;
|
||||||
|
|
||||||
radix_init_page_sizes();
|
radix_init_page_sizes();
|
||||||
if (!firmware_has_feature(FW_FEATURE_LPAR))
|
if (!firmware_has_feature(FW_FEATURE_LPAR)) {
|
||||||
|
lpcr = mfspr(SPRN_LPCR);
|
||||||
|
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
|
||||||
radix_init_partition_table();
|
radix_init_partition_table();
|
||||||
|
}
|
||||||
|
|
||||||
radix_init_pgtable();
|
radix_init_pgtable();
|
||||||
}
|
}
|
||||||
@ -353,17 +351,16 @@ void radix__early_init_mmu_secondary(void)
|
|||||||
{
|
{
|
||||||
unsigned long lpcr;
|
unsigned long lpcr;
|
||||||
/*
|
/*
|
||||||
* setup LPCR UPRT based on mmu_features
|
* update partition table control register and UPRT
|
||||||
*/
|
*/
|
||||||
|
if (!firmware_has_feature(FW_FEATURE_LPAR)) {
|
||||||
lpcr = mfspr(SPRN_LPCR);
|
lpcr = mfspr(SPRN_LPCR);
|
||||||
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
|
mtspr(SPRN_LPCR, lpcr | LPCR_UPRT);
|
||||||
/*
|
|
||||||
* update partition table control register, 64 K size.
|
|
||||||
*/
|
|
||||||
if (!firmware_has_feature(FW_FEATURE_LPAR))
|
|
||||||
mtspr(SPRN_PTCR,
|
mtspr(SPRN_PTCR,
|
||||||
__pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
|
__pa(partition_tb) | (PATB_SIZE_SHIFT - 12));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
||||||
phys_addr_t first_memblock_size)
|
phys_addr_t first_memblock_size)
|
||||||
|
@ -53,7 +53,6 @@ static int ibm_read_slot_reset_state2;
|
|||||||
static int ibm_slot_error_detail;
|
static int ibm_slot_error_detail;
|
||||||
static int ibm_get_config_addr_info;
|
static int ibm_get_config_addr_info;
|
||||||
static int ibm_get_config_addr_info2;
|
static int ibm_get_config_addr_info2;
|
||||||
static int ibm_configure_bridge;
|
|
||||||
static int ibm_configure_pe;
|
static int ibm_configure_pe;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -81,7 +80,14 @@ static int pseries_eeh_init(void)
|
|||||||
ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
|
ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
|
||||||
ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
|
ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
|
||||||
ibm_configure_pe = rtas_token("ibm,configure-pe");
|
ibm_configure_pe = rtas_token("ibm,configure-pe");
|
||||||
ibm_configure_bridge = rtas_token("ibm,configure-bridge");
|
|
||||||
|
/*
|
||||||
|
* ibm,configure-pe and ibm,configure-bridge have the same semantics,
|
||||||
|
* however ibm,configure-pe can be faster. If we can't find
|
||||||
|
* ibm,configure-pe then fall back to using ibm,configure-bridge.
|
||||||
|
*/
|
||||||
|
if (ibm_configure_pe == RTAS_UNKNOWN_SERVICE)
|
||||||
|
ibm_configure_pe = rtas_token("ibm,configure-bridge");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Necessary sanity check. We needn't check "get-config-addr-info"
|
* Necessary sanity check. We needn't check "get-config-addr-info"
|
||||||
@ -93,8 +99,7 @@ static int pseries_eeh_init(void)
|
|||||||
(ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
|
(ibm_read_slot_reset_state2 == RTAS_UNKNOWN_SERVICE &&
|
||||||
ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
|
ibm_read_slot_reset_state == RTAS_UNKNOWN_SERVICE) ||
|
||||||
ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
|
ibm_slot_error_detail == RTAS_UNKNOWN_SERVICE ||
|
||||||
(ibm_configure_pe == RTAS_UNKNOWN_SERVICE &&
|
ibm_configure_pe == RTAS_UNKNOWN_SERVICE) {
|
||||||
ibm_configure_bridge == RTAS_UNKNOWN_SERVICE)) {
|
|
||||||
pr_info("EEH functionality not supported\n");
|
pr_info("EEH functionality not supported\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@ -615,29 +620,41 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
|
|||||||
{
|
{
|
||||||
int config_addr;
|
int config_addr;
|
||||||
int ret;
|
int ret;
|
||||||
|
/* Waiting 0.2s maximum before skipping configuration */
|
||||||
|
int max_wait = 200;
|
||||||
|
|
||||||
/* Figure out the PE address */
|
/* Figure out the PE address */
|
||||||
config_addr = pe->config_addr;
|
config_addr = pe->config_addr;
|
||||||
if (pe->addr)
|
if (pe->addr)
|
||||||
config_addr = pe->addr;
|
config_addr = pe->addr;
|
||||||
|
|
||||||
/* Use new configure-pe function, if supported */
|
while (max_wait > 0) {
|
||||||
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
|
|
||||||
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
|
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
|
||||||
config_addr, BUID_HI(pe->phb->buid),
|
config_addr, BUID_HI(pe->phb->buid),
|
||||||
BUID_LO(pe->phb->buid));
|
BUID_LO(pe->phb->buid));
|
||||||
} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
|
|
||||||
ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
|
if (!ret)
|
||||||
config_addr, BUID_HI(pe->phb->buid),
|
return ret;
|
||||||
BUID_LO(pe->phb->buid));
|
|
||||||
} else {
|
/*
|
||||||
return -EFAULT;
|
* If RTAS returns a delay value that's above 100ms, cut it
|
||||||
|
* down to 100ms in case firmware made a mistake. For more
|
||||||
|
* on how these delay values work see rtas_busy_delay_time
|
||||||
|
*/
|
||||||
|
if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
|
||||||
|
ret <= RTAS_EXTENDED_DELAY_MAX)
|
||||||
|
ret = RTAS_EXTENDED_DELAY_MIN+2;
|
||||||
|
|
||||||
|
max_wait -= rtas_busy_delay_time(ret);
|
||||||
|
|
||||||
|
if (max_wait < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
rtas_busy_delay(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
|
||||||
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
|
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
|
||||||
__func__, pe->phb->global_number, pe->addr, ret);
|
__func__, pe->phb->global_number, pe->addr, ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user