Commit ae08d237 authored by David Gibson's avatar David Gibson Committed by Linus Torvalds

[PATCH] POWER5 erratum workaround

Early POWER5 revisions (<DD2.1) have a problem requiring slbie
instructions to be repeated under some circumstances.  The patch below
adds a workaround (patch made by Anton Blanchard).
parent e3756200
......@@ -311,6 +311,7 @@ BEGIN_FTR_SECTION
beq 2f /* if yes, don't slbie it */
oris r6,r6,0x0800 /* set C (class) bit */
slbie r6
slbie r6 /* Workaround POWER5 < DD2.1 issue */
2:
END_FTR_SECTION_IFSET(CPU_FTR_SLB)
clrrdi r7,r8,THREAD_SHIFT /* base of new stack */
......
......@@ -474,14 +474,14 @@ static void preload_slb(struct task_struct *tsk, struct mm_struct *mm)
void flush_slb(struct task_struct *tsk, struct mm_struct *mm)
{
unsigned long offset = __get_cpu_var(stab_cache_ptr);
if (offset <= NR_STAB_CACHE_ENTRIES) {
int i;
union {
unsigned long word0;
slb_dword0 data;
} esid_data;
if (offset <= NR_STAB_CACHE_ENTRIES) {
int i;
asm volatile("isync" : : : "memory");
for (i = 0; i < offset; i++) {
esid_data.word0 = 0;
......@@ -493,6 +493,17 @@ void flush_slb(struct task_struct *tsk, struct mm_struct *mm)
asm volatile("isync; slbia; isync" : : : "memory");
}
/* Workaround POWER5 < DD2.1 issue */
if (offset == 1 || offset > NR_STAB_CACHE_ENTRIES) {
/*
* flush segment in EEH region, we dont normally access
* addresses in this region.
*/
esid_data.word0 = 0;
esid_data.data.esid = EEH_REGION_ID;
asm volatile("slbie %0" : : "r" (esid_data));
}
__get_cpu_var(stab_cache_ptr) = 0;
preload_slb(tsk, mm);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment