diff options
Diffstat (limited to 'arch/tile/lib/memcpy_tile64.c')
-rw-r--r-- | arch/tile/lib/memcpy_tile64.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c index dfedea7b266b..b2fe15e01075 100644 --- a/arch/tile/lib/memcpy_tile64.c +++ b/arch/tile/lib/memcpy_tile64.c | |||
@@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long); | |||
54 | * we must run with interrupts disabled to avoid the risk of some | 54 | * we must run with interrupts disabled to avoid the risk of some |
55 | * other code seeing the incoherent data in our cache. (Recall that | 55 | * other code seeing the incoherent data in our cache. (Recall that |
56 | * our cache is indexed by PA, so even if the other code doesn't use | 56 | * our cache is indexed by PA, so even if the other code doesn't use |
57 | * our KM_MEMCPY virtual addresses, they'll still hit in cache using | 57 | * our kmap_atomic virtual addresses, they'll still hit in cache using |
58 | * the normal VAs that aren't supposed to hit in cache.) | 58 | * the normal VAs that aren't supposed to hit in cache.) |
59 | */ | 59 | */ |
60 | static void memcpy_multicache(void *dest, const void *source, | 60 | static void memcpy_multicache(void *dest, const void *source, |
@@ -64,6 +64,7 @@ static void memcpy_multicache(void *dest, const void *source, | |||
64 | unsigned long flags, newsrc, newdst; | 64 | unsigned long flags, newsrc, newdst; |
65 | pmd_t *pmdp; | 65 | pmd_t *pmdp; |
66 | pte_t *ptep; | 66 | pte_t *ptep; |
67 | int type0, type1; | ||
67 | int cpu = get_cpu(); | 68 | int cpu = get_cpu(); |
68 | 69 | ||
69 | /* | 70 | /* |
@@ -77,7 +78,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
77 | sim_allow_multiple_caching(1); | 78 | sim_allow_multiple_caching(1); |
78 | 79 | ||
79 | /* Set up the new dest mapping */ | 80 | /* Set up the new dest mapping */ |
80 | idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0; | 81 | type0 = kmap_atomic_idx_push(); |
82 | idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0; | ||
81 | newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); | 83 | newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); |
82 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); | 84 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); |
83 | ptep = pte_offset_kernel(pmdp, newdst); | 85 | ptep = pte_offset_kernel(pmdp, newdst); |
@@ -87,13 +89,14 @@ static void memcpy_multicache(void *dest, const void *source, | |||
87 | } | 89 | } |
88 | 90 | ||
89 | /* Set up the new source mapping */ | 91 | /* Set up the new source mapping */ |
90 | idx += (KM_MEMCPY0 - KM_MEMCPY1); | 92 | type1 = kmap_atomic_idx_push(); |
93 | idx += (type0 - type1); | ||
91 | src_pte = hv_pte_set_nc(src_pte); | 94 | src_pte = hv_pte_set_nc(src_pte); |
92 | src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ | 95 | src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ |
93 | newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); | 96 | newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); |
94 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newsrc), newsrc), newsrc); | 97 | pmdp = pmd_offset(pud_offset(pgd_offset_k(newsrc), newsrc), newsrc); |
95 | ptep = pte_offset_kernel(pmdp, newsrc); | 98 | ptep = pte_offset_kernel(pmdp, newsrc); |
96 | *ptep = src_pte; /* set_pte() would be confused by this */ | 99 | __set_pte(ptep, src_pte); /* set_pte() would be confused by this */ |
97 | local_flush_tlb_page(NULL, newsrc, PAGE_SIZE); | 100 | local_flush_tlb_page(NULL, newsrc, PAGE_SIZE); |
98 | 101 | ||
99 | /* Actually move the data. */ | 102 | /* Actually move the data. */ |
@@ -106,7 +109,7 @@ static void memcpy_multicache(void *dest, const void *source, | |||
106 | */ | 109 | */ |
107 | src_pte = hv_pte_set_mode(src_pte, HV_PTE_MODE_CACHE_NO_L3); | 110 | src_pte = hv_pte_set_mode(src_pte, HV_PTE_MODE_CACHE_NO_L3); |
108 | src_pte = hv_pte_set_writable(src_pte); /* need write access for inv */ | 111 | src_pte = hv_pte_set_writable(src_pte); /* need write access for inv */ |
109 | *ptep = src_pte; /* set_pte() would be confused by this */ | 112 | __set_pte(ptep, src_pte); /* set_pte() would be confused by this */ |
110 | local_flush_tlb_page(NULL, newsrc, PAGE_SIZE); | 113 | local_flush_tlb_page(NULL, newsrc, PAGE_SIZE); |
111 | 114 | ||
112 | /* | 115 | /* |
@@ -119,6 +122,8 @@ static void memcpy_multicache(void *dest, const void *source, | |||
119 | * We're done: notify the simulator that all is back to normal, | 122 | * We're done: notify the simulator that all is back to normal, |
120 | * and re-enable interrupts and pre-emption. | 123 | * and re-enable interrupts and pre-emption. |
121 | */ | 124 | */ |
125 | kmap_atomic_idx_pop(); | ||
126 | kmap_atomic_idx_pop(); | ||
122 | sim_allow_multiple_caching(0); | 127 | sim_allow_multiple_caching(0); |
123 | local_irq_restore(flags); | 128 | local_irq_restore(flags); |
124 | put_cpu(); | 129 | put_cpu(); |