This patch implements a simple callback for device drivers that establishtheir own references to pages (KVM, GRU, XPmem, RDMA/Infiniband, DMA enginesetc). These references are unknown to the VM (therefore external).

With these callbacks it is possible for the device driver to release externalreferences when the VM requests it. This enables swapping, page migration andallows support of remapping, permission changes etc etc for externallymapped memory.

With this functionality it becomes also possible to avoid pinning or mlockingpages (commonly done to stop the VM from unmapping device mapped pages).

A device driver must subscribe to a process using

emm_register_notifier(struct emm_notifier *, struct mm_struct *)

The VM will then perform callbacks for operations that unmap or changepermissions of pages in that address space. When the process terminatesthe callback function is called with emm_release.

Callbacks are performed before and after the unmapping action of the VM.

emm_invalidate_start before

emm_invalidate_end after

The device driver must hold off establishing new references to pagesin the range specified between a callback with emm_invalidate_start andthe subsequent call with emm_invalidate_end set. This allows the VM toensure that no concurrent driver actions are performed on an addressrange while performing remapping or unmapping operations.

Callbacks are mostly performed in a non atomic context. However, invarious places spinlocks are held to traverse rmaps. So this patch hereis only useful for those devices that can remove mappings in an atomiccontext (f.e. KVM/GRU).

If the rmap spinlocks are converted to semaphores then all callbacks willbe performed in a nonatomic context. No additional changes will be necessaryto this patchset.

V1->V2:- page_referenced_one: Do not increment reference count if it is already != 0.- Use rcu_assign_pointer and rcu_derefence_pointer instead of putting in our own barriers.