hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/arch/powerpc/platforms/pseries/iommu.c
....@@ -38,6 +38,7 @@
3838 #include <linux/of.h>
3939 #include <linux/iommu.h>
4040 #include <linux/rculist.h>
41
+#include <linux/locallock.h>
4142 #include <asm/io.h>
4243 #include <asm/prom.h>
4344 #include <asm/rtas.h>
....@@ -212,6 +213,7 @@
212213 }
213214
214215 static DEFINE_PER_CPU(__be64 *, tce_page);
216
+static DEFINE_LOCAL_IRQ_LOCK(tcp_page_lock);
215217
216218 static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
217219 long npages, unsigned long uaddr,
....@@ -233,7 +235,8 @@
233235 direction, attrs);
234236 }
235237
236
- local_irq_save(flags); /* to protect tcep and the page behind it */
238
+ /* to protect tcep and the page behind it */
239
+ local_lock_irqsave(tcp_page_lock, flags);
237240
238241 tcep = __this_cpu_read(tce_page);
239242
....@@ -244,7 +247,7 @@
244247 tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
245248 /* If allocation fails, fall back to the loop implementation */
246249 if (!tcep) {
247
- local_irq_restore(flags);
250
+ local_unlock_irqrestore(tcp_page_lock, flags);
248251 return tce_build_pSeriesLP(tbl->it_index, tcenum,
249252 tbl->it_page_shift,
250253 npages, uaddr, direction, attrs);
....@@ -279,7 +282,7 @@
279282 tcenum += limit;
280283 } while (npages > 0 && !rc);
281284
282
- local_irq_restore(flags);
285
+ local_unlock_irqrestore(tcp_page_lock, flags);
283286
284287 if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
285288 ret = (int)rc;
....@@ -450,13 +453,14 @@
450453 DMA_BIDIRECTIONAL, 0);
451454 }
452455
453
- local_irq_disable(); /* to protect tcep and the page behind it */
456
+ /* to protect tcep and the page behind it */
457
+ local_lock_irq(tcp_page_lock);
454458 tcep = __this_cpu_read(tce_page);
455459
456460 if (!tcep) {
457461 tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
458462 if (!tcep) {
459
- local_irq_enable();
463
+ local_unlock_irq(tcp_page_lock);
460464 return -ENOMEM;
461465 }
462466 __this_cpu_write(tce_page, tcep);
....@@ -502,7 +506,7 @@
502506
503507 /* error cleanup: caller will clear whole range */
504508
505
- local_irq_enable();
509
+ local_unlock_irq(tcp_page_lock);
506510 return rc;
507511 }
508512