|
@@ -193,25 +193,23 @@ mspec_close(struct vm_area_struct *vma)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * mspec_nopfn
|
|
|
|
|
|
+ * mspec_fault
|
|
*
|
|
*
|
|
* Creates a mspec page and maps it to user space.
|
|
* Creates a mspec page and maps it to user space.
|
|
*/
|
|
*/
|
|
-static unsigned long
|
|
|
|
-mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
|
|
|
|
|
|
+static int
|
|
|
|
+mspec_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|
{
|
|
{
|
|
unsigned long paddr, maddr;
|
|
unsigned long paddr, maddr;
|
|
unsigned long pfn;
|
|
unsigned long pfn;
|
|
- int index;
|
|
|
|
|
|
+ pgoff_t index = vmf->pgoff;
|
|
struct vma_data *vdata = vma->vm_private_data;
|
|
struct vma_data *vdata = vma->vm_private_data;
|
|
|
|
|
|
- BUG_ON(address < vdata->vm_start || address >= vdata->vm_end);
|
|
|
|
- index = (address - vdata->vm_start) >> PAGE_SHIFT;
|
|
|
|
maddr = (volatile unsigned long) vdata->maddr[index];
|
|
maddr = (volatile unsigned long) vdata->maddr[index];
|
|
if (maddr == 0) {
|
|
if (maddr == 0) {
|
|
maddr = uncached_alloc_page(numa_node_id(), 1);
|
|
maddr = uncached_alloc_page(numa_node_id(), 1);
|
|
if (maddr == 0)
|
|
if (maddr == 0)
|
|
- return NOPFN_OOM;
|
|
|
|
|
|
+ return VM_FAULT_OOM;
|
|
|
|
|
|
spin_lock(&vdata->lock);
|
|
spin_lock(&vdata->lock);
|
|
if (vdata->maddr[index] == 0) {
|
|
if (vdata->maddr[index] == 0) {
|
|
@@ -231,13 +229,20 @@ mspec_nopfn(struct vm_area_struct *vma, unsigned long address)
|
|
|
|
|
|
pfn = paddr >> PAGE_SHIFT;
|
|
pfn = paddr >> PAGE_SHIFT;
|
|
|
|
|
|
- return pfn;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * vm_insert_pfn can fail with -EBUSY, but in that case it will
|
|
|
|
+ * be because another thread has installed the pte first, so it
|
|
|
|
+ * is no problem.
|
|
|
|
+ */
|
|
|
|
+ vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
|
|
|
|
+
|
|
|
|
+ return VM_FAULT_NOPAGE;
|
|
}
|
|
}
|
|
|
|
|
|
static struct vm_operations_struct mspec_vm_ops = {
|
|
static struct vm_operations_struct mspec_vm_ops = {
|
|
.open = mspec_open,
|
|
.open = mspec_open,
|
|
.close = mspec_close,
|
|
.close = mspec_close,
|
|
- .nopfn = mspec_nopfn
|
|
|
|
|
|
+ .fault = mspec_fault,
|
|
};
|
|
};
|
|
|
|
|
|
/*
|
|
/*
|