From 5f15ec05b29fa0f11f6bd9123c52a3284abce011 Mon Sep 17 00:00:00 2001 From: Erik van der Kouwe Date: Thu, 20 May 2010 08:05:07 +0000 Subject: [PATCH] More system processes, this was not enough for the release script to run on some configurations --- include/minix/sys_config.h | 2 +- include/minix/types.h | 2 + kernel/arch/i386/arch_do_vmctl.c | 4 ++ kernel/arch/i386/memory.c | 26 +++++++++++++ kernel/arch/i386/protect.c | 15 +++++++ kernel/system/do_newmap.c | 8 ++++ kernel/system/do_vmctl.c | 10 ++++- kernel/utility.c | 2 + lib/libc/arch/i386/misc/getprocessor.S | 20 ++++++++++ lib/libsys/kputc.c | 1 + lib/libsys/panic.c | 1 + lib/libsys/sef.c | 13 +++++++ lib/libsys/sef_init.c | 14 +++++++ servers/init/init.c | 14 +++++++ servers/pm/main.c | 10 +++++ servers/rs/main.c | 54 ++++++++++++++++++++++++++ servers/vm/arch/i386/pagetable.c | 47 ++++++++++++++++++++++ servers/vm/exec.c | 30 ++++++++++++++ servers/vm/main.c | 49 ++++++++++++++++++++++- servers/vm/region.c | 19 +++++++++ 20 files changed, 337 insertions(+), 4 deletions(-) diff --git a/include/minix/sys_config.h b/include/minix/sys_config.h index 7505e260a..37083a549 100644 --- a/include/minix/sys_config.h +++ b/include/minix/sys_config.h @@ -15,7 +15,7 @@ #endif #define _NR_PROCS 256 -#define _NR_SYS_PROCS 32 +#define _NR_SYS_PROCS 64 /* Set the CHIP type based on the machine selected. The symbol CHIP is actually * indicative of more than just the CPU. For example, machines for which diff --git a/include/minix/types.h b/include/minix/types.h index 8740ae0d0..e80d74c63 100644 --- a/include/minix/types.h +++ b/include/minix/types.h @@ -130,4 +130,6 @@ typedef char *caddr_t; #endif /* _MINIX || __minix */ +/*XXX*/ void vmmcall(u32_t eax, u32_t ebx, u32_t ecx); + #endif /* _TYPES_H */ diff --git a/kernel/arch/i386/arch_do_vmctl.c b/kernel/arch/i386/arch_do_vmctl.c index a1be5e39d..61086756d 100644 --- a/kernel/arch/i386/arch_do_vmctl.c +++ b/kernel/arch/i386/arch_do_vmctl.c @@ -39,7 +39,9 @@ struct proc *p; return OK; case VMCTL_INCSP: /* Increase process SP. */ +vmmcall(0x12345601, 0, 40); p->p_reg.sp += m_ptr->SVMCTL_VALUE; +vmmcall(0x12345601, 0, 41); return OK; case VMCTL_I386_KERNELLIMIT: { @@ -55,7 +57,9 @@ struct proc *p; } case VMCTL_FLUSHTLB: { +vmmcall(0x12345601, 0, 42); reload_cr3(); +vmmcall(0x12345601, 0, 43); return OK; } } diff --git a/kernel/arch/i386/memory.c b/kernel/arch/i386/memory.c index e3bc551be..6b5419ee5 100644 --- a/kernel/arch/i386/memory.c +++ b/kernel/arch/i386/memory.c @@ -43,11 +43,16 @@ FORWARD _PROTOTYPE( void vm_enable_paging, (void) ); PUBLIC void vm_init(struct proc *newptproc) { +vmmcall(0x12345602, vm_running, 5); if(vm_running) panic("vm_init: vm_running"); +vmmcall(0x12345602, (unsigned) newptproc, 6); switch_address_space(newptproc); +vmmcall(0x12345602, (unsigned) ptproc, 7); assert(ptproc == newptproc); +vmmcall(0x12345602, 0, 8); vm_enable_paging(); +vmmcall(0x12345602, 0, 9); vm_running = 1; } @@ -259,36 +264,49 @@ PRIVATE void vm_enable_paging(void) u32_t cr0, cr4; int pgeok; +vmmcall(0x12345602, 0, 10); psok = _cpufeature(_CPUF_I386_PSE); +vmmcall(0x12345602, psok, 11); pgeok = _cpufeature(_CPUF_I386_PGE); +vmmcall(0x12345602, pgeok, 12); cr0= read_cr0(); +vmmcall(0x12345602, cr0, 13); cr4= read_cr4(); /* First clear PG and PGE flag, as PGE must be enabled after PG. */ +vmmcall(0x12345602, cr4, 14); write_cr0(cr0 & ~I386_CR0_PG); +vmmcall(0x12345602, 0, 15); write_cr4(cr4 & ~(I386_CR4_PGE | I386_CR4_PSE)); +vmmcall(0x12345602, 0, 16); cr0= read_cr0(); +vmmcall(0x12345602, cr0, 17); cr4= read_cr4(); /* Our first page table contains 4MB entries. */ if(psok) cr4 |= I386_CR4_PSE; +vmmcall(0x12345602, cr4, 18); write_cr4(cr4); /* First enable paging, then enable global page flag. */ +vmmcall(0x12345602, 0, 19); cr0 |= I386_CR0_PG; write_cr0(cr0 ); +vmmcall(0x12345602, 0, 20); cr0 |= I386_CR0_WP; write_cr0(cr0); /* May we enable these features? */ +vmmcall(0x12345602, 0, 21); if(pgeok) cr4 |= I386_CR4_PGE; write_cr4(cr4); +vmmcall(0x12345602, 0, 22); } PUBLIC vir_bytes alloc_remote_segment(u32_t *selector, @@ -1012,6 +1030,7 @@ PUBLIC int arch_enable_paging(struct proc * caller, const message * m_ptr) /* * copy the extra data associated with the call from userspace */ +vmmcall(0x12345602, 0, 23); if((r=data_copy(caller->p_endpoint, (vir_bytes)m_ptr->SVMCTL_VALUE, KERNEL, (vir_bytes) &ep_data, sizeof(ep_data))) != OK) { printf("vmctl_enable_paging: data_copy failed! (%d)\n", r); @@ -1022,21 +1041,26 @@ PUBLIC int arch_enable_paging(struct proc * caller, const message * m_ptr) * when turning paging on i386 we also change the segment limits to make * the special mappings requested by the kernel reachable */ +vmmcall(0x12345602, 0, 24); if ((r = prot_set_kern_seg_limit(ep_data.data_seg_limit)) != OK) return r; /* * install the new map provided by the call */ +vmmcall(0x12345602, 0, 25); if (newmap(caller, caller, ep_data.mem_map) != OK) panic("arch_enable_paging: newmap failed"); +vmmcall(0x12345602, 0, 26); FIXLINMSG(caller); +vmmcall(0x12345602, 0, 27); assert(caller->p_delivermsg_lin == umap_local(caller, D, caller->p_delivermsg_vir, sizeof(message))); #ifdef CONFIG_APIC /* if local APIC is enabled */ +vmmcall(0x12345602, 0, 28); if (lapic_addr) { lapic_addr = lapic_addr_vaddr; lapic_eoi_addr = LAPIC_EOI; @@ -1049,9 +1073,11 @@ PUBLIC int arch_enable_paging(struct proc * caller, const message * m_ptr) * lapic address. Bad things would happen. It is unfortunate but such is * life */ +vmmcall(0x12345602, 0, 29); i386_watchdog_start(); #endif +vmmcall(0x12345602, 0, 30); return OK; } diff --git a/kernel/arch/i386/protect.c b/kernel/arch/i386/protect.c index a746b1e5d..3fd61afa5 100644 --- a/kernel/arch/i386/protect.c +++ b/kernel/arch/i386/protect.c @@ -270,25 +270,32 @@ PUBLIC void alloc_segments(register struct proc *rp) phys_bytes data_bytes; int privilege; +/*XXX*/vmmcall(0x12345603, 0, 110); data_bytes = (phys_bytes) (rp->p_memmap[S].mem_vir + rp->p_memmap[S].mem_len) << CLICK_SHIFT; +/*XXX*/vmmcall(0x12345603, 0, 111); if (rp->p_memmap[T].mem_len == 0) code_bytes = data_bytes; /* common I&D, poor protect */ else code_bytes = (phys_bytes) rp->p_memmap[T].mem_len << CLICK_SHIFT; +/*XXX*/vmmcall(0x12345603, 0, 112); privilege = USER_PRIVILEGE; +/*XXX*/vmmcall(0x12345603, 0, 113); init_codeseg(&rp->p_seg.p_ldt[CS_LDT_INDEX], (phys_bytes) rp->p_memmap[T].mem_phys << CLICK_SHIFT, code_bytes, privilege); +/*XXX*/vmmcall(0x12345603, 0, 114); init_dataseg(&rp->p_seg.p_ldt[DS_LDT_INDEX], (phys_bytes) rp->p_memmap[D].mem_phys << CLICK_SHIFT, data_bytes, privilege); +/*XXX*/vmmcall(0x12345603, 0, 115); rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege; rp->p_reg.gs = rp->p_reg.fs = rp->p_reg.ss = rp->p_reg.es = rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege; +/*XXX*/vmmcall(0x12345603, 0, 116); } /*===========================================================================* @@ -428,26 +435,34 @@ PUBLIC int prot_set_kern_seg_limit(const vir_bytes limit) int orig_click; int incr_clicks; +vmmcall(0x12345603, limit, 31); if(limit <= kinfo.data_base) { +vmmcall(0x12345603, kinfo.data_base, 38); printf("prot_set_kern_seg_limit: limit bogus\n"); return EINVAL; } /* Do actual increase. */ +vmmcall(0x12345603, 0, 32); orig_click = kinfo.data_size / CLICK_SIZE; kinfo.data_size = limit - kinfo.data_base; incr_clicks = kinfo.data_size / CLICK_SIZE - orig_click; +vmmcall(0x12345603, 0, 33); prot_init(); /* Increase kernel processes too. */ +vmmcall(0x12345603, 0, 34); for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; ++rp) { +vmmcall(0x12345603, 0, 35); if (isemptyp(rp) || !iskernelp(rp)) continue; rp->p_memmap[S].mem_len += incr_clicks; +vmmcall(0x12345603, 0, 36); alloc_segments(rp); rp->p_memmap[S].mem_len -= incr_clicks; } +vmmcall(0x12345603, 0, 37); return OK; } diff --git a/kernel/system/do_newmap.c b/kernel/system/do_newmap.c index 016a0f90f..adf3f5a63 100644 --- a/kernel/system/do_newmap.c +++ b/kernel/system/do_newmap.c @@ -20,11 +20,16 @@ PUBLIC int do_newmap(struct proc * caller, message * m_ptr) struct mem_map *map_ptr; /* virtual address of map inside caller */ int proc_nr; +/*XXX*/vmmcall(0x12345604, 0, 100); map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR; +/*XXX*/vmmcall(0x12345604, 0, 101); if (! isokendpt(m_ptr->PR_ENDPT, &proc_nr)) return(EINVAL); +/*XXX*/vmmcall(0x12345604, 0, 102); if (iskerneln(proc_nr)) return(EPERM); +/*XXX*/vmmcall(0x12345604, 0, 103); rp = proc_addr(proc_nr); +/*XXX*/vmmcall(0x12345604, 0, 104); return newmap(caller, rp, map_ptr); } @@ -36,13 +41,16 @@ PUBLIC int newmap(struct proc *caller, struct proc *rp, struct mem_map *map_ptr) { int r; /* Fetch the memory map. */ +/*XXX*/vmmcall(0x12345604, 0, 105); if((r=data_copy(caller->p_endpoint, (vir_bytes) map_ptr, KERNEL, (vir_bytes) rp->p_memmap, sizeof(rp->p_memmap))) != OK) { printf("newmap: data_copy failed! (%d)\n", r); return r; } +/*XXX*/vmmcall(0x12345604, 0, 106); alloc_segments(rp); +/*XXX*/vmmcall(0x12345604, 0, 107); return(OK); } diff --git a/kernel/system/do_vmctl.c b/kernel/system/do_vmctl.c index b18cbde6e..53f9ccaaf 100644 --- a/kernel/system/do_vmctl.c +++ b/kernel/system/do_vmctl.c @@ -18,7 +18,7 @@ *===========================================================================*/ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) { - int proc_nr; + int proc_nr, r; endpoint_t ep = m_ptr->SVMCTL_WHO; struct proc *p, *rp, *target; @@ -121,12 +121,18 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr) return OK; case VMCTL_ENABLE_PAGING: +vmmcall(0x12345605, vm_running, 1); if(vm_running) panic("do_vmctl: paging already enabled"); +vmmcall(0x12345605, (unsigned) p, 2); vm_init(p); +vmmcall(0x12345605, vm_running, 3); if(!vm_running) panic("do_vmctl: paging enabling failed"); - return arch_enable_paging(caller, m_ptr); +vmmcall(0x12345605, (unsigned) caller, 4); + r = arch_enable_paging(caller, m_ptr); +vmmcall(0x12345605, r, 39); + return r; case VMCTL_KERN_PHYSMAP: { int i = m_ptr->SVMCTL_VALUE; diff --git a/kernel/utility.c b/kernel/utility.c index 5a1cf4fc8..011f96632 100644 --- a/kernel/utility.c +++ b/kernel/utility.c @@ -22,6 +22,7 @@ PUBLIC void panic(const char *fmt, ...) { va_list arg; /* The system has run aground of a fatal kernel error. Terminate execution. */ +/*XXX*/vmmcall(0x12345610, ((unsigned *) &fmt)[-1], 1); if (minix_panicing == ARE_PANICING) { arch_monitor(); } @@ -49,6 +50,7 @@ int c; /* character to append */ /* Accumulate a single character for a kernel message. Send a notification * to the output driver if an END_OF_KMESS is encountered. */ +/*XXX*/vmmcall(0x12345612, c, 1); if (c != END_OF_KMESS) { if (do_serial_debug) { if(c == '\n') diff --git a/lib/libc/arch/i386/misc/getprocessor.S b/lib/libc/arch/i386/misc/getprocessor.S index f4b893b1b..e7386b34c 100644 --- a/lib/libc/arch/i386/misc/getprocessor.S +++ b/lib/libc/arch/i386/misc/getprocessor.S @@ -53,3 +53,23 @@ flip: xorl %edx, %eax /* See if the bit changed */ testl %ecx, %eax ret + +.globl _vmmcall +_vmmcall: + push %ebp + mov %esp, %ebp + push %eax + push %ebx + push %ecx + push %edx + movl 8(%ebp), %eax + movl 12(%ebp), %ebx + movl 16(%ebp), %ecx + movl 4(%ebp), %edx +.byte 0x0F, 0x01, 0xD9 + pop %edx + pop %ecx + pop %ebx + pop %eax + pop %ebp + ret diff --git a/lib/libsys/kputc.c b/lib/libsys/kputc.c index 2f6d7135a..632f298a8 100644 --- a/lib/libsys/kputc.c +++ b/lib/libsys/kputc.c @@ -19,6 +19,7 @@ void kputc(int c) /* Accumulate another character. If 0 or buffer full, print it. */ static int buf_count; /* # characters in the buffer */ +/*XXX*/vmmcall(0x12345613, c, 1); if ((c == 0 && buf_count > 0) || buf_count == sizeof(print_buf)) { sys_sysctl(SYSCTL_CODE_DIAG, print_buf, buf_count); buf_count = 0; diff --git a/lib/libsys/panic.c b/lib/libsys/panic.c index 464101d81..6b2d668a8 100644 --- a/lib/libsys/panic.c +++ b/lib/libsys/panic.c @@ -21,6 +21,7 @@ PUBLIC void panic(const char *fmt, ...) static int panicing= 0; va_list args; +/*XXX*/vmmcall(0x12345611, ((unsigned *) &fmt)[-1], 1); if(panicing) return; panicing= 1; diff --git a/lib/libsys/sef.c b/lib/libsys/sef.c index 6e8d920d6..687e115f6 100644 --- a/lib/libsys/sef.c +++ b/lib/libsys/sef.c @@ -41,7 +41,9 @@ PUBLIC void sef_startup() int r, status; /* Get information about self. */ +/*XXX*/vmmcall(0x12345606, 0, 1); r = sys_whoami(&sef_self_endpoint, sef_self_name, SEF_SELF_NAME_MAXLEN); +/*XXX*/vmmcall(0x12345606, r, 2); if ( r != OK) { sef_self_endpoint = SELF; sprintf(sef_self_name, "%s", "Unknown"); @@ -49,6 +51,7 @@ PUBLIC void sef_startup() #if INTERCEPT_SEF_INIT_REQUESTS /* Intercept SEF Init requests. */ +/*XXX*/vmmcall(0x12345606, sef_self_endpoint, 3); if(sef_self_endpoint == RS_PROC_NR) { if((r = do_sef_rs_init()) != OK) { panic("unable to complete init: %d", r); @@ -57,20 +60,30 @@ PUBLIC void sef_startup() else { message m; +/*XXX*/vmmcall(0x12345606, 0, 4); r = receive(RS_PROC_NR, &m, &status); +/*XXX*/vmmcall(0x12345606, r, 5); +/*XXX*/vmmcall(0x12345606, status, 6); +/*XXX*/vmmcall(0x12345606, m.m_type, 7); if(r != OK) { panic("unable to receive from RS: %d", r); } +/*XXX*/vmmcall(0x12345606, 0, 8); if(IS_SEF_INIT_REQUEST(&m)) { +/*XXX*/vmmcall(0x12345606, 0, 9); if((r = do_sef_init_request(&m)) != OK) { panic("unable to process init request: %d", r); } +/*XXX*/vmmcall(0x12345606, 0, 10); } else { +/*XXX*/vmmcall(0x12345606, 0, 11); panic("got an unexpected message type %d", m.m_type); } +/*XXX*/vmmcall(0x12345606, 0, 12); } #endif +/*XXX*/vmmcall(0x12345606, 0, 13); } /*===========================================================================* diff --git a/lib/libsys/sef_init.c b/lib/libsys/sef_init.c index f06a04e47..acccbbac1 100644 --- a/lib/libsys/sef_init.c +++ b/lib/libsys/sef_init.c @@ -40,6 +40,7 @@ PUBLIC int do_sef_init_request(message *m_ptr) sef_init_info_t info; /* Debug. */ +/*XXX*/vmmcall(0x12345607, 0, 14); #if SEF_INIT_DEBUG sef_init_debug_begin(); sef_init_dprint("%s. Got a SEF Init request of type: %d. About to init.\n", @@ -48,29 +49,40 @@ PUBLIC int do_sef_init_request(message *m_ptr) #endif /* Let the callback code handle the request. */ +/*XXX*/vmmcall(0x12345607, 0, 15); type = m_ptr->RS_INIT_TYPE; +/*XXX*/vmmcall(0x12345607, type, 16); info.rproctab_gid = m_ptr->RS_INIT_RPROCTAB_GID; info.old_endpoint = m_ptr->RS_INIT_OLD_ENDPOINT; switch(type) { case SEF_INIT_FRESH: +/*XXX*/vmmcall(0x12345607, 0, 17); r = sef_cbs.sef_cb_init_fresh(type, &info); +/*XXX*/vmmcall(0x12345607, r, 18); break; case SEF_INIT_LU: +/*XXX*/vmmcall(0x12345607, 0, 19); r = sef_cbs.sef_cb_init_lu(type, &info); +/*XXX*/vmmcall(0x12345607, r, 20); break; case SEF_INIT_RESTART: +/*XXX*/vmmcall(0x12345607, 0, 21); r = sef_cbs.sef_cb_init_restart(type, &info); +/*XXX*/vmmcall(0x12345607, r, 22); break; default: /* Not a valid SEF init type. */ +/*XXX*/vmmcall(0x12345607, 0, 23); r = EINVAL; break; } /* Report back to RS. */ m_ptr->RS_INIT_RESULT = r; +/*XXX*/vmmcall(0x12345607, 0, 24); r = sendrec(RS_PROC_NR, m_ptr); +/*XXX*/vmmcall(0x12345607, 0, 25); return r; } @@ -81,7 +93,9 @@ PUBLIC int do_sef_init_request(message *m_ptr) PUBLIC void sef_setcb_init_fresh(sef_cb_init_t cb) { assert(cb != NULL); +/*XXX*/vmmcall(0x12345607, (unsigned) cb, 26); sef_cbs.sef_cb_init_fresh = cb; +/*XXX*/vmmcall(0x12345607, 0, 27); } /*===========================================================================* diff --git a/servers/init/init.c b/servers/init/init.c index af3cb2159..b58f3f8ad 100644 --- a/servers/init/init.c +++ b/servers/init/init.c @@ -75,6 +75,7 @@ int main(void) struct sigaction sa; struct stat stb; +/*XXX*/vmmcall(0x12345608, 0, 1); #define OPENFDS \ if (fstat(0, &stb) < 0) { \ /* Open standard input, output & error. */ \ @@ -83,6 +84,7 @@ int main(void) dup(1); \ } +/*XXX*/vmmcall(0x12345608, 0, 2); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; @@ -105,11 +107,15 @@ int main(void) sigaction(SIGABRT, &sa, NULL); /* Execute the /etc/rc file. */ +/*XXX*/vmmcall(0x12345608, 0, 3); if ((pid = fork()) != 0) { +/*XXX*/vmmcall(0x12345608, 0, 4); /* Parent just waits. */ while (wait(NULL) != pid) { +/*XXX*/vmmcall(0x12345608, 0, 5); if (gotabrt) reboot(RBT_HALT); } +/*XXX*/vmmcall(0x12345608, 0, 6); } else { #if ! SYS_GETKENV struct sysgetenv sysgetenv; @@ -118,6 +124,7 @@ int main(void) static char *rc_command[] = { "sh", "/etc/rc", NULL, NULL, NULL }; char **rcp = rc_command + 2; +/*XXX*/vmmcall(0x12345608, 0, 7); /* Get the boot options from the boot environment. */ sysgetenv.key = "bootopts"; sysgetenv.keylen = 8+1; @@ -126,11 +133,14 @@ int main(void) if (svrctl(MMGETPARAM, &sysgetenv) == 0) *rcp++ = bootopts; *rcp = "start"; +/*XXX*/vmmcall(0x12345608, 0, 8); execute(rc_command); +/*XXX*/vmmcall(0x12345608, 0, 9); report(2, "sh /etc/rc"); _exit(1); /* impossible, we hope */ } +/*XXX*/vmmcall(0x12345608, 0, 10); OPENFDS; /* Clear /etc/utmp if it exists. */ @@ -148,7 +158,9 @@ int main(void) check = 1; while (1) { +/*XXX*/vmmcall(0x12345608, 0, 11); while ((pid = waitpid(-1, NULL, check ? WNOHANG : 0)) > 0) { +/*XXX*/vmmcall(0x12345608, 0, 12); /* Search to see which line terminated. */ for (linenr = 0; linenr < PIDSLOTS; linenr++) { slotp = &slots[linenr]; @@ -160,6 +172,7 @@ int main(void) } } } +/*XXX*/vmmcall(0x12345608, 0, 13); /* If a signal 1 (SIGHUP) is received, simply reset error counts. */ if (gothup) { @@ -193,6 +206,7 @@ int main(void) endttyent(); } check = 0; +/*XXX*/vmmcall(0x12345608, 0, 14); } } diff --git a/servers/pm/main.c b/servers/pm/main.c index d2a55320c..81f18e9d5 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -64,17 +64,22 @@ PUBLIC int main() sigset_t sigset; /* SEF local startup. */ +/*XXX*/vmmcall(0x12345609, 0, 1); sef_local_startup(); +/*XXX*/vmmcall(0x12345609, 0, 2); sched_init(); /* initialize user-space scheduling */ /* This is PM's main loop- get work and do it, forever and forever. */ +/*XXX*/vmmcall(0x12345609, 0, 3); while (TRUE) { int ipc_status; /* Wait for the next message and extract useful information from it. */ +/*XXX*/vmmcall(0x12345609, 0, 4); if (sef_receive_status(ANY, &m_in, &ipc_status) != OK) panic("PM sef_receive_status error"); who_e = m_in.m_source; /* who sent the message */ +/*XXX*/vmmcall(0x12345609, m_in.m_type, 5); if(pm_isokendpt(who_e, &who_p) != OK) panic("PM got message from invalid endpoint: %d", who_e); call_nr = m_in.m_type; /* system call number */ @@ -83,6 +88,7 @@ PUBLIC int main() * calling. This can happen in case of synchronous alarms (CLOCK) or or * event like pending kernel signals (SYSTEM). */ +/*XXX*/vmmcall(0x12345609, call_nr, 6); mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p]; if(who_p >= 0 && mp->mp_endpoint != who_e) { panic("PM endpoint number out of sync with source: %d", @@ -90,6 +96,7 @@ PUBLIC int main() } /* Drop delayed calls from exiting processes. */ +/*XXX*/vmmcall(0x12345609, 0, 7); if (mp->mp_flags & EXITING) continue; @@ -110,6 +117,7 @@ PUBLIC int main() continue; } +/*XXX*/vmmcall(0x12345609, 0, 8); switch(call_nr) { case PM_SETUID_REPLY: @@ -149,8 +157,10 @@ PUBLIC int main() } /* Send reply. */ +/*XXX*/vmmcall(0x12345609, result, 9); if (result != SUSPEND) setreply(who_p, result); sendreply(); +/*XXX*/vmmcall(0x12345609, 0, 10); } return(OK); } diff --git a/servers/rs/main.c b/servers/rs/main.c index 58f5af3be..dff7a9eca 100644 --- a/servers/rs/main.c +++ b/servers/rs/main.c @@ -51,11 +51,14 @@ PUBLIC int main(void) int result; /* result to return */ /* SEF local startup. */ +/*XXX*/vmmcall(0x1234560a, 0, 1); sef_local_startup(); /* Main loop - get work and do it, forever. */ +/*XXX*/vmmcall(0x1234560a, 0, 2); while (TRUE) { +/*XXX*/vmmcall(0x1234560a, 0, 3); /* Wait for request message. */ get_work(&m, &ipc_status); who_e = m.m_source; @@ -63,6 +66,7 @@ PUBLIC int main(void) panic("message from bogus source: %d", who_e); } +/*XXX*/vmmcall(0x1234560a, m.m_type, 4); call_nr = m.m_type; /* Now determine what to do. Four types of requests are expected: @@ -75,6 +79,7 @@ PUBLIC int main(void) /* Notification messages are control messages and do not need a reply. * These include heartbeat messages and system notifications. */ +/*XXX*/vmmcall(0x1234560a, call_nr, 5); if (is_ipc_notify(ipc_status)) { switch (who_p) { case CLOCK: @@ -104,6 +109,7 @@ PUBLIC int main(void) } /* Handler functions are responsible for permission checking. */ +/*XXX*/vmmcall(0x1234560a, 0, 6); switch(call_nr) { /* User requests. */ case RS_UP: result = do_up(&m); break; @@ -123,11 +129,13 @@ PUBLIC int main(void) result = EINVAL; } +/*XXX*/vmmcall(0x1234560a, result, 7); /* Finally send reply message, unless disabled. */ if (result != EDONTREPLY) { m.m_type = result; reply(who_e, &m); } +/*XXX*/vmmcall(0x1234560a, 0, 8); } } } @@ -138,14 +146,19 @@ PUBLIC int main(void) PRIVATE void sef_local_startup() { /* Register init callbacks. */ +/*XXX*/vmmcall(0x1234560a, 9, 9); sef_setcb_init_fresh(sef_cb_init_fresh); /* RS can only start fresh. */ /* Register signal callbacks. */ +/*XXX*/vmmcall(0x1234560a, 10, 10); sef_setcb_signal_handler(sef_cb_signal_handler); +/*XXX*/vmmcall(0x1234560a, 11, 11); sef_setcb_signal_manager(sef_cb_signal_manager); +/*XXX*/vmmcall(0x1234560a, 12, 12); /* Let SEF perform startup. */ sef_startup(); +/*XXX*/vmmcall(0x1234560a, 13, 13); } /*===========================================================================* @@ -167,19 +180,24 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) struct boot_image_dev *boot_image_dev; /* See if we run in verbose mode. */ +/*XXX*/vmmcall(0x1234560a, 14, 14); env_parse("rs_verbose", "d", 0, &rs_verbose, 0, 1); +/*XXX*/vmmcall(0x1234560a, 15, 15); if ((s = sys_getinfo(GET_HZ, &system_hz, sizeof(system_hz), 0, 0)) != OK) panic("Cannot get system timer frequency\n"); /* Initialize the global init descriptor. */ +/*XXX*/vmmcall(0x1234560a, 16, 16); rinit.rproctab_gid = cpf_grant_direct(ANY, (vir_bytes) rprocpub, sizeof(rprocpub), CPF_READ); +/*XXX*/vmmcall(0x1234560a, 17, 17); if(!GRANT_VALID(rinit.rproctab_gid)) { panic("unable to create rprocpub table grant: %d", rinit.rproctab_gid); } /* Initialize some global variables. */ +/*XXX*/vmmcall(0x1234560a, 18, 18); rupdate.flags = 0; shutting_down = FALSE; @@ -187,6 +205,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) if ((s = sys_getimage(image)) != OK) { panic("unable to get copy of boot image table: %d", s); } +/*XXX*/vmmcall(0x1234560a, 19, 19); /* Determine the number of system services in the boot image table and * compute the size required for the boot image buffer. @@ -197,18 +216,21 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) ip = &image[i]; /* System services only. */ +/*XXX*/vmmcall(0x1234560a, 20, 20); if(iskerneln(_ENDPOINT_P(ip->endpoint))) { continue; } nr_image_srvs++; /* Lookup the corresponding entry in the boot image sys table. */ +/*XXX*/vmmcall(0x1234560a, 21, 21); boot_image_info_lookup(ip->endpoint, image, NULL, NULL, &boot_image_sys, NULL); /* If we must keep a copy of this system service, read the header * and increase the size of the boot image buffer. */ +/*XXX*/vmmcall(0x1234560a, 22, 22); if(boot_image_sys->flags & SF_USE_REPL) { boot_image_sys->flags |= SF_USE_COPY; } @@ -219,11 +241,13 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) boot_image_buffer_size += header.a_hdrlen + header.a_text + header.a_data; } +/*XXX*/vmmcall(0x1234560a, 23, 23); } /* Determine the number of entries in the boot image priv table and make sure * it matches the number of system services in the boot image table. */ +/*XXX*/vmmcall(0x1234560a, 24, 24); nr_image_priv_srvs = 0; for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; @@ -239,6 +263,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) } /* Allocate boot image buffer. */ +/*XXX*/vmmcall(0x1234560a, 25, 25); if(boot_image_buffer_size > 0) { boot_image_buffer = rs_startup_sbrk(boot_image_buffer_size); if(boot_image_buffer == (char *) -1) { @@ -247,6 +272,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) } /* Reset the system process table. */ +/*XXX*/vmmcall(0x1234560a, 26, 26); for (rp=BEG_RPROC_ADDR; rpr_flags = 0; rp->r_pub = &rprocpub[rp - rproc]; @@ -260,10 +286,12 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) * In addition, set priviliges, sys properties, and dev properties (if any) * for every system service. */ +/*XXX*/vmmcall(0x1234560a, 27, 27); for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ +/*XXX*/vmmcall(0x1234560a, 28, 28); if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { continue; } @@ -277,6 +305,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* * Get a copy of the executable image if required. */ +/*XXX*/vmmcall(0x1234560a, 29, 29); rp->r_exec_len = 0; rp->r_exec = NULL; if(boot_image_sys->flags & SF_USE_COPY) { @@ -293,6 +322,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) rpub->period = boot_image_priv->period; if(boot_image_priv->endpoint != RS_PROC_NR) { +/*XXX*/vmmcall(0x1234560a, 30, 30); /* Force a static priv id for system services in the boot image. */ rp->r_priv.s_id = static_priv_id( _ENDPOINT_P(boot_image_priv->endpoint)); @@ -309,13 +339,16 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) rp->r_priv.s_k_call_mask, KERNEL_CALL, TRUE); /* Set the privilege structure. */ +/*XXX*/vmmcall(0x1234560a, 31, 31); if ((s = sys_privctl(ip->endpoint, SYS_PRIV_SET_SYS, &(rp->r_priv))) != OK) { panic("unable to set privilege structure: %d", s); } +/*XXX*/vmmcall(0x1234560a, 32, 32); } /* Synch the privilege structure with the kernel. */ +/*XXX*/vmmcall(0x1234560a, 33, 33); if ((s = sys_getpriv(&(rp->r_priv), ip->endpoint)) != OK) { panic("unable to synch privilege structure: %d", s); } @@ -323,6 +356,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* * Set sys properties. */ +/*XXX*/vmmcall(0x1234560a, 34, 34); rpub->sys_flags = boot_image_sys->flags; /* sys flags */ /* @@ -342,6 +376,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) build_cmd_dep(rp); /* Initialize vm call mask bitmap from unordered set. */ +/*XXX*/vmmcall(0x1234560a, 35, 35); fill_call_mask(boot_image_priv->vm_calls, NR_VM_CALLS, rpub->vm_call_mask, VM_RQ_BASE, TRUE); @@ -365,12 +400,15 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) rp->r_flags = RS_IN_USE | RS_ACTIVE; rproc_ptr[_ENDPOINT_P(rpub->endpoint)]= rp; rpub->in_use = TRUE; +/*XXX*/vmmcall(0x1234560a, 36, 36); } /* - Step 2: allow every system service in the boot image to run. */ nr_uncaught_init_srvs = 0; +/*XXX*/vmmcall(0x1234560a, 37, 37); for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { +/*XXX*/vmmcall(0x1234560a, 38, 38); boot_image_priv = &boot_image_priv_table[i]; /* System services only. */ @@ -388,6 +426,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) rpub = rp->r_pub; /* Allow the service to run. */ +/*XXX*/vmmcall(0x1234560a, 39, 39); if ((s = sys_privctl(rpub->endpoint, SYS_PRIV_ALLOW, NULL)) != OK) { panic("unable to initialize privileges: %d", s); } @@ -395,10 +434,13 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* Initialize service. We assume every service will always get * back to us here at boot time. */ +/*XXX*/vmmcall(0x1234560a, 40, 40); if(boot_image_priv->flags & SYS_PROC) { +/*XXX*/vmmcall(0x1234560a, 41, 41); if ((s = init_service(rp, SEF_INIT_FRESH)) != OK) { panic("unable to initialize service: %d", s); } +/*XXX*/vmmcall(0x1234560a, 42, 42); if(rpub->sys_flags & SF_SYNCH_BOOT) { /* Catch init ready message now to synchronize. */ catch_boot_init_ready(rpub->endpoint); @@ -407,13 +449,17 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* Catch init ready message later. */ nr_uncaught_init_srvs++; } +/*XXX*/vmmcall(0x1234560a, 43, 43); } +/*XXX*/vmmcall(0x1234560a, 44, 44); } /* - Step 3: let every system service complete initialization by * catching all the init ready messages left. */ +/*XXX*/vmmcall(0x1234560a, 45, 45); while(nr_uncaught_init_srvs) { +/*XXX*/vmmcall(0x1234560a, 46, 46); catch_boot_init_ready(ANY); nr_uncaught_init_srvs--; } @@ -422,11 +468,14 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) * Complete the initialization of the system process table in collaboration * with other system services. */ +/*XXX*/vmmcall(0x1234560a, 47, 47); if ((s = getsysinfo(PM_PROC_NR, SI_PROC_TAB, mproc)) != OK) { panic("unable to get copy of PM process table: %d", s); } +/*XXX*/vmmcall(0x1234560a, 48, 48); for (i=0; boot_image_priv_table[i].endpoint != NULL_BOOT_NR; i++) { boot_image_priv = &boot_image_priv_table[i]; +/*XXX*/vmmcall(0x1234560a, 49, 49); /* System services only. */ if(iskerneln(_ENDPOINT_P(boot_image_priv->endpoint))) { @@ -456,6 +505,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) } } } +/*XXX*/vmmcall(0x1234560a, 50, 50); /* * Now complete RS initialization process in collaboration with other @@ -463,15 +513,18 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) */ /* Let the rest of the system know about our dynamically allocated buffer. */ if(boot_image_buffer_size > 0) { +/*XXX*/vmmcall(0x1234560a, 51, 51); boot_image_buffer = rs_startup_sbrk_synch(boot_image_buffer_size); if(boot_image_buffer == (char *) -1) { panic("unable to synch boot image buffer"); } } +/*XXX*/vmmcall(0x1234560a, 52, 52); /* Set alarm to periodically check service status. */ if (OK != (s=sys_setalarm(RS_DELTA_T, 0))) panic("couldn't set alarm: %d", s); +/*XXX*/vmmcall(0x1234560a, 53, 53); /* Map out our own text and data. This is normally done in crtso.o * but RS is an exception - we don't get to talk to VM so early on. @@ -483,6 +536,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) */ unmap_ok = 1; _minix_unmapzero(); +/*XXX*/vmmcall(0x1234560a, 54, 54); return(OK); } diff --git a/servers/vm/arch/i386/pagetable.c b/servers/vm/arch/i386/pagetable.c index 939322b41..67e7f1886 100644 --- a/servers/vm/arch/i386/pagetable.c +++ b/servers/vm/arch/i386/pagetable.c @@ -293,32 +293,42 @@ PUBLIC void *vm_allocpage(phys_bytes *phys, int reason) static int level = 0; void *ret; +/*XXX*/vmmcall(0x1234560e, 0, 86); pt = &vmprocess->vm_pt; assert(reason >= 0 && reason < VMP_CATEGORIES); level++; +/*XXX*/vmmcall(0x1234560e, level, 87); assert(level >= 1); assert(level <= 2); +/*XXX*/vmmcall(0x1234560e, level, 88); if(level > 1 || !(vmprocess->vm_flags & VMF_HASPT) || !meminit_done) { int r; void *s; +/*XXX*/vmmcall(0x1234560e, level, 89); s=vm_getsparepage(phys); +/*XXX*/vmmcall(0x1234560e, level, 90); level--; if(!s) { +/*XXX*/vmmcall(0x1234560e, level, 91); util_stacktrace(); printf("VM: warning: out of spare pages\n"); } +/*XXX*/vmmcall(0x1234560e, level, 92); return s; } /* VM does have a pagetable, so get a page and map it in there. * Where in our virtual address space can we put it? */ +/*XXX*/vmmcall(0x1234560e, level, 93); loc = findhole(pt, arch_vir2map(vmprocess, vmprocess->vm_stacktop), vmprocess->vm_arch.vm_data_top); +/*XXX*/vmmcall(0x1234560e, loc, 94); if(loc == NO_MEM) { +/*XXX*/vmmcall(0x1234560e, level, 95); level--; printf("VM: vm_allocpage: findhole failed\n"); return NULL; @@ -327,6 +337,7 @@ PUBLIC void *vm_allocpage(phys_bytes *phys, int reason) /* Allocate page of memory for use by VM. As VM * is trusted, we don't have to pre-clear it. */ +/*XXX*/vmmcall(0x1234560e, level, 96); if((newpage = alloc_mem(CLICKSPERPAGE, 0)) == NO_MEM) { level--; printf("VM: vm_allocpage: alloc_mem failed\n"); @@ -336,22 +347,29 @@ PUBLIC void *vm_allocpage(phys_bytes *phys, int reason) *phys = CLICK2ABS(newpage); /* Map this page into our address space. */ +/*XXX*/vmmcall(0x1234560e, 0, 97); if((r=pt_writemap(pt, loc, *phys, I386_PAGE_SIZE, I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE, 0)) != OK) { +/*XXX*/vmmcall(0x1234560e, 0, 98); free_mem(newpage, CLICKSPERPAGE); printf("vm_allocpage writemap failed\n"); level--; return NULL; } +/*XXX*/vmmcall(0x1234560e, 0, 99); if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) { +/*XXX*/vmmcall(0x1234560e, 0, 100); panic("VMCTL_FLUSHTLB failed: %d", r); } +/*XXX*/vmmcall(0x1234560e, 0, 101); level--; /* Return user-space-ready pointer to it. */ +/*XXX*/vmmcall(0x1234560e, 0, 102); ret = (void *) arch_map2vir(vmprocess, loc); +/*XXX*/vmmcall(0x1234560e, ret, 103); return ret; } @@ -684,12 +702,16 @@ PUBLIC int pt_new(pt_t *pt) * mappings from in-kernel page tables pointing to * the page directories (the page_directories data). */ +/*XXX*/vmmcall(0x1234560e, 0, 80); if(!pt->pt_dir && !(pt->pt_dir = vm_allocpage(&pt->pt_dir_phys, VMP_PAGEDIR))) { +/*XXX*/vmmcall(0x1234560e, 0, 81); return ENOMEM; } +/*XXX*/vmmcall(0x1234560e, 0, 82); for(i = 0; i < I386_VM_DIR_ENTRIES; i++) { +/*XXX*/vmmcall(0x1234560e, 0, 83); pt->pt_dir[i] = 0; /* invalid entry (I386_VM_PRESENT bit = 0) */ pt->pt_pt[i] = NULL; } @@ -698,9 +720,11 @@ PUBLIC int pt_new(pt_t *pt) pt->pt_virtop = 0; /* Map in kernel. */ +/*XXX*/vmmcall(0x1234560e, 0, 84); if(pt_mapkernel(pt) != OK) panic("pt_new: pt_mapkernel failed"); +/*XXX*/vmmcall(0x1234560e, 0, 85); return OK; } @@ -732,12 +756,15 @@ PUBLIC void pt_init(phys_bytes usedlimit) newpt = &vmprocess->vm_pt; /* Get ourselves spare pages. */ +/*XXX*/vmmcall(0x1234560e, 0, 54); if(!(sparepages_mem = (vir_bytes) aalloc(I386_PAGE_SIZE*SPAREPAGES))) panic("pt_init: aalloc for spare failed"); +/*XXX*/vmmcall(0x1234560e, 0, 55); if((r=sys_umap(SELF, VM_D, (vir_bytes) sparepages_mem, I386_PAGE_SIZE*SPAREPAGES, &sparepages_ph)) != OK) panic("pt_init: sys_umap failed: %d", r); +/*XXX*/vmmcall(0x1234560e, 0, 56); for(s = 0; s < SPAREPAGES; s++) { sparepages[s].page = (void *) (sparepages_mem + s*I386_PAGE_SIZE); sparepages[s].phys = sparepages_ph + s*I386_PAGE_SIZE; @@ -748,6 +775,7 @@ PUBLIC void pt_init(phys_bytes usedlimit) /* global bit and 4MB pages available? */ global_bit_ok = _cpufeature(_CPUF_I386_PGE); bigpage_ok = _cpufeature(_CPUF_I386_PSE); +/*XXX*/vmmcall(0x1234560e, 0, 57); /* Set bit for PTE's and PDE's if available. */ if(global_bit_ok) @@ -780,10 +808,12 @@ PUBLIC void pt_init(phys_bytes usedlimit) /* Make new page table for ourselves, partly copied * from the current one. */ +/*XXX*/vmmcall(0x1234560e, 0, 58); if(pt_new(newpt) != OK) panic("pt_init: pt_new failed"); /* Set up mappings for VM process. */ +/*XXX*/vmmcall(0x1234560e, 0, 59); for(v = lo; v < hi; v += I386_PAGE_SIZE) { phys_bytes addr; u32_t flags; @@ -791,12 +821,14 @@ PUBLIC void pt_init(phys_bytes usedlimit) /* We have to write the new position in the PT, * so we can move our segments. */ +/*XXX*/vmmcall(0x1234560e, 0, 60); if(pt_writemap(newpt, v+moveup, v, I386_PAGE_SIZE, I386_VM_PRESENT|I386_VM_WRITE|I386_VM_USER, 0) != OK) panic("pt_init: pt_writemap failed"); } /* Move segments up too. */ +/*XXX*/vmmcall(0x1234560e, 0, 61); vmprocess->vm_arch.vm_seg[T].mem_phys += ABS2CLICK(moveup); vmprocess->vm_arch.vm_seg[D].mem_phys += ABS2CLICK(moveup); vmprocess->vm_arch.vm_seg[S].mem_phys += ABS2CLICK(moveup); @@ -804,10 +836,12 @@ PUBLIC void pt_init(phys_bytes usedlimit) /* Allocate us a page table in which to remember page directory * pointers. */ +/*XXX*/vmmcall(0x1234560e, 0, 62); if(!(page_directories = vm_allocpage(&page_directories_phys, VMP_PAGETABLE))) panic("no virt addr for vm mappings"); +/*XXX*/vmmcall(0x1234560e, 0, 63); memset(page_directories, 0, I386_PAGE_SIZE); /* Increase our hardware data segment to create virtual address @@ -842,9 +876,11 @@ PUBLIC void pt_init(phys_bytes usedlimit) kernmap_pde = free_pde++; offset = kernmap_pde * I386_BIG_PAGE_SIZE; +/*XXX*/vmmcall(0x1234560e, 0, 64); while(sys_vmctl_get_mapping(index, &addr, &len, &flags) == OK) { vir_bytes vir; +/*XXX*/vmmcall(0x1234560e, 0, 65); if(index >= MAX_KERNMAPPINGS) panic("VM: too many kernel mappings: %d", index); kern_mappings[index].phys_addr = addr; @@ -854,30 +890,36 @@ PUBLIC void pt_init(phys_bytes usedlimit) kern_mappings[index].flags = I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE | global_bit; +/*XXX*/vmmcall(0x1234560e, 0, 66); if(flags & VMMF_UNCACHED) kern_mappings[index].flags |= PTF_NOCACHE; if(addr % I386_PAGE_SIZE) panic("VM: addr unaligned: %d", addr); if(len % I386_PAGE_SIZE) panic("VM: len unaligned: %d", len); +/*XXX*/vmmcall(0x1234560e, 0, 67); vir = arch_map2vir(&vmproc[VMP_SYSTEM], offset); if(sys_vmctl_reply_mapping(index, vir) != OK) panic("VM: reply failed"); offset += len; index++; kernmappings++; +/*XXX*/vmmcall(0x1234560e, 0, 68); } } /* Find a PDE below processes available for mapping in the * page directories (readonly). */ +/*XXX*/vmmcall(0x1234560e, 0, 69); pagedir_pde = free_pde++; pagedir_pde_val = (page_directories_phys & I386_VM_ADDR_MASK) | I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE; /* Tell kernel about free pde's. */ +/*XXX*/vmmcall(0x1234560e, 0, 70); while(free_pde*I386_BIG_PAGE_SIZE < VM_PROCSTART) { +/*XXX*/vmmcall(0x1234560e, 0, 71); if((r=sys_vmctl(SELF, VMCTL_I386_FREEPDE, free_pde++)) != OK) { panic("VMCTL_I386_FREEPDE failed: %d", r); } @@ -887,20 +929,25 @@ PUBLIC void pt_init(phys_bytes usedlimit) proc_pde = free_pde; /* Give our process the new, copied, private page table. */ +/*XXX*/vmmcall(0x1234560e, 0, 72); pt_mapkernel(newpt); /* didn't know about vm_dir pages earlier */ +/*XXX*/vmmcall(0x1234560e, 0, 73); pt_bind(newpt, vmprocess); /* new segment limit for the kernel after paging is enabled */ +/*XXX*/vmmcall(0x1234560e, 0, 74); ep_data.data_seg_limit = free_pde*I386_BIG_PAGE_SIZE; /* the memory map which must be installed after paging is enabled */ ep_data.mem_map = vmprocess->vm_arch.vm_seg; /* Now actually enable paging. */ +/*XXX*/vmmcall(0x1234560e, 0, 75); if(sys_vmctl_enable_paging(&ep_data) != OK) panic("pt_init: enable paging failed"); /* Back to reality - this is where the stack actually is. */ vmprocess->vm_arch.vm_seg[S].mem_len -= extra_clicks; +/*XXX*/vmmcall(0x1234560e, 0, 76); /* All OK. */ return; diff --git a/servers/vm/exec.c b/servers/vm/exec.c index f91a5f9e2..aeada773f 100644 --- a/servers/vm/exec.c +++ b/servers/vm/exec.c @@ -415,6 +415,7 @@ PUBLIC int proc_new(struct vmproc *vmp, int prealloc; struct vir_region *reg; +/*XXX*/vmmcall(0x1234560b, 0, 1); assert(!(vstart % VM_PAGE_SIZE)); assert(!(text_bytes % VM_PAGE_SIZE)); assert(!(data_bytes % VM_PAGE_SIZE)); @@ -425,6 +426,7 @@ PUBLIC int proc_new(struct vmproc *vmp, assert((!text_start && !data_start) || (text_start && data_start)); /* Place text at start of process. */ +/*XXX*/vmmcall(0x1234560b, 0, 2); vmp->vm_arch.vm_seg[T].mem_phys = ABS2CLICK(vstart); vmp->vm_arch.vm_seg[T].mem_vir = 0; vmp->vm_arch.vm_seg[T].mem_len = ABS2CLICK(text_bytes); @@ -434,35 +436,50 @@ PUBLIC int proc_new(struct vmproc *vmp, /* page mapping flags for code */ #define TEXTFLAGS (PTF_PRESENT | PTF_USER) SANITYCHECK(SCL_DETAIL); +/*XXX*/vmmcall(0x1234560b, 0, 3); if(text_bytes > 0) { +/*XXX*/vmmcall(0x1234560b, 0, 4); if(!(reg=map_page_region(vmp, vstart, 0, text_bytes, text_start ? text_start : MAP_NONE, VR_ANON | VR_WRITABLE, text_start ? 0 : MF_PREALLOC))) { +/*XXX*/vmmcall(0x1234560b, 0, 5); SANITYCHECK(SCL_DETAIL); printf("VM: proc_new: map_page_region failed (text)\n"); map_free_proc(vmp); SANITYCHECK(SCL_DETAIL); +/*XXX*/vmmcall(0x1234560b, 0, 6); return(ENOMEM); } +/*XXX*/vmmcall(0x1234560b, 0, 7); map_region_set_tag(reg, VRT_TEXT); +/*XXX*/vmmcall(0x1234560b, 0, 8); SANITYCHECK(SCL_DETAIL); +/*XXX*/vmmcall(0x1234560b, 0, 9); } +/*XXX*/vmmcall(0x1234560b, 0, 10); SANITYCHECK(SCL_DETAIL); +/*XXX*/vmmcall(0x1234560b, 0, 11); /* Allocate memory for data (including bss, but not including gap * or stack), make sure it's cleared, and map it in after text * (if any). */ +/*XXX*/vmmcall(0x1234560b, 0, 12); if(!(vmp->vm_heap = map_page_region(vmp, vstart + text_bytes, 0, data_bytes, data_start ? data_start : MAP_NONE, VR_ANON | VR_WRITABLE, data_start ? 0 : MF_PREALLOC))) { +/*XXX*/vmmcall(0x1234560b, 0, 13); printf("VM: exec: map_page_region for data failed\n"); +/*XXX*/vmmcall(0x1234560b, 0, 14); map_free_proc(vmp); +/*XXX*/vmmcall(0x1234560b, 0, 15); SANITYCHECK(SCL_DETAIL); +/*XXX*/vmmcall(0x1234560b, 0, 16); return ENOMEM; } /* Tag the heap so brk() call knows which region to extend. */ +/*XXX*/vmmcall(0x1234560b, 0, 17); map_region_set_tag(vmp->vm_heap, VRT_HEAP); /* How many address space clicks between end of data @@ -470,17 +487,22 @@ PUBLIC int proc_new(struct vmproc *vmp, * stacktop is the first address after the stack, as addressed * from within the user process. */ +/*XXX*/vmmcall(0x1234560b, 0, 18); hole_bytes = stacktop - data_bytes - stack_bytes - gap_bytes; +/*XXX*/vmmcall(0x1234560b, 0, 19); if(!(reg=map_page_region(vmp, vstart + text_bytes + data_bytes + hole_bytes, 0, stack_bytes + gap_bytes, MAP_NONE, VR_ANON | VR_WRITABLE, prealloc_stack ? MF_PREALLOC : 0)) != OK) { +/*XXX*/vmmcall(0x1234560b, 0, 20); panic("map_page_region failed for stack"); } +/*XXX*/vmmcall(0x1234560b, 0, 21); map_region_set_tag(reg, VRT_STACK); +/*XXX*/vmmcall(0x1234560b, 0, 22); vmp->vm_arch.vm_seg[D].mem_phys = ABS2CLICK(vstart + text_bytes); vmp->vm_arch.vm_seg[D].mem_vir = 0; vmp->vm_arch.vm_seg[D].mem_len = ABS2CLICK(data_bytes); @@ -496,6 +518,7 @@ PUBLIC int proc_new(struct vmproc *vmp, vmp->vm_flags |= VMF_HASPT; +/*XXX*/vmmcall(0x1234560b, 0, 23); if(vmp->vm_endpoint != NONE) { /* Pretend the stack is the full size of the data segment, so @@ -503,22 +526,29 @@ PUBLIC int proc_new(struct vmproc *vmp, * After sys_newmap(), change the stack to what we know the * stack to be (up to stacktop). */ +/*XXX*/vmmcall(0x1234560b, 0, 24); vmp->vm_arch.vm_seg[S].mem_len = (VM_DATATOP >> CLICK_SHIFT) - vmp->vm_arch.vm_seg[S].mem_vir - ABS2CLICK(vstart) - ABS2CLICK(text_bytes); /* What is the final size of the data segment in bytes? */ +/*XXX*/vmmcall(0x1234560b, 0, 25); vmp->vm_arch.vm_data_top = (vmp->vm_arch.vm_seg[S].mem_vir + vmp->vm_arch.vm_seg[S].mem_len) << CLICK_SHIFT; +/*XXX*/vmmcall(0x1234560b, 0, 26); if((s=sys_newmap(vmp->vm_endpoint, vmp->vm_arch.vm_seg)) != OK) panic("sys_newmap (vm) failed: %d", s); +/*XXX*/vmmcall(0x1234560b, 0, 27); if((s=pt_bind(&vmp->vm_pt, vmp)) != OK) panic("exec_newmem: pt_bind failed: %d", s); +/*XXX*/vmmcall(0x1234560b, 0, 28); } /* No yielded memory blocks. */ +/*XXX*/vmmcall(0x1234560b, 0, 29); yielded_init(&vmp->vm_yielded_blocks); +/*XXX*/vmmcall(0x1234560b, 0, 30); return OK; } diff --git a/servers/vm/main.c b/servers/vm/main.c index 0d49a4958..f74f3a713 100644 --- a/servers/vm/main.c +++ b/servers/vm/main.c @@ -79,23 +79,30 @@ PUBLIC int main(void) int caller_slot; struct vmproc *vmp_caller; +/*XXX*/vmmcall(0x1234560c, 0, 0); + /* SEF local startup. */ sef_local_startup(); +/*XXX*/vmmcall(0x1234560c, 0, 1); SANITYCHECK(SCL_TOP); /* This is VM's main loop. */ +/*XXX*/vmmcall(0x1234560c, 0, 2); while (TRUE) { int r, c; +/*XXX*/vmmcall(0x1234560c, 0, 3); SANITYCHECK(SCL_TOP); if(missing_spares > 0) { pt_cycle(); /* pagetable code wants to be called */ } +/*XXX*/vmmcall(0x1234560c, 0, 4); if ((r=sef_receive_status(ANY, &msg, &rcv_sts)) != OK) panic("sef_receive_status() error: %d", r); +/*XXX*/vmmcall(0x1234560c, msg.m_type, 5); if (is_ipc_notify(rcv_sts)) { /* Unexpected notify(). */ printf("VM: ignoring notify() from %d\n", msg.m_source); @@ -106,6 +113,7 @@ PUBLIC int main(void) panic("invalid caller", who_e); vmp_caller = &vmproc[caller_slot]; c = CALLNUMBER(msg.m_type); +/*XXX*/vmmcall(0x1234560c, c, 6); result = ENOSYS; /* Out of range or restricted calls return this. */ if (msg.m_type == VM_PAGEFAULT) { if (!IPC_STATUS_FLAGS_TEST(rcv_sts, IPC_FLG_MSG_FROM_KERNEL)) { @@ -131,6 +139,7 @@ PUBLIC int main(void) SANITYCHECK(SCL_FUNCTIONS); } } +/*XXX*/vmmcall(0x1234560c, result, 7); /* Send reply message, unless the return code is SUSPEND, * which is a pseudo-result suppressing the reply message. @@ -143,7 +152,9 @@ PUBLIC int main(void) panic("send() error"); } } +/*XXX*/vmmcall(0x1234560c, 0, 8); } +/*XXX*/vmmcall(0x1234560c, 0, 9); return(OK); } @@ -153,16 +164,21 @@ PUBLIC int main(void) PRIVATE void sef_local_startup() { /* Register init callbacks. */ +/*XXX*/vmmcall(0x1234560c, 10, 10); sef_setcb_init_fresh(sef_cb_init_fresh); +/*XXX*/vmmcall(0x1234560c, 11, 11); sef_setcb_init_restart(sef_cb_init_fail); /* No live update support for now. */ /* Register signal callbacks. */ +/*XXX*/vmmcall(0x1234560c, 12, 12); sef_setcb_signal_handler(sef_cb_signal_handler); /* Let SEF perform startup. */ +/*XXX*/vmmcall(0x1234560c, 13, 13); sef_startup(); +/*XXX*/vmmcall(0x1234560c, 14, 14); } /*===========================================================================* @@ -182,7 +198,8 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) #if SANITYCHECKS incheck = nocheck = 0; #endif - + +/*XXX*/vmmcall(0x1234560c, 0, 27); vm_paged = 1; env_parse("vm_paged", "d", 0, &vm_paged, 0, 1); #if SANITYCHECKS @@ -190,18 +207,22 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) #endif /* Get chunks of available memory. */ +/*XXX*/vmmcall(0x1234560c, 0, 28); get_mem_chunks(mem_chunks); /* Initialize VM's process table. Request a copy of the system * image table that is defined at the kernel level to see which * slots to fill in. */ +/*XXX*/vmmcall(0x1234560c, 0, 28); if (OK != (s=sys_getimage(image))) panic("couldn't get image table: %d", s); /* Set table to 0. This invalidates all slots (clear VMF_INUSE). */ +/*XXX*/vmmcall(0x1234560c, 0, 29); memset(vmproc, 0, sizeof(vmproc)); +/*XXX*/vmmcall(0x1234560c, 0, 30); for(i = 0; i < ELEMENTS(vmproc); i++) { vmproc[i].vm_slot = i; } @@ -209,10 +230,12 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* Walk through boot-time system processes that are alive * now and make valid slot entries for them. */ +/*XXX*/vmmcall(0x1234560c, 0, 31); for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) { phys_bytes proclimit; struct vmproc *vmp; +/*XXX*/vmmcall(0x1234560c, 0, 32); if(ip->proc_nr >= _NR_PROCS) { panic("proc: %d", ip->proc_nr); } if(ip->proc_nr < 0 && ip->proc_nr != SYSTEM) continue; @@ -228,22 +251,28 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* Initialize normal process table slot or special SYSTEM * table slot. Kernel memory is already reserved. */ +/*XXX*/vmmcall(0x1234560c, 0, 33); GETVMP(vmp, ip->proc_nr); /* reset fields as if exited */ +/*XXX*/vmmcall(0x1234560c, 0, 34); clear_proc(vmp); /* Get memory map for this process from the kernel. */ +/*XXX*/vmmcall(0x1234560c, 0, 35); if ((s=get_mem_map(ip->proc_nr, vmp->vm_arch.vm_seg)) != OK) panic("couldn't get process mem_map: %d", s); /* Remove this memory from the free list. */ +/*XXX*/vmmcall(0x1234560c, 0, 36); reserve_proc_mem(mem_chunks, vmp->vm_arch.vm_seg); /* Set memory limit. */ +/*XXX*/vmmcall(0x1234560c, 0, 37); proclimit = CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_phys + vmp->vm_arch.vm_seg[S].mem_len) - 1; +/*XXX*/vmmcall(0x1234560c, 0, 38); if(proclimit > limit) limit = proclimit; @@ -255,21 +284,26 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) if (vmp->vm_arch.vm_seg[T].mem_len != 0) vmp->vm_flags |= VMF_SEPARATE; +/*XXX*/vmmcall(0x1234560c, 0, 39); } /* Architecture-dependent initialization. */ +/*XXX*/vmmcall(0x1234560c, 0, 40); pt_init(limit); /* Initialize tables to all physical memory. */ +/*XXX*/vmmcall(0x1234560c, 0, 41); mem_init(mem_chunks); meminit_done = 1; /* Give these processes their own page table. */ +/*XXX*/vmmcall(0x1234560c, 0, 42); for (ip = &image[0]; ip < &image[NR_BOOT_PROCS]; ip++) { int s; struct vmproc *vmp; vir_bytes old_stacktop, old_stack; +/*XXX*/vmmcall(0x1234560c, 0, 43); if(ip->proc_nr < 0) continue; GETVMP(vmp, ip->proc_nr); @@ -282,20 +316,26 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) vmp->vm_arch.vm_seg[S].mem_len - vmp->vm_arch.vm_seg[D].mem_len; +/*XXX*/vmmcall(0x1234560c, 0, 44); if(pt_new(&vmp->vm_pt) != OK) panic("VM: no new pagetable"); #define BASICSTACK VM_PAGE_SIZE +/*XXX*/vmmcall(0x1234560c, 0, 77); old_stacktop = CLICK2ABS(vmp->vm_arch.vm_seg[S].mem_vir + vmp->vm_arch.vm_seg[S].mem_len); +/*XXX*/vmmcall(0x1234560c, old_stacktop, 78); if(sys_vmctl(vmp->vm_endpoint, VMCTL_INCSP, VM_STACKTOP - old_stacktop) != OK) { +/*XXX*/vmmcall(0x1234560c, 0, 79); panic("VM: vmctl for new stack failed"); } +/*XXX*/vmmcall(0x1234560c, 0, 45); free_mem(vmp->vm_arch.vm_seg[D].mem_phys + vmp->vm_arch.vm_seg[D].mem_len, old_stack); +/*XXX*/vmmcall(0x1234560c, 0, 46); if(proc_new(vmp, VM_PROCSTART, CLICK2ABS(vmp->vm_arch.vm_seg[T].mem_len), @@ -309,6 +349,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) VM_STACKTOP, 0) != OK) { panic("failed proc_new for boot process"); } +/*XXX*/vmmcall(0x1234560c, 0, 47); } /* Set up table of calls. */ @@ -322,6 +363,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) /* Set call table to 0. This invalidates all calls (clear * vmc_func). */ +/*XXX*/vmmcall(0x1234560c, 0, 48); memset(vm_calls, 0, sizeof(vm_calls)); /* Basic VM calls. */ @@ -359,17 +401,21 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) CALLMAP(VM_YIELDBLOCKGETBLOCK, do_yieldblockgetblock); /* Sanity checks */ +/*XXX*/vmmcall(0x1234560c, 0, 49); if(find_kernel_top() >= VM_PROCSTART) panic("kernel loaded too high"); /* Initialize the structures for queryexit */ +/*XXX*/vmmcall(0x1234560c, 0, 50); init_query_exit(); /* Unmap our own low pages. */ +/*XXX*/vmmcall(0x1234560c, 0, 51); unmap_ok = 1; _minix_unmapzero(); /* Map all the services in the boot image. */ +/*XXX*/vmmcall(0x1234560c, 0, 52); if((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0, (vir_bytes) rprocpub, sizeof(rprocpub), S)) != OK) { panic("sys_safecopyfrom failed: %d", s); @@ -381,6 +427,7 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) } } } +/*XXX*/vmmcall(0x1234560c, 0, 53); return(OK); } diff --git a/servers/vm/region.c b/servers/vm/region.c index a4ac327ee..f59d08f6a 100644 --- a/servers/vm/region.c +++ b/servers/vm/region.c @@ -439,21 +439,25 @@ int mapflags; struct phys_region *ph; physr_avl *phavl; +/*XXX*/vmmcall(0x1234560d, 0, 31); assert(!(length % VM_PAGE_SIZE)); SANITYCHECK(SCL_FUNCTIONS); +/*XXX*/vmmcall(0x1234560d, 0, 32); startv = region_find_slot(vmp, minv, maxv, length, &prevregion); if (startv == (vir_bytes) -1) return NULL; /* Now we want a new region. */ +/*XXX*/vmmcall(0x1234560d, 0, 33); if(!SLABALLOC(newregion)) { printf("VM: map_page_region: allocating region failed\n"); return NULL; } /* Fill in node details. */ +/*XXX*/vmmcall(0x1234560d, 0, 34); USE(newregion, newregion->vaddr = startv; newregion->length = length; @@ -461,23 +465,29 @@ USE(newregion, newregion->tag = VRT_NONE; newregion->parent = vmp;); +/*XXX*/vmmcall(0x1234560d, 0, 35); SLABALLOC(phavl); if(!phavl) { +/*XXX*/vmmcall(0x1234560d, 0, 36); printf("VM: map_page_region: allocating phys avl failed\n"); SLABFREE(newregion); return NULL; } USE(newregion, newregion->phys = phavl;); +/*XXX*/vmmcall(0x1234560d, 0, 37); physr_init(newregion->phys); /* If we know what we're going to map to, map it right away. */ +/*XXX*/vmmcall(0x1234560d, 0, 38); if(what != MAP_NONE) { assert(!(what % VM_PAGE_SIZE)); assert(!(startv % VM_PAGE_SIZE)); assert(!(mapflags & MF_PREALLOC)); +/*XXX*/vmmcall(0x1234560d, 0, 39); if(map_new_physblock(vmp, newregion, 0, length, what, PAF_CLEAR, 0) != OK) { +/*XXX*/vmmcall(0x1234560d, 0, 40); printf("VM: map_new_physblock failed\n"); USE(newregion, SLABFREE(newregion->phys);); @@ -486,8 +496,11 @@ USE(newregion, } } +/*XXX*/vmmcall(0x1234560d, 0, 41); if((flags & VR_ANON) && (mapflags & MF_PREALLOC)) { +/*XXX*/vmmcall(0x1234560d, 0, 42); if(map_handle_memory(vmp, newregion, 0, length, 1) != OK) { +/*XXX*/vmmcall(0x1234560d, 0, 43); printf("VM: map_page_region: prealloc failed\n"); USE(newregion, SLABFREE(newregion->phys);); @@ -497,14 +510,18 @@ USE(newregion, } /* Link it. */ +/*XXX*/vmmcall(0x1234560d, 0, 44); if(prevregion) { +/*XXX*/vmmcall(0x1234560d, 0, 45); assert(prevregion->vaddr < newregion->vaddr); USE(newregion, newregion->next = prevregion->next;); USE(prevregion, prevregion->next = newregion;); } else { +/*XXX*/vmmcall(0x1234560d, 0, 46); USE(newregion, newregion->next = vmp->vm_regions;); vmp->vm_regions = newregion; } +/*XXX*/vmmcall(0x1234560d, 0, 47); #if SANITYCHECKS assert(startv == newregion->vaddr); @@ -513,8 +530,10 @@ USE(newregion, } #endif +/*XXX*/vmmcall(0x1234560d, 0, 48); SANITYCHECK(SCL_FUNCTIONS); +/*XXX*/vmmcall(0x1234560d, 0, 49); return newregion; } -- 2.44.0