kernel/vm: change pde table info from single buffer to explicit per-process.
makes code in kernel more readable, and allows better sanity checking on using the pde info.
This commit is contained in:
@@ -12,8 +12,6 @@
|
||||
|
||||
#include "proto.h"
|
||||
|
||||
extern u8_t *vm_pagedirs;
|
||||
|
||||
/*===========================================================================*
|
||||
* arch_do_vmctl *
|
||||
*===========================================================================*/
|
||||
@@ -26,13 +24,15 @@ struct proc *p;
|
||||
/* Get process CR3. */
|
||||
m_ptr->SVMCTL_VALUE = p->p_seg.p_cr3;
|
||||
return OK;
|
||||
case VMCTL_I386_SETCR3:
|
||||
case VMCTL_SETADDRSPACE:
|
||||
/* Set process CR3. */
|
||||
if(m_ptr->SVMCTL_VALUE) {
|
||||
p->p_seg.p_cr3 = m_ptr->SVMCTL_VALUE;
|
||||
if(m_ptr->SVMCTL_PTROOT) {
|
||||
p->p_seg.p_cr3 = m_ptr->SVMCTL_PTROOT;
|
||||
p->p_seg.p_cr3_v = (u32_t *) m_ptr->SVMCTL_PTROOT_V;
|
||||
p->p_misc_flags |= MF_FULLVM;
|
||||
} else {
|
||||
p->p_seg.p_cr3 = 0;
|
||||
p->p_seg.p_cr3_v = NULL;
|
||||
p->p_misc_flags &= ~MF_FULLVM;
|
||||
}
|
||||
RTS_UNSET(p, RTS_VMINHIBIT);
|
||||
@@ -48,11 +48,6 @@ struct proc *p;
|
||||
r = prot_set_kern_seg_limit(m_ptr->SVMCTL_VALUE);
|
||||
return r;
|
||||
}
|
||||
case VMCTL_I386_PAGEDIRS:
|
||||
{
|
||||
vm_pagedirs = (u8_t *) m_ptr->SVMCTL_VALUE;
|
||||
return OK;
|
||||
}
|
||||
case VMCTL_I386_FREEPDE:
|
||||
{
|
||||
i386_freepde(m_ptr->SVMCTL_VALUE);
|
||||
|
||||
@@ -28,12 +28,6 @@
|
||||
|
||||
PRIVATE int psok = 0;
|
||||
|
||||
#define PROCPDEPTR(pr, pi) ((u32_t *) ((u8_t *) vm_pagedirs +\
|
||||
I386_PAGE_SIZE * pr->p_nr + \
|
||||
I386_VM_PT_ENT_SIZE * pi))
|
||||
|
||||
PUBLIC u8_t *vm_pagedirs = NULL;
|
||||
|
||||
#define MAX_FREEPDES (3 * CONFIG_MAX_CPUS)
|
||||
PRIVATE int nfreepdes = 0, freepdes[MAX_FREEPDES];
|
||||
|
||||
@@ -90,6 +84,7 @@ PRIVATE phys_bytes createpde(
|
||||
|
||||
assert(free_pde_idx >= 0 && free_pde_idx < nfreepdes);
|
||||
pde = freepdes[free_pde_idx];
|
||||
assert(pde >= 0 && pde < 1024);
|
||||
|
||||
if(pr && ((pr == ptproc) || !HASPT(pr))) {
|
||||
/* Process memory is requested, and
|
||||
@@ -106,7 +101,8 @@ PRIVATE phys_bytes createpde(
|
||||
* accessible directly. Grab the PDE entry of that process'
|
||||
* page table that corresponds to the requested address.
|
||||
*/
|
||||
pdeval = *PROCPDEPTR(pr, I386_VM_PDE(linaddr));
|
||||
assert(pr->p_seg.p_cr3_v);
|
||||
pdeval = pr->p_seg.p_cr3_v[I386_VM_PDE(linaddr)];
|
||||
} else {
|
||||
/* Requested address is physical. Make up the PDE entry. */
|
||||
pdeval = (linaddr & I386_VM_ADDR_MASK_4MB) |
|
||||
@@ -118,8 +114,9 @@ PRIVATE phys_bytes createpde(
|
||||
* can access, into the currently loaded page table so it becomes
|
||||
* visible.
|
||||
*/
|
||||
if(*PROCPDEPTR(ptproc, pde) != pdeval) {
|
||||
*PROCPDEPTR(ptproc, pde) = pdeval;
|
||||
assert(ptproc->p_seg.p_cr3_v);
|
||||
if(ptproc->p_seg.p_cr3_v[pde] != pdeval) {
|
||||
ptproc->p_seg.p_cr3_v[pde] = pdeval;
|
||||
*changed = 1;
|
||||
}
|
||||
|
||||
@@ -155,6 +152,11 @@ PRIVATE int lin_lin_copy(const struct proc *srcproc, vir_bytes srclinaddr,
|
||||
|
||||
assert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES);
|
||||
|
||||
if(srcproc) assert(!RTS_ISSET(srcproc, RTS_SLOT_FREE));
|
||||
if(dstproc) assert(!RTS_ISSET(dstproc, RTS_SLOT_FREE));
|
||||
assert(!RTS_ISSET(ptproc, RTS_SLOT_FREE));
|
||||
assert(ptproc->p_seg.p_cr3_v);
|
||||
|
||||
while(bytes > 0) {
|
||||
phys_bytes srcptr, dstptr;
|
||||
vir_bytes chunk = bytes;
|
||||
@@ -191,6 +193,11 @@ PRIVATE int lin_lin_copy(const struct proc *srcproc, vir_bytes srclinaddr,
|
||||
dstlinaddr += chunk;
|
||||
}
|
||||
|
||||
if(srcproc) assert(!RTS_ISSET(srcproc, RTS_SLOT_FREE));
|
||||
if(dstproc) assert(!RTS_ISSET(dstproc, RTS_SLOT_FREE));
|
||||
assert(!RTS_ISSET(ptproc, RTS_SLOT_FREE));
|
||||
assert(ptproc->p_seg.p_cr3_v);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -677,6 +684,8 @@ int vm_phys_memset(phys_bytes ph, const u8_t c, phys_bytes bytes)
|
||||
|
||||
assert(nfreepdes >= 3);
|
||||
|
||||
assert(ptproc->p_seg.p_cr3_v);
|
||||
|
||||
/* With VM, we have to map in the physical memory.
|
||||
* We can do this 4MB at a time.
|
||||
*/
|
||||
@@ -695,6 +704,7 @@ int vm_phys_memset(phys_bytes ph, const u8_t c, phys_bytes bytes)
|
||||
ph += chunk;
|
||||
}
|
||||
|
||||
assert(ptproc->p_seg.p_cr3_v);
|
||||
|
||||
return OK;
|
||||
}
|
||||
@@ -1004,3 +1014,8 @@ PUBLIC int arch_enable_paging(struct proc * caller, const message * m_ptr)
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
PUBLIC void release_address_space(struct proc *pr)
|
||||
{
|
||||
pr->p_seg.p_cr3_v = NULL;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
FP_SAVE_AREA_P = P_STACKTOP
|
||||
P_LDT_SEL = FP_SAVE_AREA_P + 532
|
||||
P_CR3 = P_LDT_SEL+W
|
||||
P_LDT = P_CR3+W
|
||||
P_CR3_V = P_CR3+4
|
||||
P_LDT = P_CR3_V+W
|
||||
P_MISC_FLAGS = P_LDT + 50
|
||||
Msize = 9 /* size of a message in 32-bit words*/
|
||||
|
||||
|
||||
@@ -182,4 +182,5 @@ _PROTOTYPE( int copy_msg_from_user, (struct proc * p, message * user_mbuf,
|
||||
_PROTOTYPE( int copy_msg_to_user, (struct proc * p, message * src,
|
||||
message * user_mbuf));
|
||||
_PROTOTYPE(void switch_address_space, (struct proc * p));
|
||||
_PROTOTYPE(void release_address_space, (struct proc *pr));
|
||||
#endif /* PROTO_H */
|
||||
|
||||
@@ -31,6 +31,8 @@ PUBLIC int do_clear(struct proc * caller, message * m_ptr)
|
||||
}
|
||||
rc = proc_addr(exit_p); /* clean up */
|
||||
|
||||
release_address_space(rc);
|
||||
|
||||
/* Don't clear if already cleared. */
|
||||
if(isemptyp(rc)) return OK;
|
||||
|
||||
|
||||
@@ -117,6 +117,9 @@ PUBLIC int do_fork(struct proc * caller, message * m_ptr)
|
||||
RTS_UNSET(rpc, (RTS_SIGNALED | RTS_SIG_PENDING | RTS_P_STOP));
|
||||
sigemptyset(&rpc->p_pending);
|
||||
|
||||
rpc->p_seg.p_cr3 = 0;
|
||||
rpc->p_seg.p_cr3_v = NULL;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user