re-establish kernel assert()s.
use the regular <assert.h> assert() instead of vmassert() in kernel. throw out some #if 0 code. fix a few assert() conditions. enable by default.
This commit is contained in:
parent
88ac328e6b
commit
0937d6c367
|
@ -7,6 +7,7 @@
|
|||
#include "proto.h"
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "../../proc.h"
|
||||
#include "../../proto.h"
|
||||
|
||||
|
@ -21,7 +22,7 @@ void pagefault( struct proc *pr,
|
|||
|
||||
reg_t pagefaultcr2;
|
||||
|
||||
vmassert(frame);
|
||||
assert(frame);
|
||||
|
||||
pagefaultcr2 = read_cr2();
|
||||
|
||||
|
@ -31,7 +32,7 @@ void pagefault( struct proc *pr,
|
|||
#endif
|
||||
|
||||
if(pr->p_seg.p_cr3) {
|
||||
vmassert(pr->p_seg.p_cr3 == read_cr3());
|
||||
assert(pr->p_seg.p_cr3 == read_cr3());
|
||||
}
|
||||
|
||||
in_physcopy = (frame->eip > (vir_bytes) phys_copy) &&
|
||||
|
@ -76,8 +77,8 @@ void pagefault( struct proc *pr,
|
|||
}
|
||||
|
||||
/* Don't schedule this process until pagefault is handled. */
|
||||
vmassert(pr->p_seg.p_cr3 == read_cr3());
|
||||
vmassert(!RTS_ISSET(pr, RTS_PAGEFAULT));
|
||||
assert(pr->p_seg.p_cr3 == read_cr3());
|
||||
assert(!RTS_ISSET(pr, RTS_PAGEFAULT));
|
||||
RTS_SET(pr, RTS_PAGEFAULT);
|
||||
|
||||
/* Save pagefault details, suspend process,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <minix/syslib.h>
|
||||
#include <minix/cpufeature.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <machine/vm.h>
|
||||
|
||||
|
@ -50,6 +51,7 @@ PUBLIC void vm_init(struct proc *newptproc)
|
|||
if(vm_running)
|
||||
panic("vm_init: vm_running");
|
||||
switch_address_space(newptproc);
|
||||
assert(ptproc == newptproc);
|
||||
vm_enable_paging();
|
||||
vm_running = 1;
|
||||
|
||||
|
@ -85,11 +87,11 @@ PUBLIC void vm_init(struct proc *newptproc)
|
|||
int mustinvl; \
|
||||
u32_t pdeval, mask; \
|
||||
phys_bytes offset; \
|
||||
vmassert(psok); \
|
||||
assert(psok); \
|
||||
if(PROC) { \
|
||||
TYPE = TYPEPROCMAP; \
|
||||
vmassert(!iskernelp(PROC)); \
|
||||
vmassert(HASPT(PROC)); \
|
||||
assert(!iskernelp(PROC)); \
|
||||
assert(HASPT(PROC)); \
|
||||
pdeptr = PROCPDEPTR(PROC, proc_pde_index); \
|
||||
pdeval = *pdeptr; \
|
||||
} else { \
|
||||
|
@ -104,15 +106,15 @@ PUBLIC void vm_init(struct proc *newptproc)
|
|||
continue; \
|
||||
*PROCPDEPTR(ptproc, k) = 0; \
|
||||
PDE = k; \
|
||||
vmassert(k >= 0); \
|
||||
vmassert(k < sizeof(dirtypde)*8); \
|
||||
assert(k >= 0); \
|
||||
assert(k < sizeof(dirtypde)*8); \
|
||||
mask = PDEMASK(PDE); \
|
||||
if(dirtypde & mask) \
|
||||
continue; \
|
||||
break; \
|
||||
} \
|
||||
vmassert(PDE != NOPDE); \
|
||||
vmassert(mask); \
|
||||
assert(PDE != NOPDE); \
|
||||
assert(mask); \
|
||||
if(dirtypde & mask) { \
|
||||
mustinvl = TRUE; \
|
||||
} else { \
|
||||
|
@ -131,16 +133,16 @@ PUBLIC void vm_init(struct proc *newptproc)
|
|||
|
||||
#define DONEPDE(PDE) { \
|
||||
if(PDE != NOPDE) { \
|
||||
vmassert(PDE > 0); \
|
||||
vmassert(PDE < sizeof(dirtypde)*8); \
|
||||
assert(PDE > 0); \
|
||||
assert(PDE < sizeof(dirtypde)*8); \
|
||||
dirtypde |= PDEMASK(PDE); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define WIPEPDE(PDE) { \
|
||||
if(PDE != NOPDE) { \
|
||||
vmassert(PDE > 0); \
|
||||
vmassert(PDE < sizeof(dirtypde)*8); \
|
||||
assert(PDE > 0); \
|
||||
assert(PDE < sizeof(dirtypde)*8); \
|
||||
*PROCPDEPTR(ptproc, PDE) = 0; \
|
||||
} \
|
||||
}
|
||||
|
@ -156,16 +158,16 @@ PRIVATE int lin_lin_copy(struct proc *srcproc, vir_bytes srclinaddr,
|
|||
|
||||
NOREC_ENTER(linlincopy);
|
||||
|
||||
vmassert(vm_running);
|
||||
vmassert(nfreepdes >= 3);
|
||||
assert(vm_running);
|
||||
assert(nfreepdes >= 3);
|
||||
|
||||
vmassert(ptproc);
|
||||
vmassert(proc_ptr);
|
||||
vmassert(getcr3val() == ptproc->p_seg.p_cr3);
|
||||
assert(ptproc);
|
||||
assert(proc_ptr);
|
||||
assert(read_cr3() == ptproc->p_seg.p_cr3);
|
||||
|
||||
procslot = ptproc->p_nr;
|
||||
|
||||
vmassert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES);
|
||||
assert(procslot >= 0 && procslot < I386_VM_DIR_ENTRIES);
|
||||
|
||||
while(bytes > 0) {
|
||||
phys_bytes srcptr, dstptr;
|
||||
|
@ -434,7 +436,7 @@ vir_bytes bytes; /* # of bytes to be copied */
|
|||
/* phys must be larger than 0 (or the caller will think the call
|
||||
* failed), and address must not cross a page boundary.
|
||||
*/
|
||||
vmassert(phys);
|
||||
assert(phys);
|
||||
|
||||
return phys;
|
||||
}
|
||||
|
@ -450,9 +452,9 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical,
|
|||
u32_t pde_v, pte_v;
|
||||
NOREC_ENTER(vmlookup);
|
||||
|
||||
vmassert(proc);
|
||||
vmassert(physical);
|
||||
vmassert(!isemptyp(proc));
|
||||
assert(proc);
|
||||
assert(physical);
|
||||
assert(!isemptyp(proc));
|
||||
|
||||
if(!HASPT(proc)) {
|
||||
*physical = virtual;
|
||||
|
@ -461,9 +463,9 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical,
|
|||
|
||||
/* Retrieve page directory entry. */
|
||||
root = (u32_t *) proc->p_seg.p_cr3;
|
||||
vmassert(!((u32_t) root % I386_PAGE_SIZE));
|
||||
assert(!((u32_t) root % I386_PAGE_SIZE));
|
||||
pde = I386_VM_PDE(virtual);
|
||||
vmassert(pde >= 0 && pde < I386_VM_DIR_ENTRIES);
|
||||
assert(pde >= 0 && pde < I386_VM_DIR_ENTRIES);
|
||||
pde_v = phys_get32((u32_t) (root + pde));
|
||||
|
||||
if(!(pde_v & I386_VM_PRESENT)) {
|
||||
|
@ -478,9 +480,9 @@ PUBLIC int vm_lookup(struct proc *proc, vir_bytes virtual, vir_bytes *physical,
|
|||
} else {
|
||||
/* Retrieve page table entry. */
|
||||
pt = (u32_t *) I386_VM_PFA(pde_v);
|
||||
vmassert(!((u32_t) pt % I386_PAGE_SIZE));
|
||||
assert(!((u32_t) pt % I386_PAGE_SIZE));
|
||||
pte = I386_VM_PTE(virtual);
|
||||
vmassert(pte >= 0 && pte < I386_VM_PT_ENTRIES);
|
||||
assert(pte >= 0 && pte < I386_VM_PT_ENTRIES);
|
||||
pte_v = phys_get32((u32_t) (pt + pte));
|
||||
if(!(pte_v & I386_VM_PRESENT)) {
|
||||
NOREC_RETURN(vmlookup, EFAULT);
|
||||
|
@ -505,8 +507,8 @@ PUBLIC int vm_contiguous(struct proc *targetproc, u32_t vir_buf, size_t bytes)
|
|||
u32_t prev_phys = 0; /* Keep lints happy. */
|
||||
u32_t po;
|
||||
|
||||
vmassert(targetproc);
|
||||
vmassert(bytes > 0);
|
||||
assert(targetproc);
|
||||
assert(bytes > 0);
|
||||
|
||||
if(!HASPT(targetproc))
|
||||
return 1;
|
||||
|
@ -561,16 +563,11 @@ PRIVATE void vm_suspend(struct proc *caller, struct proc *target,
|
|||
/* This range is not OK for this process. Set parameters
|
||||
* of the request and notify VM about the pending request.
|
||||
*/
|
||||
vmassert(!RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
vmassert(!RTS_ISSET(target, RTS_VMREQUEST));
|
||||
assert(!RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
assert(!RTS_ISSET(target, RTS_VMREQUEST));
|
||||
|
||||
RTS_SET(caller, RTS_VMREQUEST);
|
||||
|
||||
#if DEBUG_VMASSERT
|
||||
caller->p_vmrequest.stacktrace[0] = '\0';
|
||||
util_stacktrace_strcat(caller->p_vmrequest.stacktrace);
|
||||
#endif
|
||||
|
||||
caller->p_vmrequest.req_type = VMPTYPE_CHECK;
|
||||
caller->p_vmrequest.target = target->p_endpoint;
|
||||
caller->p_vmrequest.params.check.start = linaddr;
|
||||
|
@ -593,20 +590,11 @@ int delivermsg(struct proc *rp)
|
|||
int r;
|
||||
NOREC_ENTER(deliver);
|
||||
|
||||
vmassert(rp->p_misc_flags & MF_DELIVERMSG);
|
||||
vmassert(rp->p_delivermsg.m_source != NONE);
|
||||
assert(rp->p_misc_flags & MF_DELIVERMSG);
|
||||
assert(rp->p_delivermsg.m_source != NONE);
|
||||
|
||||
vmassert(rp->p_delivermsg_lin);
|
||||
#if DEBUG_VMASSERT
|
||||
if(rp->p_delivermsg_lin !=
|
||||
umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message))) {
|
||||
printf("vir: 0x%lx lin was: 0x%lx umap now: 0x%lx\n",
|
||||
rp->p_delivermsg_vir, rp->p_delivermsg_lin,
|
||||
umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message)));
|
||||
panic("that's wrong");
|
||||
}
|
||||
|
||||
#endif
|
||||
assert(rp->p_delivermsg_lin);
|
||||
assert(rp->p_delivermsg_lin == umap_local(rp, D, rp->p_delivermsg_vir, sizeof(message)));
|
||||
|
||||
PHYS_COPY_CATCH(vir2phys(&rp->p_delivermsg),
|
||||
rp->p_delivermsg_lin, sizeof(message), addr);
|
||||
|
@ -616,10 +604,10 @@ int delivermsg(struct proc *rp)
|
|||
VMSTYPE_DELIVERMSG);
|
||||
r = VMSUSPEND;
|
||||
} else {
|
||||
#if DEBUG_VMASSERT
|
||||
/* Indicate message has been delivered; address is 'used'. */
|
||||
rp->p_delivermsg.m_source = NONE;
|
||||
rp->p_delivermsg_lin = 0;
|
||||
#endif
|
||||
|
||||
rp->p_misc_flags &= ~MF_DELIVERMSG;
|
||||
r = OK;
|
||||
}
|
||||
|
@ -649,7 +637,7 @@ PRIVATE void vm_pt_print(u32_t *pagetable, u32_t v)
|
|||
int pte;
|
||||
int col = 0;
|
||||
|
||||
vmassert(!((u32_t) pagetable % I386_PAGE_SIZE));
|
||||
assert(!((u32_t) pagetable % I386_PAGE_SIZE));
|
||||
|
||||
for(pte = 0; pte < I386_VM_PT_ENTRIES; pte++) {
|
||||
u32_t pte_v, pfa;
|
||||
|
@ -672,7 +660,7 @@ PRIVATE void vm_print(u32_t *root)
|
|||
{
|
||||
int pde;
|
||||
|
||||
vmassert(!((u32_t) root % I386_PAGE_SIZE));
|
||||
assert(!((u32_t) root % I386_PAGE_SIZE));
|
||||
|
||||
printf("page table 0x%lx:\n", root);
|
||||
|
||||
|
@ -713,7 +701,7 @@ int vm_phys_memset(phys_bytes ph, u8_t c, phys_bytes bytes)
|
|||
NOREC_RETURN(physmemset, OK);
|
||||
}
|
||||
|
||||
vmassert(nfreepdes >= 3);
|
||||
assert(nfreepdes >= 3);
|
||||
|
||||
/* With VM, we have to map in the physical memory.
|
||||
* We can do this 4MB at a time.
|
||||
|
@ -757,7 +745,7 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
|||
struct proc *procs[2];
|
||||
NOREC_ENTER(virtualcopy);
|
||||
|
||||
vmassert((vmcheck && caller) || (!vmcheck && !caller));
|
||||
assert((vmcheck && caller) || (!vmcheck && !caller));
|
||||
|
||||
/* Check copy count. */
|
||||
if (bytes <= 0) return(EDOM);
|
||||
|
@ -831,13 +819,9 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
|||
int r;
|
||||
|
||||
if(caller && RTS_ISSET(caller, RTS_VMREQUEST)) {
|
||||
vmassert(caller->p_vmrequest.vmresult != VMSUSPEND);
|
||||
assert(caller->p_vmrequest.vmresult != VMSUSPEND);
|
||||
RTS_UNSET(caller, RTS_VMREQUEST);
|
||||
if(caller->p_vmrequest.vmresult != OK) {
|
||||
#if DEBUG_VMASSERT
|
||||
printf("virtual_copy: returning VM error %d\n",
|
||||
caller->p_vmrequest.vmresult);
|
||||
#endif
|
||||
NOREC_RETURN(virtualcopy, caller->p_vmrequest.vmresult);
|
||||
}
|
||||
}
|
||||
|
@ -852,7 +836,7 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
|||
NOREC_RETURN(virtualcopy, r);
|
||||
}
|
||||
|
||||
vmassert(procs[_SRC_] && procs[_DST_]);
|
||||
assert(procs[_SRC_] && procs[_DST_]);
|
||||
|
||||
if(r == EFAULT_SRC) {
|
||||
lin = phys_addr[_SRC_];
|
||||
|
@ -864,22 +848,14 @@ int vmcheck; /* if nonzero, can return VMSUSPEND */
|
|||
panic("r strange: %d", r);
|
||||
}
|
||||
|
||||
#if 0
|
||||
printf("virtual_copy: suspending caller %d / %s, target %d / %s\n",
|
||||
caller->p_endpoint, caller->p_name,
|
||||
target->p_endpoint, target->p_name);
|
||||
#endif
|
||||
|
||||
vmassert(proc_ptr->p_endpoint == SYSTEM);
|
||||
vm_suspend(caller, target, lin, bytes,
|
||||
VMSTYPE_KERNELCALL);
|
||||
vm_suspend(caller, target, lin, bytes, VMSTYPE_KERNELCALL);
|
||||
NOREC_RETURN(virtualcopy, VMSUSPEND);
|
||||
}
|
||||
|
||||
NOREC_RETURN(virtualcopy, OK);
|
||||
}
|
||||
|
||||
vmassert(!vm_running);
|
||||
assert(!vm_running);
|
||||
|
||||
/* can't copy to/from process with PT without VM */
|
||||
#define NOPT(p) (!(p) || !HASPT(p))
|
||||
|
|
|
@ -11,97 +11,101 @@
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#if DEBUG_SCHED_CHECK /* only include code if enabled */
|
||||
|
||||
#define MAX_LOOP (NR_PROCS + NR_TASKS)
|
||||
|
||||
PUBLIC void
|
||||
check_runqueues_f(char *file, int line)
|
||||
PUBLIC int
|
||||
runqueues_ok(void)
|
||||
{
|
||||
int q, l = 0;
|
||||
register struct proc *xp;
|
||||
|
||||
FIXME("check_runqueues being done");
|
||||
|
||||
#define MYPANIC(msg) { \
|
||||
panic("check_runqueues:%s:%d: %s\n", file, line, msg); \
|
||||
}
|
||||
|
||||
for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
|
||||
xp->p_found = 0;
|
||||
if (l++ > MAX_LOOP) { MYPANIC("check error"); }
|
||||
if (l++ > MAX_LOOP) panic("check error");
|
||||
}
|
||||
|
||||
for (q=l=0; q < NR_SCHED_QUEUES; q++) {
|
||||
if (rdy_head[q] && !rdy_tail[q]) {
|
||||
printf("head but no tail in %d\n", q);
|
||||
MYPANIC("scheduling error");
|
||||
return 0;
|
||||
}
|
||||
if (!rdy_head[q] && rdy_tail[q]) {
|
||||
printf("tail but no head in %d\n", q);
|
||||
MYPANIC("scheduling error");
|
||||
return 0;
|
||||
}
|
||||
if (rdy_tail[q] && rdy_tail[q]->p_nextready != NIL_PROC) {
|
||||
printf("tail and tail->next not null in %d\n", q);
|
||||
MYPANIC("scheduling error");
|
||||
return 0;
|
||||
}
|
||||
for(xp = rdy_head[q]; xp != NIL_PROC; xp = xp->p_nextready) {
|
||||
vir_bytes vxp = (vir_bytes) xp, dxp;
|
||||
if(vxp < (vir_bytes) BEG_PROC_ADDR || vxp >= (vir_bytes) END_PROC_ADDR) {
|
||||
MYPANIC("xp out of range");
|
||||
printf("xp out of range\n");
|
||||
return 0;
|
||||
}
|
||||
dxp = vxp - (vir_bytes) BEG_PROC_ADDR;
|
||||
if(dxp % sizeof(struct proc)) {
|
||||
MYPANIC("xp not a real pointer");
|
||||
printf("xp not a real pointer");
|
||||
return 0;
|
||||
}
|
||||
if(xp->p_magic != PMAGIC) {
|
||||
MYPANIC("magic wrong in xp");
|
||||
if(!proc_ptr_ok(xp)) {
|
||||
printf("xp bogus pointer");
|
||||
return 0;
|
||||
}
|
||||
if (RTS_ISSET(xp, RTS_SLOT_FREE)) {
|
||||
printf("scheduling error: dead proc q %d %d\n",
|
||||
q, xp->p_endpoint);
|
||||
MYPANIC("dead proc on run queue");
|
||||
return 0;
|
||||
}
|
||||
if (!xp->p_ready) {
|
||||
if (!proc_is_runnable(xp)) {
|
||||
printf("scheduling error: unready on runq %d proc %d\n",
|
||||
q, xp->p_nr);
|
||||
MYPANIC("found unready process on run queue");
|
||||
return 0;
|
||||
}
|
||||
if (xp->p_priority != q) {
|
||||
printf("scheduling error: wrong priority q %d proc %d ep %d name %s\n",
|
||||
q, xp->p_nr, xp->p_endpoint, xp->p_name);
|
||||
MYPANIC("wrong priority");
|
||||
return 0;
|
||||
}
|
||||
if (xp->p_found) {
|
||||
printf("scheduling error: double sched q %d proc %d\n",
|
||||
q, xp->p_nr);
|
||||
MYPANIC("proc more than once on scheduling queue");
|
||||
return 0;
|
||||
}
|
||||
xp->p_found = 1;
|
||||
if (xp->p_nextready == NIL_PROC && rdy_tail[q] != xp) {
|
||||
printf("sched err: last element not tail q %d proc %d\n",
|
||||
q, xp->p_nr);
|
||||
MYPANIC("scheduling error");
|
||||
return 0;
|
||||
}
|
||||
if (l++ > MAX_LOOP) {
|
||||
printf("loop in schedule queue?");
|
||||
return 0;
|
||||
}
|
||||
if (l++ > MAX_LOOP) MYPANIC("loop in schedule queue?");
|
||||
}
|
||||
}
|
||||
|
||||
l = 0;
|
||||
for (xp = BEG_PROC_ADDR; xp < END_PROC_ADDR; ++xp) {
|
||||
if(xp->p_magic != PMAGIC)
|
||||
MYPANIC("p_magic wrong in proc table");
|
||||
if(!proc_ptr_ok(xp)) {
|
||||
printf("xp bogus pointer in proc table\n");
|
||||
return 0;
|
||||
}
|
||||
if (isemptyp(xp))
|
||||
continue;
|
||||
if(xp->p_ready && ! xp->p_found) {
|
||||
if(proc_is_runnable(xp) && !xp->p_found) {
|
||||
printf("sched error: ready proc %d not on queue\n", xp->p_nr);
|
||||
MYPANIC("ready proc not on scheduling queue");
|
||||
if (l++ > MAX_LOOP) { MYPANIC("loop in debug.c?"); }
|
||||
return 0;
|
||||
if (l++ > MAX_LOOP) {
|
||||
printf("loop in debug.c?\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* DEBUG_SCHED_CHECK */
|
||||
/* All is ok. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
PUBLIC char *
|
||||
rtsflagstr(int flags)
|
||||
|
|
|
@ -24,10 +24,10 @@
|
|||
#define DEBUG_STACKTRACE 1
|
||||
#define DEBUG_TIME_LOCKS 1
|
||||
|
||||
/* Runtime sanity checking. */
|
||||
#define DEBUG_VMASSERT 0
|
||||
#define DEBUG_SCHED_CHECK 0
|
||||
#define DEBUG_STACK_CHECK 0
|
||||
/* Sanity checks. */
|
||||
#define DEBUG_SANITYCHECKS 0
|
||||
|
||||
/* Verbose messages. */
|
||||
#define DEBUG_TRACE 0
|
||||
|
||||
#if DEBUG_TRACE
|
||||
|
@ -46,25 +46,18 @@
|
|||
|
||||
#define NOREC_ENTER(varname) \
|
||||
static int varname = NOTENTERED; \
|
||||
vmassert(varname == ENTERED || varname == NOTENTERED); \
|
||||
vmassert(magictest == MAGICTEST); \
|
||||
vmassert(varname != ENTERED); \
|
||||
assert(varname == ENTERED || varname == NOTENTERED); \
|
||||
assert(magictest == MAGICTEST); \
|
||||
assert(varname != ENTERED); \
|
||||
varname = ENTERED;
|
||||
|
||||
#define NOREC_RETURN(varname, v) do { \
|
||||
vmassert(magictest == MAGICTEST); \
|
||||
vmassert(varname == ENTERED || varname == NOTENTERED); \
|
||||
assert(magictest == MAGICTEST); \
|
||||
assert(varname == ENTERED || varname == NOTENTERED); \
|
||||
varname = NOTENTERED; \
|
||||
return v; \
|
||||
} while(0)
|
||||
|
||||
#if DEBUG_VMASSERT
|
||||
#define vmassert(t) { \
|
||||
if(!(t)) { panic("kernel:%s:%d: assert %s failed", __FILE__, __LINE__, #t); } }
|
||||
#else
|
||||
#define vmassert(t) { }
|
||||
#endif
|
||||
|
||||
#define NOT_REACHABLE do { \
|
||||
panic("NOT_REACHABLE at %s:%d", __FILE__, __LINE__); \
|
||||
for(;;); \
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "kernel.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <a.out.h>
|
||||
#include <minix/com.h>
|
||||
#include <minix/endpoint.h>
|
||||
|
@ -48,9 +49,7 @@ PUBLIC void main()
|
|||
*/
|
||||
for (rp = BEG_PROC_ADDR, i = -NR_TASKS; rp < END_PROC_ADDR; ++rp, ++i) {
|
||||
rp->p_rts_flags = RTS_SLOT_FREE; /* initialize free slot */
|
||||
#if DEBUG_SCHED_CHECK
|
||||
rp->p_magic = PMAGIC;
|
||||
#endif
|
||||
rp->p_nr = i; /* proc number from ptr */
|
||||
rp->p_endpoint = _ENDPOINT(0, rp->p_nr); /* generation no. 0 */
|
||||
}
|
||||
|
@ -251,12 +250,6 @@ PUBLIC void main()
|
|||
* so it's a clear warning no full release should be done with them
|
||||
* enabled.
|
||||
*/
|
||||
#if DEBUG_SCHED_CHECK
|
||||
FIXME("DEBUG_SCHED_CHECK enabled");
|
||||
#endif
|
||||
#if DEBUG_VMASSERT
|
||||
FIXME("DEBUG_VMASSERT enabled");
|
||||
#endif
|
||||
#if DEBUG_PROC_CHECK
|
||||
FIXME("PROC check enabled");
|
||||
#endif
|
||||
|
@ -265,6 +258,8 @@ PUBLIC void main()
|
|||
cycles_accounting_init();
|
||||
DEBUGMAX(("done\n"));
|
||||
|
||||
assert(runqueues_ok());
|
||||
|
||||
restart();
|
||||
NOT_REACHABLE;
|
||||
}
|
||||
|
|
153
kernel/proc.c
153
kernel/proc.c
|
@ -34,6 +34,7 @@
|
|||
#include <stddef.h>
|
||||
#include <signal.h>
|
||||
#include <minix/syslib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "kernel.h"
|
||||
|
@ -86,9 +87,9 @@ PRIVATE int QueueMess(endpoint_t ep, vir_bytes msg_lin, struct proc *dst)
|
|||
* process (using dst process table entry). Do actual copy to
|
||||
* kernel here; it's an error if the copy fails into kernel.
|
||||
*/
|
||||
vmassert(!(dst->p_misc_flags & MF_DELIVERMSG));
|
||||
vmassert(dst->p_delivermsg_lin);
|
||||
vmassert(isokendpt(ep, &k));
|
||||
assert(!(dst->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(dst->p_delivermsg_lin);
|
||||
assert(isokendpt(ep, &k));
|
||||
|
||||
#if 0
|
||||
if(INMEMORY(dst)) {
|
||||
|
@ -184,13 +185,13 @@ not_runnable_pick_new:
|
|||
|
||||
check_misc_flags:
|
||||
|
||||
vmassert(proc_ptr);
|
||||
vmassert(proc_is_runnable(proc_ptr));
|
||||
assert(proc_ptr);
|
||||
assert(proc_is_runnable(proc_ptr));
|
||||
while (proc_ptr->p_misc_flags &
|
||||
(MF_KCALL_RESUME | MF_DELIVERMSG |
|
||||
MF_SC_DEFER | MF_SC_TRACE | MF_SC_ACTIVE)) {
|
||||
|
||||
vmassert(proc_is_runnable(proc_ptr));
|
||||
assert(proc_is_runnable(proc_ptr));
|
||||
if (proc_ptr->p_misc_flags & MF_KCALL_RESUME) {
|
||||
kernel_call_resume(proc_ptr);
|
||||
}
|
||||
|
@ -202,16 +203,13 @@ check_misc_flags:
|
|||
printf("suspending %s / %d\n",
|
||||
proc_ptr->p_name,
|
||||
proc_ptr->p_endpoint););
|
||||
vmassert(!proc_is_runnable(proc_ptr));
|
||||
assert(!proc_is_runnable(proc_ptr));
|
||||
}
|
||||
}
|
||||
else if (proc_ptr->p_misc_flags & MF_SC_DEFER) {
|
||||
/* Perform the system call that we deferred earlier. */
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (proc_ptr->p_misc_flags & MF_SC_ACTIVE)
|
||||
panic("MF_SC_ACTIVE and MF_SC_DEFER set");
|
||||
#endif
|
||||
assert (!(proc_ptr->p_misc_flags & MF_SC_ACTIVE));
|
||||
|
||||
arch_do_syscall(proc_ptr);
|
||||
|
||||
|
@ -286,6 +284,8 @@ long bit_map; /* notification event set or flags */
|
|||
int src_dst_p; /* Process slot number */
|
||||
size_t msg_size;
|
||||
|
||||
assert(!RTS_ISSET(caller_ptr, RTS_SLOT_FREE));
|
||||
|
||||
/* If this process is subject to system call tracing, handle that first. */
|
||||
if (caller_ptr->p_misc_flags & (MF_SC_TRACE | MF_SC_DEFER)) {
|
||||
/* Are we tracing this process, and is it the first sys_call entry? */
|
||||
|
@ -308,44 +308,16 @@ long bit_map; /* notification event set or flags */
|
|||
/* If the MF_SC_DEFER flag is set, the syscall is now being resumed. */
|
||||
caller_ptr->p_misc_flags &= ~MF_SC_DEFER;
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (caller_ptr->p_misc_flags & MF_SC_ACTIVE)
|
||||
panic("MF_SC_ACTIVE already set");
|
||||
#endif
|
||||
assert (!(caller_ptr->p_misc_flags & MF_SC_ACTIVE));
|
||||
|
||||
/* Set a flag to allow reliable tracing of leaving the system call. */
|
||||
caller_ptr->p_misc_flags |= MF_SC_ACTIVE;
|
||||
}
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if(caller_ptr->p_misc_flags & MF_DELIVERMSG) {
|
||||
printf("sys_call: MF_DELIVERMSG on for %s / %d\n",
|
||||
panic("sys_call: MF_DELIVERMSG on for %s / %d\n",
|
||||
caller_ptr->p_name, caller_ptr->p_endpoint);
|
||||
panic("MF_DELIVERMSG on");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
if(src_dst_e != 4 && src_dst_e != 5 &&
|
||||
caller_ptr->p_endpoint != 4 && caller_ptr->p_endpoint != 5) {
|
||||
if(call_nr == SEND)
|
||||
printf("(%d SEND to %d) ", caller_ptr->p_endpoint, src_dst_e);
|
||||
else if(call_nr == RECEIVE)
|
||||
printf("(%d RECEIVE from %d) ", caller_ptr->p_endpoint, src_dst_e);
|
||||
else if(call_nr == SENDREC)
|
||||
printf("(%d SENDREC to %d) ", caller_ptr->p_endpoint, src_dst_e);
|
||||
else
|
||||
printf("(%d %d to/from %d) ", caller_ptr->p_endpoint, call_nr, src_dst_e);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (RTS_ISSET(caller_ptr, RTS_SLOT_FREE))
|
||||
{
|
||||
printf("called by the dead?!?\n");
|
||||
return EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check destination. SENDA is special because its argument is a table and
|
||||
* not a single destination. RECEIVE is the only call that accepts ANY (in
|
||||
|
@ -592,7 +564,7 @@ int flags;
|
|||
*/
|
||||
if (WILLRECEIVE(dst_ptr, caller_ptr->p_endpoint)) {
|
||||
/* Destination is indeed waiting for this message. */
|
||||
vmassert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
if((r=QueueMess(caller_ptr->p_endpoint, linaddr, dst_ptr)) != OK)
|
||||
return r;
|
||||
RTS_UNSET(dst_ptr, RTS_RECEIVING);
|
||||
|
@ -643,7 +615,7 @@ int flags;
|
|||
int i, r, src_id, src_proc_nr, src_p;
|
||||
phys_bytes linaddr;
|
||||
|
||||
vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
|
||||
if(!(linaddr = umap_local(caller_ptr, D, (vir_bytes) m_ptr,
|
||||
sizeof(message)))) {
|
||||
|
@ -695,8 +667,8 @@ int flags;
|
|||
/* Found a suitable source, deliver the notification message. */
|
||||
BuildNotifyMessage(&m, src_proc_nr, caller_ptr); /* assemble message */
|
||||
hisep = proc_addr(src_proc_nr)->p_endpoint;
|
||||
vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
vmassert(src_e == ANY || hisep == src_e);
|
||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(src_e == ANY || hisep == src_e);
|
||||
if((r=QueueMess(hisep, vir2phys(&m), caller_ptr)) != OK) {
|
||||
panic("mini_receive: local QueueMess failed");
|
||||
}
|
||||
|
@ -708,18 +680,11 @@ int flags;
|
|||
xpp = &caller_ptr->p_caller_q;
|
||||
while (*xpp != NIL_PROC) {
|
||||
if (src_e == ANY || src_p == proc_nr(*xpp)) {
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (RTS_ISSET(*xpp, RTS_SLOT_FREE) || RTS_ISSET(*xpp, RTS_NO_ENDPOINT))
|
||||
{
|
||||
printf("%d: receive from %d; found dead %d (%s)?\n",
|
||||
caller_ptr->p_endpoint, src_e, (*xpp)->p_endpoint,
|
||||
(*xpp)->p_name);
|
||||
return EINVAL;
|
||||
}
|
||||
#endif
|
||||
assert(!RTS_ISSET(*xpp, RTS_SLOT_FREE));
|
||||
assert(!RTS_ISSET(*xpp, RTS_NO_ENDPOINT));
|
||||
|
||||
/* Found acceptable message. Copy it and update status. */
|
||||
vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
QueueMess((*xpp)->p_endpoint,
|
||||
vir2phys(&(*xpp)->p_sendmsg), caller_ptr);
|
||||
if ((*xpp)->p_misc_flags & MF_SIG_DELAY)
|
||||
|
@ -791,7 +756,7 @@ endpoint_t dst_e; /* which process to notify */
|
|||
* message is in the kernel's address space.
|
||||
*/
|
||||
BuildNotifyMessage(&m, proc_nr(caller_ptr), dst_ptr);
|
||||
vmassert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(!(dst_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
if((r=QueueMess(caller_ptr->p_endpoint, vir2phys(&m), dst_ptr)) != OK) {
|
||||
panic("mini_notify: local QueueMess failed");
|
||||
}
|
||||
|
@ -955,7 +920,7 @@ PRIVATE int mini_senda(struct proc *caller_ptr, asynmsg_t *table, size_t size)
|
|||
dst_ptr = proc_addr(dst_p);
|
||||
|
||||
/* RTS_NO_ENDPOINT should be removed */
|
||||
if (dst_ptr->p_rts_flags & RTS_NO_ENDPOINT)
|
||||
if (RTS_ISSET(dst_ptr, RTS_NO_ENDPOINT))
|
||||
{
|
||||
tabent.result= EDEADSRCDST;
|
||||
A_INSERT(i, result);
|
||||
|
@ -1029,7 +994,7 @@ struct proc *caller_ptr;
|
|||
|
||||
src_ptr= proc_addr(privp->s_proc_nr);
|
||||
|
||||
vmassert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(!(caller_ptr->p_misc_flags & MF_DELIVERMSG));
|
||||
r= try_one(src_ptr, caller_ptr, &postponed);
|
||||
if (r == OK)
|
||||
return r;
|
||||
|
@ -1163,14 +1128,12 @@ register struct proc *rp; /* this process is now runnable */
|
|||
|
||||
NOREC_ENTER(enqueuefunc);
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (rp->p_ready) panic("enqueue already ready process");
|
||||
#endif
|
||||
assert(proc_is_runnable(rp));
|
||||
|
||||
/* Determine where to insert to process. */
|
||||
sched(rp, &q, &front);
|
||||
|
||||
vmassert(q >= 0);
|
||||
assert(q >= 0);
|
||||
|
||||
/* Now add the process to the queue. */
|
||||
if (rdy_head[q] == NIL_PROC) { /* add to empty queue */
|
||||
|
@ -1187,23 +1150,18 @@ register struct proc *rp; /* this process is now runnable */
|
|||
rp->p_nextready = NIL_PROC; /* mark new end */
|
||||
}
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
rp->p_ready = 1;
|
||||
CHECK_RUNQUEUES;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* enqueueing a process with a higher priority than the current one, it gets
|
||||
* preempted. The current process must be preemptible. Testing the priority
|
||||
* also makes sure that a process does not preempt itself
|
||||
*/
|
||||
vmassert(proc_ptr);
|
||||
assert(proc_ptr && proc_ptr_ok(proc_ptr));
|
||||
if ((proc_ptr->p_priority > rp->p_priority) &&
|
||||
(priv(proc_ptr)->s_flags & PREEMPTIBLE))
|
||||
RTS_SET(proc_ptr, RTS_PREEMPTED); /* calls dequeue() */
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
CHECK_RUNQUEUES;
|
||||
#if DEBUG_SANITYCHECKS
|
||||
assert(runqueues_ok());
|
||||
#endif
|
||||
|
||||
NOREC_RETURN(enqueuefunc, );
|
||||
|
@ -1222,17 +1180,18 @@ PRIVATE void enqueue_head(struct proc *rp)
|
|||
{
|
||||
int q = rp->p_priority; /* scheduling queue to use */
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (rp->p_ready) panic("enqueue already ready process");
|
||||
#endif
|
||||
assert(proc_ptr_ok(rp));
|
||||
assert(proc_is_runnable(rp));
|
||||
|
||||
/*
|
||||
* the process was runnable without its quantum expired when dequeued. A
|
||||
* process with no time left should vahe been handled else and differently
|
||||
*/
|
||||
vmassert(rp->p_ticks_left);
|
||||
#if 0
|
||||
assert(rp->p_ticks_left);
|
||||
#endif
|
||||
|
||||
vmassert(q >= 0);
|
||||
assert(q >= 0);
|
||||
|
||||
|
||||
/* Now add the process to the queue. */
|
||||
|
@ -1244,9 +1203,8 @@ PRIVATE void enqueue_head(struct proc *rp)
|
|||
rp->p_nextready = rdy_head[q]; /* chain head of queue */
|
||||
rdy_head[q] = rp; /* set new queue head */
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
rp->p_ready = 1;
|
||||
CHECK_RUNQUEUES;
|
||||
#if DEBUG_SANITYCHECKS
|
||||
assert(runqueues_ok());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1266,17 +1224,11 @@ register struct proc *rp; /* this process is no longer runnable */
|
|||
|
||||
NOREC_ENTER(dequeuefunc);
|
||||
|
||||
#if DEBUG_STACK_CHECK
|
||||
/* Side-effect for kernel: check if the task's stack still is ok? */
|
||||
if (iskernelp(rp)) {
|
||||
if (*priv(rp)->s_stack_guard != STACK_GUARD)
|
||||
panic("stack overrun by task: %d", proc_nr(rp));
|
||||
}
|
||||
#endif
|
||||
assert(proc_ptr_ok(rp));
|
||||
assert(!proc_is_runnable(rp));
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
if (! rp->p_ready) panic("dequeue() already unready process");
|
||||
#endif
|
||||
/* Side-effect for kernel: check if the task's stack still is ok? */
|
||||
assert (!iskernelp(rp) || *priv(rp)->s_stack_guard == STACK_GUARD);
|
||||
|
||||
/* Now make sure that the process is not in its ready queue. Remove the
|
||||
* process if it is found. A process can be made unready even if it is not
|
||||
|
@ -1284,23 +1236,19 @@ register struct proc *rp; /* this process is no longer runnable */
|
|||
*/
|
||||
prev_xp = NIL_PROC;
|
||||
for (xpp = &rdy_head[q]; *xpp != NIL_PROC; xpp = &(*xpp)->p_nextready) {
|
||||
|
||||
if (*xpp == rp) { /* found process to remove */
|
||||
*xpp = (*xpp)->p_nextready; /* replace with next chain */
|
||||
if (rp == rdy_tail[q]) /* queue tail removed */
|
||||
if (rp == rdy_tail[q]) { /* queue tail removed */
|
||||
rdy_tail[q] = prev_xp; /* set new tail */
|
||||
}
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
rp->p_ready = 0;
|
||||
CHECK_RUNQUEUES;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
prev_xp = *xpp; /* save previous in chain */
|
||||
}
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
CHECK_RUNQUEUES;
|
||||
#if DEBUG_SANITYCHECKS
|
||||
assert(runqueues_ok());
|
||||
#endif
|
||||
|
||||
NOREC_RETURN(dequeuefunc, );
|
||||
|
@ -1362,7 +1310,7 @@ PRIVATE struct proc * pick_proc(void)
|
|||
}
|
||||
TRACE(VF_PICKPROC, printf("found %s / %d on queue %d\n",
|
||||
rp->p_name, rp->p_endpoint, q););
|
||||
vmassert(!proc_is_runnable(rp));
|
||||
assert(proc_is_runnable(rp));
|
||||
if (priv(rp)->s_flags & BILLABLE)
|
||||
bill_ptr = rp; /* bill for system time */
|
||||
return rp;
|
||||
|
@ -1389,10 +1337,17 @@ timer_t *tp; /* watchdog timer pointer */
|
|||
for (rp=BEG_PROC_ADDR; rp<END_PROC_ADDR; rp++) {
|
||||
if (! isemptyp(rp)) { /* check slot use */
|
||||
if (rp->p_priority > rp->p_max_priority) { /* update priority? */
|
||||
if (proc_is_runnable(rp)) dequeue(rp); /* take off queue */
|
||||
int paused = 0;
|
||||
if (proc_is_runnable(rp)) {
|
||||
RTS_SET(rp, RTS_PROC_STOP); /* take off queue */
|
||||
paused = 1;
|
||||
}
|
||||
ticks_added += rp->p_quantum_size; /* do accounting */
|
||||
rp->p_priority -= 1; /* raise priority */
|
||||
if (proc_is_runnable(rp)) enqueue(rp); /* put on queue */
|
||||
if(paused) {
|
||||
RTS_UNSET(rp, RTS_PROC_STOP);
|
||||
assert(proc_is_runnable(rp));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ticks_added += rp->p_quantum_size - rp->p_ticks_left;
|
||||
|
|
|
@ -98,23 +98,14 @@ struct proc {
|
|||
/* VM result when available */
|
||||
int vmresult;
|
||||
|
||||
#if DEBUG_VMASSERT
|
||||
char stacktrace[200];
|
||||
#endif
|
||||
|
||||
/* If the suspended operation is a sys_call, its details are
|
||||
* stored here.
|
||||
*/
|
||||
} p_vmrequest;
|
||||
|
||||
struct proc *next_soft_notify;
|
||||
int p_softnotified;
|
||||
|
||||
#if DEBUG_SCHED_CHECK
|
||||
int p_ready, p_found;
|
||||
int p_found; /* consistency checking variables */
|
||||
#define PMAGIC 0xC0FFEE1
|
||||
int p_magic; /* check validity of proc pointers */
|
||||
#endif
|
||||
int p_magic; /* check validity of proc pointers */
|
||||
|
||||
#if DEBUG_TRACE
|
||||
int p_schedules;
|
||||
|
@ -156,6 +147,7 @@ struct proc {
|
|||
|
||||
#define proc_is_preempted(p) ((p)->p_rts_flags & RTS_PREEMPTED)
|
||||
#define proc_no_quantum(p) ((p)->p_rts_flags & RTS_NO_QUANTUM)
|
||||
#define proc_ptr_ok(p) ((p)->p_magic == PMAGIC)
|
||||
|
||||
/* Macro to return: on which process is a certain process blocked?
|
||||
* return endpoint number (can be ANY) or NONE. It's important to
|
||||
|
@ -184,8 +176,11 @@ struct proc {
|
|||
/* Set flag and dequeue if the process was runnable. */
|
||||
#define RTS_SET(rp, f) \
|
||||
do { \
|
||||
if(proc_is_runnable(rp)) { dequeue(rp); } \
|
||||
(rp)->p_rts_flags |= (f); \
|
||||
int rts = (rp)->p_rts_flags; \
|
||||
(rp)->p_rts_flags |= (f); \
|
||||
if(rts_f_is_runnable(rts) && !proc_is_runnable(rp)) { \
|
||||
dequeue(rp); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Clear flag and enqueue if the process was not runnable but is now. */
|
||||
|
|
|
@ -88,10 +88,7 @@ _PROTOTYPE( void enable_irq, (irq_hook_t *hook) );
|
|||
_PROTOTYPE( int disable_irq, (irq_hook_t *hook) );
|
||||
|
||||
/* debug.c */
|
||||
#if DEBUG_SCHED_CHECK
|
||||
#define CHECK_RUNQUEUES check_runqueues_f(__FILE__, __LINE__)
|
||||
_PROTOTYPE( void check_runqueues_f, (char *file, int line) );
|
||||
#endif
|
||||
_PROTOTYPE( int runqueues_ok, (void) );
|
||||
_PROTOTYPE( char *rtsflagstr, (int flags) );
|
||||
_PROTOTYPE( char *miscflagstr, (int flags) );
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "proc.h"
|
||||
#include "vm.h"
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/sigcontext.h>
|
||||
|
@ -63,8 +64,8 @@ PRIVATE void kernel_call_finish(struct proc * caller, message *msg, int result)
|
|||
* until VM tells us it's allowed. VM has been notified
|
||||
* and we must wait for its reply to restart the call.
|
||||
*/
|
||||
vmassert(RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
vmassert(caller->p_vmrequest.type == VMSTYPE_KERNELCALL);
|
||||
assert(RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
assert(caller->p_vmrequest.type == VMSTYPE_KERNELCALL);
|
||||
caller->p_vmrequest.saved.reqmsg = *msg;
|
||||
caller->p_misc_flags |= MF_KCALL_RESUME;
|
||||
} else {
|
||||
|
@ -536,10 +537,10 @@ PUBLIC void kernel_call_resume(struct proc *caller)
|
|||
{
|
||||
int result;
|
||||
|
||||
vmassert(!RTS_ISSET(p, RTS_SLOT_FREE));
|
||||
vmassert(!RTS_ISSET(p, RTS_VMREQUEST));
|
||||
assert(!RTS_ISSET(caller, RTS_SLOT_FREE));
|
||||
assert(!RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
|
||||
vmassert(p->p_vmrequest.saved.reqmsg.m_source == p->p_endpoint);
|
||||
assert(caller->p_vmrequest.saved.reqmsg.m_source == caller->p_endpoint);
|
||||
|
||||
/*
|
||||
printf("KERNEL_CALL restart from %s / %d rts 0x%08x misc 0x%08x\n",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "../vm.h"
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
|
||||
|
@ -40,7 +41,7 @@ PUBLIC int do_fork(struct proc * caller, message * m_ptr)
|
|||
rpc = proc_addr(m_ptr->PR_SLOT);
|
||||
if (isemptyp(rpp) || ! isemptyp(rpc)) return(EINVAL);
|
||||
|
||||
vmassert(!(rpp->p_misc_flags & MF_DELIVERMSG));
|
||||
assert(!(rpp->p_misc_flags & MF_DELIVERMSG));
|
||||
|
||||
/* needs to be receiving so we know where the message buffer is */
|
||||
if(!RTS_ISSET(rpp, RTS_RECEIVING)) {
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
* SMAP_FLAG access, writable map or not?
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <minix/type.h>
|
||||
#include <minix/safecopies.h>
|
||||
|
||||
|
@ -139,10 +141,10 @@ PUBLIC int map_invoke_vm(struct proc * caller,
|
|||
return EINVAL;
|
||||
}
|
||||
|
||||
vmassert(!RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
vmassert(!RTS_ISSET(caller, RTS_VMREQTARGET));
|
||||
vmassert(!RTS_ISSET(dst, RTS_VMREQUEST));
|
||||
vmassert(!RTS_ISSET(dst, RTS_VMREQTARGET));
|
||||
assert(!RTS_ISSET(caller, RTS_VMREQUEST));
|
||||
assert(!RTS_ISSET(caller, RTS_VMREQTARGET));
|
||||
assert(!RTS_ISSET(dst, RTS_VMREQUEST));
|
||||
assert(!RTS_ISSET(dst, RTS_VMREQTARGET));
|
||||
RTS_SET(caller, RTS_VMREQUEST);
|
||||
RTS_SET(dst, RTS_VMREQTARGET);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "../system.h"
|
||||
#include "../vm.h"
|
||||
#include "../debug.h"
|
||||
#include <assert.h>
|
||||
#include <minix/type.h>
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -33,33 +34,17 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
|||
|
||||
switch(m_ptr->SVMCTL_PARAM) {
|
||||
case VMCTL_CLEAR_PAGEFAULT:
|
||||
assert(RTS_ISSET(p,RTS_PAGEFAULT));
|
||||
RTS_UNSET(p, RTS_PAGEFAULT);
|
||||
return OK;
|
||||
case VMCTL_MEMREQ_GET:
|
||||
/* Send VM the information about the memory request. */
|
||||
if(!(rp = vmrequest))
|
||||
return ESRCH;
|
||||
vmassert(RTS_ISSET(rp, RTS_VMREQUEST));
|
||||
assert(RTS_ISSET(rp, RTS_VMREQUEST));
|
||||
|
||||
#if 0
|
||||
printf("kernel: vm request sent by: %s / %d about %d; 0x%lx-0x%lx, wr %d, stack: %s ",
|
||||
rp->p_name, rp->p_endpoint, rp->p_vmrequest.who,
|
||||
rp->p_vmrequest.start,
|
||||
rp->p_vmrequest.start + rp->p_vmrequest.length,
|
||||
rp->p_vmrequest.writeflag, rp->p_vmrequest.stacktrace);
|
||||
printf("type %d\n", rp->p_vmrequest.type);
|
||||
#endif
|
||||
|
||||
#if DEBUG_VMASSERT
|
||||
okendpt(rp->p_vmrequest.who, &proc_nr);
|
||||
okendpt(rp->p_vmrequest.target, &proc_nr);
|
||||
target = proc_addr(proc_nr);
|
||||
#if 0
|
||||
if(!RTS_ISSET(target, RTS_VMREQTARGET)) {
|
||||
printf("set stack: %s\n", rp->p_vmrequest.stacktrace);
|
||||
panic( "RTS_VMREQTARGET not set for target");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Reply with request fields. */
|
||||
switch(rp->p_vmrequest.req_type) {
|
||||
|
@ -75,9 +60,11 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
|||
m_ptr->SVMCTL_MRG_REQUESTOR =
|
||||
(void *) rp->p_endpoint;
|
||||
break;
|
||||
case VMPTYPE_COWMAP:
|
||||
case VMPTYPE_SMAP:
|
||||
case VMPTYPE_SUNMAP:
|
||||
case VMPTYPE_COWMAP:
|
||||
assert(RTS_ISSET(target,RTS_VMREQTARGET));
|
||||
RTS_UNSET(target, RTS_VMREQTARGET);
|
||||
m_ptr->SVMCTL_MRG_TARGET =
|
||||
rp->p_vmrequest.target;
|
||||
m_ptr->SVMCTL_MRG_ADDR =
|
||||
|
@ -104,27 +91,12 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
|||
|
||||
return rp->p_vmrequest.req_type;
|
||||
case VMCTL_MEMREQ_REPLY:
|
||||
vmassert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
vmassert(p->p_vmrequest.vmresult == VMSUSPEND);
|
||||
assert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
assert(p->p_vmrequest.vmresult == VMSUSPEND);
|
||||
okendpt(p->p_vmrequest.target, &proc_nr);
|
||||
target = proc_addr(proc_nr);
|
||||
p->p_vmrequest.vmresult = m_ptr->SVMCTL_VALUE;
|
||||
vmassert(p->p_vmrequest.vmresult != VMSUSPEND);
|
||||
#if DEBUG_VMASSERT
|
||||
if(p->p_vmrequest.vmresult != OK)
|
||||
printf("SYSTEM: VM replied %d to mem request\n",
|
||||
p->p_vmrequest.vmresult);
|
||||
|
||||
printf("memreq reply: vm request sent by: %s / %d about %d; 0x%lx-0x%lx, wr %d, stack: %s ",
|
||||
p->p_name, p->p_endpoint, p->p_vmrequest.who,
|
||||
p->p_vmrequest.start,
|
||||
p->p_vmrequest.start + p->p_vmrequest.length,
|
||||
p->p_vmrequest.writeflag, p->p_vmrequest.stacktrace);
|
||||
printf("type %d\n", p->p_vmrequest.type);
|
||||
#endif
|
||||
|
||||
vmassert(RTS_ISSET(target, RTS_VMREQTARGET));
|
||||
RTS_UNSET(target, RTS_VMREQTARGET);
|
||||
assert(p->p_vmrequest.vmresult != VMSUSPEND);
|
||||
|
||||
switch(p->p_vmrequest.type) {
|
||||
case VMSTYPE_KERNELCALL:
|
||||
|
@ -135,19 +107,15 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
|||
p->p_misc_flags |= MF_KCALL_RESUME;
|
||||
break;
|
||||
case VMSTYPE_DELIVERMSG:
|
||||
vmassert(p->p_misc_flags & MF_DELIVERMSG);
|
||||
vmassert(p == target);
|
||||
vmassert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
assert(p->p_misc_flags & MF_DELIVERMSG);
|
||||
assert(p == target);
|
||||
assert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
break;
|
||||
case VMSTYPE_MAP:
|
||||
vmassert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
assert(RTS_ISSET(p, RTS_VMREQUEST));
|
||||
break;
|
||||
default:
|
||||
#if DEBUG_VMASSERT
|
||||
printf("suspended with stack: %s\n",
|
||||
p->p_vmrequest.stacktrace);
|
||||
#endif
|
||||
panic( "strange request type: %d",p->p_vmrequest.type);
|
||||
panic("strange request type: %d",p->p_vmrequest.type);
|
||||
}
|
||||
|
||||
RTS_UNSET(p, RTS_VMREQUEST);
|
||||
|
@ -159,15 +127,14 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
|||
vm_init(p);
|
||||
if(!vm_running)
|
||||
panic("do_vmctl: paging enabling failed");
|
||||
vmassert(p->p_delivermsg_lin ==
|
||||
umap_local(p, D, p->p_delivermsg_vir, sizeof(message)));
|
||||
if ((err = arch_enable_paging()) != OK) {
|
||||
return err;
|
||||
}
|
||||
if(newmap(caller, p, (struct mem_map *) m_ptr->SVMCTL_VALUE) != OK)
|
||||
panic("do_vmctl: newmap failed");
|
||||
FIXLINMSG(p);
|
||||
vmassert(p->p_delivermsg_lin);
|
||||
assert(p->p_delivermsg_lin ==
|
||||
umap_local(p, D, p->p_delivermsg_vir, sizeof(message)));
|
||||
return OK;
|
||||
case VMCTL_KERN_PHYSMAP:
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue