> +int follow_invalidate_pte(struct mm_struct *mm, unsigned long address, > + struct mmu_notifier_range *range, pte_t **ptepp, pmd_t **pmdpp, > + spinlock_t **ptlp); This adds a very pointless overy long line. > +/** > + * follow_pte - look up PTE at a user virtual address > + * @vma: memory mapping > + * @address: user virtual address > + * @ptepp: location to store found PTE > + * @ptlp: location to store the lock for the PTE > + * > + * On a successful return, the pointer to the PTE is stored in @ptepp; > + * the corresponding lock is taken and its location is stored in @ptlp. > + * The contents of the PTE are only stable until @ptlp is released; > + * any further use, if any, must be protected against invalidation > + * with MMU notifiers. > + * > + * Only IO mappings and raw PFN mappings are allowed. The mmap semaphore > + * should be taken for read. > + * > + * Return: zero on success, -ve otherwise. > + */ > +int follow_pte(struct mm_struct *mm, unsigned long address, > + pte_t **ptepp, spinlock_t **ptlp) > +{ > + return follow_invalidate_pte(mm, address, NULL, ptepp, NULL, ptlp); > +} > +EXPORT_SYMBOL_GPL(follow_pte); I still don't think this is good as a general API. Please document this as KVM only for now, and hopefully next merge window I'll finish an export variant restricting us to specific modules.