diff options
Diffstat (limited to 'include/linux/mmu_notifier.h')
| -rw-r--r-- | include/linux/mmu_notifier.h | 102 | 
1 files changed, 67 insertions, 35 deletions
| diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index 9893a6432adf..4050ec1c3b45 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -25,6 +25,13 @@ struct mmu_notifier_mm {  	spinlock_t lock;  }; +struct mmu_notifier_range { +	struct mm_struct *mm; +	unsigned long start; +	unsigned long end; +	bool blockable; +}; +  struct mmu_notifier_ops {  	/*  	 * Called either by mmu_notifier_unregister or when the mm is @@ -146,12 +153,9 @@ struct mmu_notifier_ops {  	 *  	 */  	int (*invalidate_range_start)(struct mmu_notifier *mn, -				       struct mm_struct *mm, -				       unsigned long start, unsigned long end, -				       bool blockable); +				      const struct mmu_notifier_range *range);  	void (*invalidate_range_end)(struct mmu_notifier *mn, -				     struct mm_struct *mm, -				     unsigned long start, unsigned long end); +				     const struct mmu_notifier_range *range);  	/*  	 * invalidate_range() is either called between @@ -216,11 +220,8 @@ extern int __mmu_notifier_test_young(struct mm_struct *mm,  				     unsigned long address);  extern void __mmu_notifier_change_pte(struct mm_struct *mm,  				      unsigned long address, pte_t pte); -extern int __mmu_notifier_invalidate_range_start(struct mm_struct *mm, -				  unsigned long start, unsigned long end, -				  bool blockable); -extern void __mmu_notifier_invalidate_range_end(struct mm_struct *mm, -				  unsigned long start, unsigned long end, +extern int __mmu_notifier_invalidate_range_start(struct mmu_notifier_range *r); +extern void __mmu_notifier_invalidate_range_end(struct mmu_notifier_range *r,  				  bool only_end);  extern void __mmu_notifier_invalidate_range(struct mm_struct *mm,  				  unsigned long start, unsigned long end); @@ -264,33 +265,37 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm,  		__mmu_notifier_change_pte(mm, address, pte);  } -static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline void +mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)  { -	if (mm_has_notifiers(mm)) -		__mmu_notifier_invalidate_range_start(mm, start, end, true); +	if (mm_has_notifiers(range->mm)) { +		range->blockable = true; +		__mmu_notifier_invalidate_range_start(range); +	}  } -static inline int mmu_notifier_invalidate_range_start_nonblock(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline int +mmu_notifier_invalidate_range_start_nonblock(struct mmu_notifier_range *range)  { -	if (mm_has_notifiers(mm)) -		return __mmu_notifier_invalidate_range_start(mm, start, end, false); +	if (mm_has_notifiers(range->mm)) { +		range->blockable = false; +		return __mmu_notifier_invalidate_range_start(range); +	}  	return 0;  } -static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline void +mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range)  { -	if (mm_has_notifiers(mm)) -		__mmu_notifier_invalidate_range_end(mm, start, end, false); +	if (mm_has_notifiers(range->mm)) +		__mmu_notifier_invalidate_range_end(range, false);  } -static inline void mmu_notifier_invalidate_range_only_end(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline void +mmu_notifier_invalidate_range_only_end(struct mmu_notifier_range *range)  { -	if (mm_has_notifiers(mm)) -		__mmu_notifier_invalidate_range_end(mm, start, end, true); +	if (mm_has_notifiers(range->mm)) +		__mmu_notifier_invalidate_range_end(range, true);  }  static inline void mmu_notifier_invalidate_range(struct mm_struct *mm, @@ -311,6 +316,17 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)  		__mmu_notifier_mm_destroy(mm);  } + +static inline void mmu_notifier_range_init(struct mmu_notifier_range *range, +					   struct mm_struct *mm, +					   unsigned long start, +					   unsigned long end) +{ +	range->mm = mm; +	range->start = start; +	range->end = end; +} +  #define ptep_clear_flush_young_notify(__vma, __address, __ptep)		\  ({									\  	int __young;							\ @@ -420,10 +436,26 @@ static inline void mmu_notifier_mm_destroy(struct mm_struct *mm)  extern void mmu_notifier_call_srcu(struct rcu_head *rcu,  				   void (*func)(struct rcu_head *rcu)); -extern void mmu_notifier_synchronize(void);  #else /* CONFIG_MMU_NOTIFIER */ +struct mmu_notifier_range { +	unsigned long start; +	unsigned long end; +}; + +static inline void _mmu_notifier_range_init(struct mmu_notifier_range *range, +					    unsigned long start, +					    unsigned long end) +{ +	range->start = start; +	range->end = end; +} + +#define mmu_notifier_range_init(range, mm, start, end) \ +	_mmu_notifier_range_init(range, start, end) + +  static inline int mm_has_notifiers(struct mm_struct *mm)  {  	return 0; @@ -451,24 +483,24 @@ static inline void mmu_notifier_change_pte(struct mm_struct *mm,  {  } -static inline void mmu_notifier_invalidate_range_start(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline void +mmu_notifier_invalidate_range_start(struct mmu_notifier_range *range)  {  } -static inline int mmu_notifier_invalidate_range_start_nonblock(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline int +mmu_notifier_invalidate_range_start_nonblock(struct mmu_notifier_range *range)  {  	return 0;  } -static inline void mmu_notifier_invalidate_range_end(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline +void mmu_notifier_invalidate_range_end(struct mmu_notifier_range *range)  {  } -static inline void mmu_notifier_invalidate_range_only_end(struct mm_struct *mm, -				  unsigned long start, unsigned long end) +static inline void +mmu_notifier_invalidate_range_only_end(struct mmu_notifier_range *range)  {  } | 
