301-MIPS-Add-barriers-between-dcache-icache-flushes.patch 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. From e6e6ef4275978823ec3a84133fc91f4ffbef5c84 Mon Sep 17 00:00:00 2001
  2. From: Paul Burton <[email protected]>
  3. Date: Mon, 22 Feb 2016 18:09:44 +0000
  4. Subject: [PATCH] MIPS: Add barriers between dcache & icache flushes
  5. Index-based cache operations may be arbitrarily reordered by out of
  6. order CPUs. Thus code which writes back the dcache & then invalidates
  7. the icache using indexed cache ops must include a barrier between
  8. operating on the 2 caches in order to prevent the scenario in which:
  9. - icache invalidation occurs.
  10. - icache fetch occurs, due to speculation.
  11. - dcache writeback occurs.
  12. If the above were allowed to happen then the icache would contain stale
  13. data. Forcing the dcache writeback to complete before the icache
  14. invalidation avoids this.
  15. Signed-off-by: Paul Burton <[email protected]>
  16. Cc: James Hogan <[email protected]>
  17. ---
  18. arch/mips/mm/c-r4k.c | 13 +++++++++++--
  19. 1 file changed, 11 insertions(+), 2 deletions(-)
  20. --- a/arch/mips/mm/c-r4k.c
  21. +++ b/arch/mips/mm/c-r4k.c
  22. @@ -515,6 +515,7 @@ static inline void local_r4k___flush_cac
  23. default:
  24. r4k_blast_dcache();
  25. + mb(); /* cache instructions may be reordered */
  26. r4k_blast_icache();
  27. break;
  28. }
  29. @@ -595,8 +596,10 @@ static inline void local_r4k_flush_cache
  30. if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc))
  31. r4k_blast_dcache();
  32. /* If executable, blast stale lines from icache */
  33. - if (exec)
  34. + if (exec) {
  35. + mb(); /* cache instructions may be reordered */
  36. r4k_blast_icache();
  37. + }
  38. }
  39. static void r4k_flush_cache_range(struct vm_area_struct *vma,
  40. @@ -697,8 +700,13 @@ static inline void local_r4k_flush_cache
  41. if (cpu_has_dc_aliases || (exec && !cpu_has_ic_fills_f_dc)) {
  42. vaddr ? r4k_blast_dcache_page(addr) :
  43. r4k_blast_dcache_user_page(addr);
  44. - if (exec && !cpu_icache_snoops_remote_store)
  45. + if (exec)
  46. + mb(); /* cache instructions may be reordered */
  47. +
  48. + if (exec && !cpu_icache_snoops_remote_store) {
  49. r4k_blast_scache_page(addr);
  50. + mb(); /* cache instructions may be reordered */
  51. + }
  52. }
  53. if (exec) {
  54. if (vaddr && cpu_has_vtag_icache && mm == current->active_mm) {
  55. @@ -765,6 +773,7 @@ static inline void __local_r4k_flush_ica
  56. else
  57. blast_dcache_range(start, end);
  58. }
  59. + mb(); /* cache instructions may be reordered */
  60. }
  61. if (type == R4K_INDEX ||