hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/arch/arm/mm/highmem.c
....@@ -34,6 +34,11 @@
3434 return *ptep;
3535 }
3636
37
+static unsigned int fixmap_idx(int type)
38
+{
39
+ return FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
40
+}
41
+
3742 void *kmap(struct page *page)
3843 {
3944 might_sleep();
....@@ -54,12 +59,13 @@
5459
5560 void *kmap_atomic(struct page *page)
5661 {
62
+ pte_t pte = mk_pte(page, kmap_prot);
5763 unsigned int idx;
5864 unsigned long vaddr;
5965 void *kmap;
6066 int type;
6167
62
- preempt_disable();
68
+ preempt_disable_nort();
6369 pagefault_disable();
6470 if (!PageHighMem(page))
6571 return page_address(page);
....@@ -79,7 +85,7 @@
7985
8086 type = kmap_atomic_idx_push();
8187
82
- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
88
+ idx = fixmap_idx(type);
8389 vaddr = __fix_to_virt(idx);
8490 #ifdef CONFIG_DEBUG_HIGHMEM
8591 /*
....@@ -93,7 +99,10 @@
9399 * in place, so the contained TLB flush ensures the TLB is updated
94100 * with the new mapping.
95101 */
96
- set_fixmap_pte(idx, mk_pte(page, kmap_prot));
102
+#ifdef CONFIG_PREEMPT_RT_FULL
103
+ current->kmap_pte[type] = pte;
104
+#endif
105
+ set_fixmap_pte(idx, pte);
97106
98107 return (void *)vaddr;
99108 }
....@@ -106,44 +115,75 @@
106115
107116 if (kvaddr >= (void *)FIXADDR_START) {
108117 type = kmap_atomic_idx();
109
- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
118
+ idx = fixmap_idx(type);
110119
111120 if (cache_is_vivt())
112121 __cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);
122
+#ifdef CONFIG_PREEMPT_RT_FULL
123
+ current->kmap_pte[type] = __pte(0);
124
+#endif
113125 #ifdef CONFIG_DEBUG_HIGHMEM
114126 BUG_ON(vaddr != __fix_to_virt(idx));
115
- set_fixmap_pte(idx, __pte(0));
116127 #else
117128 (void) idx; /* to kill a warning */
118129 #endif
130
+ set_fixmap_pte(idx, __pte(0));
119131 kmap_atomic_idx_pop();
120132 } else if (vaddr >= PKMAP_ADDR(0) && vaddr < PKMAP_ADDR(LAST_PKMAP)) {
121133 /* this address was obtained through kmap_high_get() */
122134 kunmap_high(pte_page(pkmap_page_table[PKMAP_NR(vaddr)]));
123135 }
124136 pagefault_enable();
125
- preempt_enable();
137
+ preempt_enable_nort();
126138 }
127139 EXPORT_SYMBOL(__kunmap_atomic);
128140
129141 void *kmap_atomic_pfn(unsigned long pfn)
130142 {
143
+ pte_t pte = pfn_pte(pfn, kmap_prot);
131144 unsigned long vaddr;
132145 int idx, type;
133146 struct page *page = pfn_to_page(pfn);
134147
135
- preempt_disable();
148
+ preempt_disable_nort();
136149 pagefault_disable();
137150 if (!PageHighMem(page))
138151 return page_address(page);
139152
140153 type = kmap_atomic_idx_push();
141
- idx = FIX_KMAP_BEGIN + type + KM_TYPE_NR * smp_processor_id();
154
+ idx = fixmap_idx(type);
142155 vaddr = __fix_to_virt(idx);
143156 #ifdef CONFIG_DEBUG_HIGHMEM
144157 BUG_ON(!pte_none(get_fixmap_pte(vaddr)));
145158 #endif
146
- set_fixmap_pte(idx, pfn_pte(pfn, kmap_prot));
159
+#ifdef CONFIG_PREEMPT_RT_FULL
160
+ current->kmap_pte[type] = pte;
161
+#endif
162
+ set_fixmap_pte(idx, pte);
147163
148164 return (void *)vaddr;
149165 }
166
+#if defined CONFIG_PREEMPT_RT_FULL
167
+void switch_kmaps(struct task_struct *prev_p, struct task_struct *next_p)
168
+{
169
+ int i;
170
+
171
+ /*
172
+ * Clear @prev's kmap_atomic mappings
173
+ */
174
+ for (i = 0; i < prev_p->kmap_idx; i++) {
175
+ int idx = fixmap_idx(i);
176
+
177
+ set_fixmap_pte(idx, __pte(0));
178
+ }
179
+ /*
180
+ * Restore @next_p's kmap_atomic mappings
181
+ */
182
+ for (i = 0; i < next_p->kmap_idx; i++) {
183
+ int idx = fixmap_idx(i);
184
+
185
+ if (!pte_none(next_p->kmap_pte[i]))
186
+ set_fixmap_pte(idx, next_p->kmap_pte[i]);
187
+ }
188
+}
189
+#endif