Basic VM and other minor improvements.
Not complete, probably not fully debugged or optimized.
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "../system.h"
|
||||
#include "../vm.h"
|
||||
|
||||
#if USE_UMAP
|
||||
|
||||
@@ -25,8 +26,11 @@ register message *m_ptr; /* pointer to request message */
|
||||
vir_bytes offset = m_ptr->CP_SRC_ADDR;
|
||||
int count = m_ptr->CP_NR_BYTES;
|
||||
int endpt = (int) m_ptr->CP_SRC_ENDPT;
|
||||
int proc_nr;
|
||||
phys_bytes phys_addr;
|
||||
int proc_nr, r;
|
||||
int naughty = 0;
|
||||
phys_bytes phys_addr = 0, lin_addr = 0;
|
||||
int caller_pn;
|
||||
struct proc *targetpr, *caller;
|
||||
|
||||
/* Verify process number. */
|
||||
if (endpt == SELF)
|
||||
@@ -34,27 +38,88 @@ register message *m_ptr; /* pointer to request message */
|
||||
else
|
||||
if (! isokendpt(endpt, &proc_nr))
|
||||
return(EINVAL);
|
||||
targetpr = proc_addr(proc_nr);
|
||||
|
||||
okendpt(who_e, &caller_pn);
|
||||
caller = proc_addr(caller_pn);
|
||||
|
||||
/* See which mapping should be made. */
|
||||
switch(seg_type) {
|
||||
case LOCAL_SEG:
|
||||
phys_addr = umap_local(proc_addr(proc_nr), seg_index, offset, count);
|
||||
phys_addr = lin_addr = umap_local(targetpr, seg_index, offset, count);
|
||||
if(!lin_addr) return EFAULT;
|
||||
CHECKRANGE_OR_SUSPEND(targetpr, lin_addr, count, 1);
|
||||
naughty = 1;
|
||||
break;
|
||||
case REMOTE_SEG:
|
||||
phys_addr = umap_remote(proc_addr(proc_nr), seg_index, offset, count);
|
||||
phys_addr = lin_addr = umap_remote(targetpr, seg_index, offset, count);
|
||||
if(!lin_addr) return EFAULT;
|
||||
CHECKRANGE_OR_SUSPEND(targetpr, lin_addr, count, 1);
|
||||
naughty = 1;
|
||||
break;
|
||||
#if _MINIX_CHIP == _CHIP_INTEL
|
||||
case BIOS_SEG:
|
||||
phys_addr = umap_bios(proc_addr(proc_nr), offset, count);
|
||||
break;
|
||||
#endif
|
||||
case GRANT_SEG:
|
||||
phys_addr = umap_grant(proc_addr(proc_nr), offset, count);
|
||||
naughty = 1;
|
||||
case LOCAL_VM_SEG:
|
||||
if(seg_index == MEM_GRANT || seg_type == GRANT_SEG) {
|
||||
vir_bytes newoffset;
|
||||
endpoint_t newep;
|
||||
int new_proc_nr;
|
||||
|
||||
if(verify_grant(targetpr->p_endpoint, ANY, offset, count, 0, 0,
|
||||
&newoffset, &newep) != OK) {
|
||||
kprintf("SYSTEM: do_umap: verify_grant in %s, grant %d, bytes 0x%lx, failed, caller %s\n", targetpr->p_name, offset, count, caller->p_name);
|
||||
proc_stacktrace(caller);
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
if(!isokendpt(newep, &new_proc_nr)) {
|
||||
kprintf("SYSTEM: do_umap: isokendpt failed\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
/* New lookup. */
|
||||
offset = newoffset;
|
||||
targetpr = proc_addr(new_proc_nr);
|
||||
seg_index = D;
|
||||
}
|
||||
|
||||
if(seg_index == T || seg_index == D || seg_index == S) {
|
||||
phys_addr = lin_addr = umap_local(targetpr, seg_index, offset, count);
|
||||
} else {
|
||||
kprintf("SYSTEM: bogus seg type 0x%lx\n", seg_index);
|
||||
return EFAULT;
|
||||
}
|
||||
if(!lin_addr) {
|
||||
kprintf("SYSTEM:do_umap: umap_local failed\n");
|
||||
return EFAULT;
|
||||
}
|
||||
CHECKRANGE_OR_SUSPEND(targetpr, lin_addr, count, 1);
|
||||
if(vm_lookup(targetpr, lin_addr, &phys_addr, NULL) != OK) {
|
||||
kprintf("SYSTEM:do_umap: vm_lookup failed\n");
|
||||
return EFAULT;
|
||||
}
|
||||
if(phys_addr == 0)
|
||||
minix_panic("vm_lookup returned zero physical address", NO_NUM);
|
||||
break;
|
||||
default:
|
||||
return(EINVAL);
|
||||
if((r=arch_umap(targetpr, offset, count, seg_type, &lin_addr))
|
||||
!= OK)
|
||||
return r;
|
||||
phys_addr = lin_addr;
|
||||
}
|
||||
|
||||
if(vm_running && !vm_contiguous(targetpr, lin_addr, count)) {
|
||||
kprintf("SYSTEM:do_umap: not contiguous\n");
|
||||
return EFAULT;
|
||||
}
|
||||
|
||||
m_ptr->CP_DST_ADDR = phys_addr;
|
||||
if(naughty || phys_addr == 0) {
|
||||
kprintf("kernel: umap 0x%x done by %d / %s, pc 0x%lx, 0x%lx -> 0x%lx\n",
|
||||
seg_type, who_e, caller->p_name, caller->p_reg.pc, offset, phys_addr);
|
||||
kprintf("caller stack: ");
|
||||
proc_stacktrace(caller);
|
||||
}
|
||||
return (phys_addr == 0) ? EFAULT: OK;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user