diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2016-06-17 02:02:00 -0400 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2016-06-17 05:47:51 -0400 |
commit | e568006b9d828403397668864d9797dc4bfefd28 (patch) | |
tree | 5d33a311e57ea12fecda5c04edca711b653cc845 | |
parent | 8550e2fa34f077c8a87cf1ba2453102bbbc9ade9 (diff) |
powerpc/mm/hash: Don't add memory coherence if cache inhibited is set
H_ENTER hcall handling in qemu had assumptions that a cache inhibited
hpte entry won't have memory conference set. Also older kernel
mentioned that some version of pHyp required this (the code removed
by the below commit says:
/* Make pHyp happy */
if ((rflags & _PAGE_NO_CACHE) && !(rflags & _PAGE_WRITETHRU))
hpte_r &= ~HPTE_R_M;
But with older kernel we had some inconsistent memory conherence
mapping. We always enabled memory conherence in the page fault path and
removed memory conherence is _PAGE_NO_CACHE was set when we mapped the
page via htab_bolt_mapping. The commit mentioned below tried to
consolidate that by always enabling memory conherence. But as mentioned
above that breaks Qemu H_ENTER handling.
This patch update this such that we enable memory conherence only if
cache inhibited is not set and bring fault handling, lpar and bolt
mapping in sync.
Fixes: commit 30bda41aba4e("powerpc/mm: Drop WIMG in favour of new constant")
Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/mm/hash_utils_64.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index b2740c67e172..5b22ba0b58bc 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c | |||
@@ -201,9 +201,8 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) | |||
201 | /* | 201 | /* |
202 | * We can't allow hardware to update hpte bits. Hence always | 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 | 203 | * set 'R' bit and set 'C' if it is a write fault |
204 | * Memory coherence is always enabled | ||
205 | */ | 204 | */ |
206 | rflags |= HPTE_R_R | HPTE_R_M; | 205 | rflags |= HPTE_R_R; |
207 | 206 | ||
208 | if (pteflags & _PAGE_DIRTY) | 207 | if (pteflags & _PAGE_DIRTY) |
209 | rflags |= HPTE_R_C; | 208 | rflags |= HPTE_R_C; |
@@ -213,10 +212,15 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags) | |||
213 | 212 | ||
214 | if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_TOLERANT) | 213 | if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_TOLERANT) |
215 | rflags |= HPTE_R_I; | 214 | rflags |= HPTE_R_I; |
216 | if ((pteflags & _PAGE_CACHE_CTL ) == _PAGE_NON_IDEMPOTENT) | 215 | else if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_NON_IDEMPOTENT) |
217 | rflags |= (HPTE_R_I | HPTE_R_G); | 216 | rflags |= (HPTE_R_I | HPTE_R_G); |
218 | if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_SAO) | 217 | else if ((pteflags & _PAGE_CACHE_CTL) == _PAGE_SAO) |
219 | rflags |= (HPTE_R_I | HPTE_R_W); | 218 | rflags |= (HPTE_R_W | HPTE_R_I | HPTE_R_M); |
219 | else | ||
220 | /* | ||
221 | * Add memory coherence if cache inhibited is not set | ||
222 | */ | ||
223 | rflags |= HPTE_R_M; | ||
220 | 224 | ||
221 | return rflags; | 225 | return rflags; |
222 | } | 226 | } |