|
@@ -2,6 +2,7 @@
|
|
#ifndef _LINUX_MMU_NOTIFIER_H
|
|
#ifndef _LINUX_MMU_NOTIFIER_H
|
|
#define _LINUX_MMU_NOTIFIER_H
|
|
#define _LINUX_MMU_NOTIFIER_H
|
|
|
|
|
|
|
|
+#include <linux/types.h>
|
|
#include <linux/list.h>
|
|
#include <linux/list.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/mm_types.h>
|
|
#include <linux/mm_types.h>
|
|
@@ -10,6 +11,9 @@
|
|
struct mmu_notifier;
|
|
struct mmu_notifier;
|
|
struct mmu_notifier_ops;
|
|
struct mmu_notifier_ops;
|
|
|
|
|
|
|
|
+/* mmu_notifier_ops flags */
|
|
|
|
+#define MMU_INVALIDATE_DOES_NOT_BLOCK (0x01)
|
|
|
|
+
|
|
#ifdef CONFIG_MMU_NOTIFIER
|
|
#ifdef CONFIG_MMU_NOTIFIER
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -26,6 +30,15 @@ struct mmu_notifier_mm {
|
|
};
|
|
};
|
|
|
|
|
|
struct mmu_notifier_ops {
|
|
struct mmu_notifier_ops {
|
|
|
|
+ /*
|
|
|
|
+ * Flags to specify behavior of callbacks for this MMU notifier.
|
|
|
|
+ * Used to determine which context an operation may be called.
|
|
|
|
+ *
|
|
|
|
+ * MMU_INVALIDATE_DOES_NOT_BLOCK: invalidate_range_* callbacks do not
|
|
|
|
+ * block
|
|
|
|
+ */
|
|
|
|
+ int flags;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Called either by mmu_notifier_unregister or when the mm is
|
|
* Called either by mmu_notifier_unregister or when the mm is
|
|
* being destroyed by exit_mmap, always before all pages are
|
|
* being destroyed by exit_mmap, always before all pages are
|
|
@@ -137,6 +150,10 @@ struct mmu_notifier_ops {
|
|
* page. Pages will no longer be referenced by the linux
|
|
* page. Pages will no longer be referenced by the linux
|
|
* address space but may still be referenced by sptes until
|
|
* address space but may still be referenced by sptes until
|
|
* the last refcount is dropped.
|
|
* the last refcount is dropped.
|
|
|
|
+ *
|
|
|
|
+ * If both of these callbacks cannot block, and invalidate_range
|
|
|
|
+ * cannot block, mmu_notifier_ops.flags should have
|
|
|
|
+ * MMU_INVALIDATE_DOES_NOT_BLOCK set.
|
|
*/
|
|
*/
|
|
void (*invalidate_range_start)(struct mmu_notifier *mn,
|
|
void (*invalidate_range_start)(struct mmu_notifier *mn,
|
|
struct mm_struct *mm,
|
|
struct mm_struct *mm,
|
|
@@ -159,12 +176,13 @@ struct mmu_notifier_ops {
|
|
* external TLB range needs to be flushed. For more in depth
|
|
* external TLB range needs to be flushed. For more in depth
|
|
* discussion on this see Documentation/vm/mmu_notifier.txt
|
|
* discussion on this see Documentation/vm/mmu_notifier.txt
|
|
*
|
|
*
|
|
- * The invalidate_range() function is called under the ptl
|
|
|
|
- * spin-lock and not allowed to sleep.
|
|
|
|
- *
|
|
|
|
* Note that this function might be called with just a sub-range
|
|
* Note that this function might be called with just a sub-range
|
|
* of what was passed to invalidate_range_start()/end(), if
|
|
* of what was passed to invalidate_range_start()/end(), if
|
|
* called between those functions.
|
|
* called between those functions.
|
|
|
|
+ *
|
|
|
|
+ * If this callback cannot block, and invalidate_range_{start,end}
|
|
|
|
+ * cannot block, mmu_notifier_ops.flags should have
|
|
|
|
+ * MMU_INVALIDATE_DOES_NOT_BLOCK set.
|
|
*/
|
|
*/
|
|
void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm,
|
|
void (*invalidate_range)(struct mmu_notifier *mn, struct mm_struct *mm,
|
|
unsigned long start, unsigned long end);
|
|
unsigned long start, unsigned long end);
|
|
@@ -218,6 +236,7 @@ extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm,
|
|
bool only_end);
|
|
bool only_end);
|
|
extern void __mmu_notifier_invalidate_range(struct mm_struct *mm,
|
|
extern void __mmu_notifier_invalidate_range(struct mm_struct *mm,
|
|
unsigned long start, unsigned long end);
|
|
unsigned long start, unsigned long end);
|
|
|
|
+extern bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm);
|
|
|
|
|
|
static inline void mmu_notifier_release(struct mm_struct *mm)
|
|
static inline void mmu_notifier_release(struct mm_struct *mm)
|
|
{
|
|
{
|
|
@@ -457,6 +476,11 @@ static inline void mmu_notifier_invalidate_range(struct mm_struct *mm,
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static inline bool mm_has_blockable_invalidate_notifiers(struct mm_struct *mm)
|
|
|
|
+{
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
static inline void mmu_notifier_mm_init(struct mm_struct *mm)
|
|
static inline void mmu_notifier_mm_init(struct mm_struct *mm)
|
|
{
|
|
{
|
|
}
|
|
}
|