[POWERPC] Add 1TB workaround for PA6T
PA6T has a bug where the slbie instruction does not honor the large segment bit. As a result, we have to always use slbia when switching context. We don't have to worry about changing the slbie's during fault processing, since they should never be replacing one VSID with another using the same ESID. I.e. there's no risk for inserting duplicate entries due to a failed slbie of the old entry. So as long as we clear it out on context switch we should be fine. Signed-off-by: Olof Johansson <olof@lixom.net> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Родитель
8129535b6b
Коммит
f66bce5e6a
|
@ -408,6 +408,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
|
||||||
std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
|
std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
|
||||||
std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
|
std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
|
||||||
|
|
||||||
|
/* No need to check for CPU_FTR_NO_SLBIE_B here, since when
|
||||||
|
* we have 1TB segments, the only CPUs known to have the errata
|
||||||
|
* only support less than 1TB of system memory and we'll never
|
||||||
|
* actually hit this code path.
|
||||||
|
*/
|
||||||
|
|
||||||
slbie r6
|
slbie r6
|
||||||
slbie r6 /* Workaround POWER5 < DD2.1 issue */
|
slbie r6 /* Workaround POWER5 < DD2.1 issue */
|
||||||
slbmte r7,r0
|
slbmte r7,r0
|
||||||
|
|
|
@ -212,6 +212,7 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cur_cpu_spec->cpu_features &= ~CPU_FTR_NO_SLBIE_B;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,7 +157,8 @@ void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
|
||||||
unsigned long stack = KSTK_ESP(tsk);
|
unsigned long stack = KSTK_ESP(tsk);
|
||||||
unsigned long unmapped_base;
|
unsigned long unmapped_base;
|
||||||
|
|
||||||
if (offset <= SLB_CACHE_ENTRIES) {
|
if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
|
||||||
|
offset <= SLB_CACHE_ENTRIES) {
|
||||||
int i;
|
int i;
|
||||||
asm volatile("isync" : : : "memory");
|
asm volatile("isync" : : : "memory");
|
||||||
for (i = 0; i < offset; i++) {
|
for (i = 0; i < offset; i++) {
|
||||||
|
|
|
@ -165,6 +165,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
|
||||||
#define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000)
|
#define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000)
|
||||||
#define CPU_FTR_DSCR LONG_ASM_CONST(0x0002000000000000)
|
#define CPU_FTR_DSCR LONG_ASM_CONST(0x0002000000000000)
|
||||||
#define CPU_FTR_1T_SEGMENT LONG_ASM_CONST(0x0004000000000000)
|
#define CPU_FTR_1T_SEGMENT LONG_ASM_CONST(0x0004000000000000)
|
||||||
|
#define CPU_FTR_NO_SLBIE_B LONG_ASM_CONST(0x0008000000000000)
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
|
@ -367,7 +368,7 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
|
||||||
#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | \
|
#define CPU_FTRS_PA6T (CPU_FTR_USE_TB | \
|
||||||
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
|
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
|
||||||
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
|
CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
|
||||||
CPU_FTR_PURR | CPU_FTR_REAL_LE)
|
CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
|
||||||
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | \
|
#define CPU_FTRS_COMPATIBLE (CPU_FTR_USE_TB | \
|
||||||
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
|
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче