rus_vm_fault(): cleanup and early exit on NULL access
Change-Id: I90b18988989d4e377ed9c35df6b2e6bcdddd13b6
This commit is contained in:
committed by
Masamichi Takagi
parent
cc07d6e017
commit
80f964e44f
@@ -557,27 +557,26 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
struct ikc_scd_packet packet = { };
|
struct ikc_scd_packet packet = { };
|
||||||
unsigned long rsysnum = 0;
|
unsigned long rsysnum = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
||||||
dprintk("mcctrl:page fault:flags %#x pgoff %#lx va %#lx page %p\n",
|
unsigned long addr = vmf->address;
|
||||||
vmf->flags, vmf->pgoff, vmf->address, vmf->page);
|
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
||||||
dprintk("mcctrl:page fault:flags %#x pgoff %#lx va %p page %p\n",
|
void __user *addr = vmf->virtual_address;
|
||||||
vmf->flags, vmf->pgoff, vmf->virtual_address, vmf->page);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
||||||
|
|
||||||
/* Look up per-process structure */
|
/* Look up per-process structure */
|
||||||
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(task));
|
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(task));
|
||||||
if (!ppd) {
|
if (!ppd) {
|
||||||
dprintk("%s: INFO: no per-process structure for pid %d (tid %d), trying to use pid %d\n",
|
pr_err("%s: INFO: no per-process structure for "
|
||||||
__func__, task_tgid_vnr(task), task_pid_vnr(task),
|
"pid %d (tid %d), trying to use pid %d\n",
|
||||||
vma->vm_mm->owner->pid);
|
__func__,
|
||||||
|
task_tgid_vnr(task), task_pid_vnr(task),
|
||||||
|
vma->vm_mm->owner->pid);
|
||||||
task = vma->vm_mm->owner;
|
task = vma->vm_mm->owner;
|
||||||
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(task));
|
ppd = mcctrl_get_per_proc_data(usrdata, task_tgid_vnr(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ppd) {
|
if (!ppd) {
|
||||||
kprintf("%s: ERROR: no per-process structure for PID %d??\n",
|
pr_err("%s: ERROR: no per-process structure for PID %d??\n",
|
||||||
__func__, task_tgid_vnr(task));
|
__func__, task_tgid_vnr(task));
|
||||||
ret = VM_FAULT_SIGBUS;
|
ret = VM_FAULT_SIGBUS;
|
||||||
goto no_ppd;
|
goto no_ppd;
|
||||||
@@ -599,27 +598,25 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
pr_ptd("put", task_pid_vnr(task), ptd);
|
pr_ptd("put", task_pid_vnr(task), ptd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Don't even bother looking up NULL */
|
||||||
|
if (!addr) {
|
||||||
|
pr_warn("%s: WARNING: attempted NULL pointer access\n",
|
||||||
|
__func__);
|
||||||
|
ret = VM_FAULT_SIGBUS;
|
||||||
|
goto put_and_out;
|
||||||
|
}
|
||||||
|
|
||||||
for (try = 1; ; ++try) {
|
for (try = 1; ; ++try) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
|
||||||
error = translate_rva_to_rpa(usrdata->os, ppd->rpgtable,
|
error = translate_rva_to_rpa(usrdata->os, ppd->rpgtable,
|
||||||
vmf->address, &rpa, &pgsize);
|
(unsigned long)addr, &rpa, &pgsize);
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
error = translate_rva_to_rpa(usrdata->os, ppd->rpgtable,
|
|
||||||
(unsigned long)vmf->virtual_address,
|
|
||||||
&rpa, &pgsize);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
#define NTRIES 2
|
#define NTRIES 2
|
||||||
if (!error || (try >= NTRIES)) {
|
if (!error || (try >= NTRIES)) {
|
||||||
if (error) {
|
if (error) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
pr_err("%s: error translating 0x%#lx "
|
||||||
pr_err("%s: error translating 0x%#lx (req: TID: %u, syscall: %lu)\n",
|
"(req: TID: %u, syscall: %lu)\n",
|
||||||
__func__, vmf->address,
|
__func__,
|
||||||
packet.fault_tid, rsysnum);
|
(unsigned long)addr,
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
packet.fault_tid, rsysnum);
|
||||||
pr_err("%s: error translating 0x%p (req: TID: %u, syscall: %lu)\n",
|
|
||||||
__func__, vmf->virtual_address,
|
|
||||||
packet.fault_tid, rsysnum);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -630,23 +627,14 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
#define PF_WRITE 0x02
|
#define PF_WRITE 0x02
|
||||||
reason |= PF_WRITE;
|
reason |= PF_WRITE;
|
||||||
}
|
}
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
error = remote_page_fault(usrdata, (void *)addr,
|
||||||
error = remote_page_fault(usrdata, (void *)vmf->address,
|
|
||||||
reason, ppd, &packet);
|
reason, ppd, &packet);
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
error = remote_page_fault(usrdata, vmf->virtual_address,
|
|
||||||
reason, ppd, &packet);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
if (error) {
|
if (error) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
pr_err("%s: error forwarding PF for 0x%#lx "
|
||||||
pr_err("%s: error forwarding PF for 0x%#lx (req: TID: %d, syscall: %lu)\n",
|
"(req: TID: %d, syscall: %lu)\n",
|
||||||
__func__, vmf->address,
|
__func__,
|
||||||
packet.fault_tid, rsysnum);
|
(unsigned long)addr,
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
packet.fault_tid, rsysnum);
|
||||||
pr_err("%s: error forwarding PF for 0x%p (req: TID: %d, syscall: %lu)\n",
|
|
||||||
__func__, vmf->virtual_address,
|
|
||||||
packet.fault_tid, rsysnum);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -655,11 +643,7 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
goto put_and_out;
|
goto put_and_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
rva = (unsigned long)addr & ~(pgsize - 1);
|
||||||
rva = vmf->address & ~(pgsize - 1);
|
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
rva = (unsigned long)vmf->virtual_address & ~(pgsize - 1);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
rpa = rpa & ~(pgsize - 1);
|
rpa = rpa & ~(pgsize - 1);
|
||||||
|
|
||||||
phys = ihk_device_map_memory(dev, rpa, pgsize);
|
phys = ihk_device_map_memory(dev, rpa, pgsize);
|
||||||
@@ -679,17 +663,13 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
|
|
||||||
error = vm_insert_page(vma, rva+(pix*PAGE_SIZE), page);
|
error = vm_insert_page(vma, rva+(pix*PAGE_SIZE), page);
|
||||||
if (error) {
|
if (error) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
pr_err("%s: error inserting mapping for 0x%#lx "
|
||||||
pr_err("%s: error inserting mapping for 0x%#lx (req: TID: %d, syscall: %lu) error: %d, vm_start: 0x%lx, vm_end: 0x%lx\n",
|
"(req: TID: %d, syscall: %lu) error: %d,"
|
||||||
__func__, vmf->address,
|
" vm_start: 0x%lx, vm_end: 0x%lx\n",
|
||||||
packet.fault_tid, rsysnum,
|
__func__,
|
||||||
error, vma->vm_start, vma->vm_end);
|
(unsigned long)addr, packet.fault_tid,
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
rsysnum, error,
|
||||||
pr_err("%s: error inserting mapping for 0x%p (req: TID: %d, syscall: %lu) error: %d, vm_start: 0x%lx, vm_end: 0x%lx\n",
|
vma->vm_start, vma->vm_end);
|
||||||
__func__, vmf->virtual_address,
|
|
||||||
packet.fault_tid, rsysnum, error,
|
|
||||||
vma->vm_start, vma->vm_end);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -715,15 +695,11 @@ static int rus_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
#endif
|
#endif
|
||||||
ihk_device_unmap_memory(dev, phys, pgsize);
|
ihk_device_unmap_memory(dev, phys, pgsize);
|
||||||
if (error) {
|
if (error) {
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0)
|
pr_err("%s: remote PF failed for 0x%#lx, pgoff: %lu"
|
||||||
pr_err("%s: remote PF failed for 0x%#lx, pgoff: %lu (req: TID: %d, syscall: %lu)\n",
|
" (req: TID: %d, syscall: %lu)\n",
|
||||||
__func__, vmf->address, vmf->pgoff,
|
__func__,
|
||||||
packet.fault_tid, rsysnum);
|
(unsigned long)addr, vmf->pgoff,
|
||||||
#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
packet.fault_tid, rsysnum);
|
||||||
pr_err("%s: remote PF failed for 0x%p, pgoff: %lu (req: TID: %d, syscall: %lu)\n",
|
|
||||||
__func__, vmf->virtual_address, vmf->pgoff,
|
|
||||||
packet.fault_tid, rsysnum);
|
|
||||||
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4,10,0) */
|
|
||||||
ret = VM_FAULT_SIGBUS;
|
ret = VM_FAULT_SIGBUS;
|
||||||
goto put_and_out;
|
goto put_and_out;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user