|
@@ -1485,6 +1485,29 @@ out_exit:
|
|
|
local_irq_restore(flags);
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
|
|
+static inline void tm_flush_hash_page(int local)
|
|
|
+{
|
|
|
+ /*
|
|
|
+ * Transactions are not aborted by tlbiel, only tlbie. Without, syncing a
|
|
|
+ * page back to a block device w/PIO could pick up transactional data
|
|
|
+ * (bad!) so we force an abort here. Before the sync the page will be
|
|
|
+ * made read-only, which will flush_hash_page. BIG ISSUE here: if the
|
|
|
+ * kernel uses a page from userspace without unmapping it first, it may
|
|
|
+ * see the speculated version.
|
|
|
+ */
|
|
|
+ if (local && cpu_has_feature(CPU_FTR_TM) && current->thread.regs &&
|
|
|
+ MSR_TM_ACTIVE(current->thread.regs->msr)) {
|
|
|
+ tm_enable();
|
|
|
+ tm_abort(TM_CAUSE_TLBI);
|
|
|
+ }
|
|
|
+}
|
|
|
+#else
|
|
|
+static inline void tm_flush_hash_page(int local)
|
|
|
+{
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
/* WARNING: This is called from hash_low_64.S, if you change this prototype,
|
|
|
* do not forget to update the assembly call site !
|
|
|
*/
|
|
@@ -1511,21 +1534,7 @@ void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize,
|
|
|
ssize, local);
|
|
|
} pte_iterate_hashed_end();
|
|
|
|
|
|
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
|
|
- /* Transactions are not aborted by tlbiel, only tlbie.
|
|
|
- * Without, syncing a page back to a block device w/ PIO could pick up
|
|
|
- * transactional data (bad!) so we force an abort here. Before the
|
|
|
- * sync the page will be made read-only, which will flush_hash_page.
|
|
|
- * BIG ISSUE here: if the kernel uses a page from userspace without
|
|
|
- * unmapping it first, it may see the speculated version.
|
|
|
- */
|
|
|
- if (local && cpu_has_feature(CPU_FTR_TM) &&
|
|
|
- current->thread.regs &&
|
|
|
- MSR_TM_ACTIVE(current->thread.regs->msr)) {
|
|
|
- tm_enable();
|
|
|
- tm_abort(TM_CAUSE_TLBI);
|
|
|
- }
|
|
|
-#endif
|
|
|
+ tm_flush_hash_page(local);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
|
@@ -1582,22 +1591,7 @@ void flush_hash_hugepage(unsigned long vsid, unsigned long addr,
|
|
|
MMU_PAGE_16M, ssize, local);
|
|
|
}
|
|
|
tm_abort:
|
|
|
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
|
|
- /* Transactions are not aborted by tlbiel, only tlbie.
|
|
|
- * Without, syncing a page back to a block device w/ PIO could pick up
|
|
|
- * transactional data (bad!) so we force an abort here. Before the
|
|
|
- * sync the page will be made read-only, which will flush_hash_page.
|
|
|
- * BIG ISSUE here: if the kernel uses a page from userspace without
|
|
|
- * unmapping it first, it may see the speculated version.
|
|
|
- */
|
|
|
- if (local && cpu_has_feature(CPU_FTR_TM) &&
|
|
|
- current->thread.regs &&
|
|
|
- MSR_TM_ACTIVE(current->thread.regs->msr)) {
|
|
|
- tm_enable();
|
|
|
- tm_abort(TM_CAUSE_TLBI);
|
|
|
- }
|
|
|
-#endif
|
|
|
- return;
|
|
|
+ tm_flush_hash_page(local);
|
|
|
}
|
|
|
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
|
|
|