1: /* This task handles the interface between file system and kernel as well as 2: * between memory manager and kernel. System services are obtained by sending 3: * sys_task() a message specifying what is needed. To make life easier for 4: * MM and FS, a library is provided with routines whose names are of the 5: * form sys_xxx, e.g. sys_xit sends the SYS_XIT message to sys_task. The 6: * message types and parameters are: 7: * 8: * SYS_FORK informs kernel that a process has forked 9: * SYS_NEWMAP allows MM to set up a process memory map 10: * SYS_GETMAP allows MM to get a process' memory map 11: * SYS_EXEC sets program counter and stack pointer after EXEC 12: * SYS_XIT informs kernel that a process has exited 13: * SYS_GETSP caller wants to read out some process' stack pointer 14: * SYS_TIMES caller wants to get accounting times for a process 15: * SYS_ABORT MM or FS cannot go on; abort MINIX 16: * SYS_FRESH start with a fresh process image during EXEC (68000 only) 17: * SYS_SENDSIG send a signal to a process (POSIX style) 18: * SYS_SIGRETURN complete POSIX-style signalling 19: * SYS_KILL cause a signal to be sent via MM 20: * SYS_ENDSIG finish up after SYS_KILL-type signal 21: * SYS_COPY request a block of data to be copied between processes 22: * SYS_VCOPY request a series of data blocks to be copied between procs 23: * SYS_GBOOT copies the boot parameters to a process 24: * SYS_MEM returns the next free chunk of physical memory 25: * SYS_UMAP compute the physical address for a given virtual address 26: * SYS_TRACE request a trace operation 27: * SYS_SYSCTL handles miscelleneous kernel control functions 28: * SYS_PUTS a server (MM, FS, ...) wants to issue a diagnostic 29: * SYS_FINDPROC find a process' task number given it's names 30: * 31: * Message types and parameters: 32: * 33: * m_type PROC1 PROC2 PID MEM_PTR 34: * ------------------------------------------------------ 35: * | SYS_FORK | parent | child | pid | | 36: * |------------+---------+---------+---------+---------| 37: * | SYS_NEWMAP | proc nr | | | map ptr | 38: * |------------+---------+---------+---------+---------| 39: * | SYS_EXEC | proc nr | traced | new sp | | 40: * |------------+---------+---------+---------+---------| 41: * | SYS_XIT | parent | exitee | | | 42: * |------------+---------+---------+---------+---------| 43: * | SYS_GETSP | proc nr | | | | 44: * |------------+---------+---------+---------+---------| 45: * | SYS_TIMES | proc nr | | buf ptr | | 46: * |------------+---------+---------+---------+---------| 47: * | SYS_ABORT | | | | | 48: * |------------+---------+---------+---------+---------| 49: * | SYS_FRESH | proc nr | data_cl | | | 50: * |------------+---------+---------+---------+---------| 51: * | SYS_GBOOT | proc nr | | | bootptr | 52: * |------------+---------+---------+---------+---------| 53: * | SYS_GETMAP | proc nr | | | map ptr | 54: * ------------------------------------------------------ 55: * 56: * m_type m1_i1 m1_i2 m1_i3 m1_p1 57: * ----------------+---------+---------+---------+-------------- 58: * | SYS_VCOPY | src p | dst p | vec siz | vc addr | 59: * |---------------+---------+---------+---------+-------------| 60: * | SYS_SENDSIG | proc nr | | | smp | 61: * |---------------+---------+---------+---------+-------------| 62: * | SYS_SIGRETURN | proc nr | | | scp | 63: * |---------------+---------+---------+---------+-------------| 64: * | SYS_ENDSIG | proc nr | | | | 65: * |---------------+---------+---------+---------+-------------| 66: * | SYS_PUTS | count | | | buf | 67: * ------------------------------------------------------------- 68: * 69: * m_type m2_i1 m2_i2 m2_l1 m2_l2 m2_p1 70: * --------------------------------------------------------------- 71: * | SYS_TRACE | proc_nr | request | addr | data | | 72: * |------------+---------+---------+---------+---------|--------- 73: * | SYS_SYSCTL | proc_nr | request | | | argp | 74: * --------------------------------------------------------------- 75: * 76: * m_type m6_i1 m6_i2 m6_i3 m6_f1 77: * ------------------------------------------------------ 78: * | SYS_KILL | proc_nr | sig | | | 79: * ------------------------------------------------------ 80: * 81: * m_type m3_i1 m3_i2 m3_p1 m3_ca1 82: * -------------------------------------------------- 83: * | SYS_FINDPROC | flags | | | name | 84: * -------------------------------------------------- 85: * 86: * m_type m5_c1 m5_i1 m5_l1 m5_c2 m5_i2 m5_l2 m5_l3 87: * -------------------------------------------------------------------------- 88: * | SYS_COPY |src seg|src proc|src vir|dst seg|dst proc|dst vir| byte ct | 89: * -------------------------------------------------------------------------- 90: * | SYS_UMAP | seg |proc nr |vir adr| | | | byte ct | 91: * -------------------------------------------------------------------------- 92: * 93: * m_type m1_i1 m1_i2 m1_i3 94: * |------------+----------+----------+---------- 95: * | SYS_MEM | mem base | mem size | tot mem | 96: * ---------------------------------------------- 97: * 98: * In addition to the main sys_task() entry point, there are 5 other minor 99: * entry points: 100: * cause_sig: take action to cause a signal to occur, sooner or later 101: * inform: tell MM about pending signals 102: * numap: umap D segment starting from process number instead of pointer 103: * umap: compute the physical address for a given virtual address 104: * alloc_segments: allocate segments for 8088 or higher processor 105: */ 106: 107: #include "kernel.h" 108: #include <stdlib.h> 109: #include <signal.h> 110: #include <unistd.h> 111: #include <sys/sigcontext.h> 112: #include <sys/ptrace.h> 113: #include <sys/svrctl.h> 114: #include <minix/callnr.h> 115: #include <minix/com.h> 116: #include "proc.h" 117: #if (CHIP == INTEL) 118: #include "protect.h" 119: #endif 120: #include "assert.h" 121: INIT_ASSERT 122: 123: /* PSW masks. */ 124: #define IF_MASK 0x00000200 125: #define IOPL_MASK 0x003000 126: 127: PRIVATE message m; 128: 129: FORWARD _PROTOTYPE( int do_abort, (message *m_ptr) ); 130: FORWARD _PROTOTYPE( int do_copy, (message *m_ptr) ); 131: FORWARD _PROTOTYPE( int do_exec, (message *m_ptr) ); 132: FORWARD _PROTOTYPE( int do_fork, (message *m_ptr) ); 133: FORWARD _PROTOTYPE( int do_getsp, (message *m_ptr) ); 134: FORWARD _PROTOTYPE( int do_kill, (message *m_ptr) ); 135: FORWARD _PROTOTYPE( int do_mem, (message *m_ptr) ); 136: FORWARD _PROTOTYPE( int do_newmap, (message *m_ptr) ); 137: FORWARD _PROTOTYPE( int do_sendsig, (message *m_ptr) ); 138: FORWARD _PROTOTYPE( int do_sigreturn, (message *m_ptr) ); 139: FORWARD _PROTOTYPE( int do_endsig, (message *m_ptr) ); 140: FORWARD _PROTOTYPE( int do_times, (message *m_ptr) ); 141: FORWARD _PROTOTYPE( int do_trace, (message *m_ptr) ); 142: FORWARD _PROTOTYPE( int do_umap, (message *m_ptr) ); 143: FORWARD _PROTOTYPE( int do_xit, (message *m_ptr) ); 144: FORWARD _PROTOTYPE( int do_vcopy, (message *m_ptr) ); 145: FORWARD _PROTOTYPE( int do_getmap, (message *m_ptr) ); 146: FORWARD _PROTOTYPE( int do_sysctl, (message *m_ptr) ); 147: FORWARD _PROTOTYPE( int do_puts, (message *m_ptr) ); 148: FORWARD _PROTOTYPE( int do_findproc, (message *m_ptr) ); 149: 150: 151: /*===========================================================================* 152: * sys_task * 153: *===========================================================================*/ 154: PUBLIC void sys_task() 155: { 156: /* Main entry point of sys_task. Get the message and dispatch on type. */ 157: 158: register int r; 159: 160: while (TRUE) { 161: receive(ANY, &m); 162: 163: switch (m.m_type) { /* which system call */ 164: case SYS_FORK: r = do_fork(&m); break; 165: case SYS_NEWMAP: r = do_newmap(&m); break; 166: case SYS_GETMAP: r = do_getmap(&m); break; 167: case SYS_EXEC: r = do_exec(&m); break; 168: case SYS_XIT: r = do_xit(&m); break; 169: case SYS_GETSP: r = do_getsp(&m); break; 170: case SYS_TIMES: r = do_times(&m); break; 171: case SYS_ABORT: r = do_abort(&m); break; 172: case SYS_SENDSIG: r = do_sendsig(&m); break; 173: case SYS_SIGRETURN: r = do_sigreturn(&m); break; 174: case SYS_KILL: r = do_kill(&m); break; 175: case SYS_ENDSIG: r = do_endsig(&m); break; 176: case SYS_COPY: r = do_copy(&m); break; 177: case SYS_VCOPY: r = do_vcopy(&m); break; 178: case SYS_MEM: r = do_mem(&m); break; 179: case SYS_UMAP: r = do_umap(&m); break; 180: case SYS_TRACE: r = do_trace(&m); break; 181: case SYS_SYSCTL: r = do_sysctl(&m); break; 182: case SYS_PUTS: r = do_puts(&m); break; 183: case SYS_FINDPROC: r = do_findproc(&m); break; 184: default: r = E_BAD_FCN; 185: } 186: 187: m.m_type = r; /* 'r' reports status of call */ 188: send(m.m_source, &m); /* send reply to caller */ 189: } 190: } 191: 192: 193: /*===========================================================================* 194: * do_fork * 195: *===========================================================================*/ 196: PRIVATE int do_fork(m_ptr) 197: register message *m_ptr; /* pointer to request message */ 198: { 199: /* Handle sys_fork(). m_ptr->PROC1 has forked. The child is m_ptr->PROC2. */ 200: 201: #if (CHIP == INTEL) 202: reg_t old_ldt_sel; 203: #endif 204: register struct proc *rpc; 205: struct proc *rpp; 206: 207: rpp = proc_addr(m_ptr->PROC1); 208: assert(isuserp(rpp)); 209: rpc = proc_addr(m_ptr->PROC2); 210: assert(isemptyp(rpc)); 211: 212: /* Copy parent 'proc' struct to child. */ 213: #if (CHIP == INTEL) 214: old_ldt_sel = rpc->p_ldt_sel; /* stop this being obliterated by copy */ 215: #endif 216: 217: *rpc = *rpp; /* copy 'proc' struct */ 218: 219: #if (CHIP == INTEL) 220: rpc->p_ldt_sel = old_ldt_sel; 221: #endif 222: rpc->p_nr = m_ptr->PROC2; /* this was obliterated by copy */ 223: 224: rpc->p_flags |= NO_MAP; /* inhibit the process from running */ 225: 226: rpc->p_flags &= ~(PENDING | SIG_PENDING | P_STOP); 227: 228: /* Only 1 in group should have PENDING, child does not inherit trace status*/ 229: sigemptyset(&rpc->p_pending); 230: rpc->p_pendcount = 0; 231: rpc->p_pid = m_ptr->PID; /* install child's pid */ 232: rpc->p_reg.retreg = 0; /* child sees pid = 0 to know it is child */ 233: 234: rpc->user_time = 0; /* set all the accounting times to 0 */ 235: rpc->sys_time = 0; 236: rpc->child_utime = 0; 237: rpc->child_stime = 0; 238: 239: return(OK); 240: } 241: 242: 243: /*===========================================================================* 244: * do_newmap * 245: *===========================================================================*/ 246: PRIVATE int do_newmap(m_ptr) 247: message *m_ptr; /* pointer to request message */ 248: { 249: /* Handle sys_newmap(). Fetch the memory map from MM. */ 250: 251: register struct proc *rp; 252: phys_bytes src_phys; 253: int caller; /* whose space has the new map (usually MM) */ 254: int k; /* process whose map is to be loaded */ 255: int old_flags; /* value of flags before modification */ 256: struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */ 257: 258: /* Extract message parameters and copy new memory map from MM. */ 259: caller = m_ptr->m_source; 260: k = m_ptr->PROC1; 261: map_ptr = (struct mem_map *) m_ptr->MEM_PTR; 262: if (!isokprocn(k)) return(E_BAD_PROC); 263: rp = proc_addr(k); /* ptr to entry of user getting new map */ 264: 265: /* Copy the map from MM. */ 266: src_phys = umap(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map)); 267: assert(src_phys != 0); 268: phys_copy(src_phys, vir2phys(rp->p_map), (phys_bytes) sizeof(rp->p_map)); 269: 270: #if (CHIP != M68000) 271: alloc_segments(rp); 272: #else 273: pmmu_init_proc(rp); 274: #endif 275: old_flags = rp->p_flags; /* save the previous value of the flags */ 276: rp->p_flags &= ~NO_MAP; 277: if (old_flags != 0 && rp->p_flags == 0) lock_ready(rp); 278: 279: return(OK); 280: } 281: 282: 283: /*===========================================================================* 284: * do_getmap * 285: *===========================================================================*/ 286: PRIVATE int do_getmap(m_ptr) 287: message *m_ptr; /* pointer to request message */ 288: { 289: /* Handle sys_getmap(). Report the memory map to MM. */ 290: 291: register struct proc *rp; 292: phys_bytes dst_phys; 293: int caller; /* where the map has to be stored */ 294: int k; /* process whose map is to be loaded */ 295: struct mem_map *map_ptr; /* virtual address of map inside caller (MM) */ 296: 297: /* Extract message parameters and copy new memory map to MM. */ 298: caller = m_ptr->m_source; 299: k = m_ptr->PROC1; 300: map_ptr = (struct mem_map *) m_ptr->MEM_PTR; 301: 302: assert(isokprocn(k)); /* unlikely: MM sends a bad proc nr. */ 303: 304: rp = proc_addr(k); /* ptr to entry of the map */ 305: 306: /* Copy the map to MM. */ 307: dst_phys = umap(proc_addr(caller), D, (vir_bytes) map_ptr, sizeof(rp->p_map)); 308: assert(dst_phys != 0); 309: phys_copy(vir2phys(rp->p_map), dst_phys, sizeof(rp->p_map)); 310: 311: return(OK); 312: } 313: 314: 315: /*===========================================================================* 316: * do_exec * 317: *===========================================================================*/ 318: PRIVATE int do_exec(m_ptr) 319: register message *m_ptr; /* pointer to request message */ 320: { 321: /* Handle sys_exec(). A process has done a successful EXEC. Patch it up. */ 322: 323: register struct proc *rp; 324: reg_t sp; /* new sp */ 325: phys_bytes phys_name; 326: char *np; 327: #define NLEN (sizeof(rp->p_name)-1) 328: 329: rp = proc_addr(m_ptr->PROC1); 330: assert(isuserp(rp)); 331: /* PROC2 field is used as flag to indicate process is being traced */ 332: if (m_ptr->PROC2) cause_sig(m_ptr->PROC1, SIGTRAP); 333: sp = (reg_t) m_ptr->STACK_PTR; 334: rp->p_reg.sp = sp; /* set the stack pointer */ 335: #if (CHIP == M68000) 336: rp->p_splow = sp; /* set the stack pointer low water */ 337: #ifdef FPP 338: /* Initialize fpp for this process */ 339: fpp_new_state(rp); 340: #endif 341: #endif 342: #if (CHIP == INTEL) /* wipe extra LDT entries */ 343: memset(&rp->p_ldt[EXTRA_LDT_INDEX], 0, 344: (LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_ldt[0])); 345: #endif 346: rp->p_reg.pc = (reg_t) m_ptr->IP_PTR; /* set pc */ 347: rp->p_flags &= ~RECEIVING; /* MM does not reply to EXEC call */ 348: if (rp->p_flags == 0) lock_ready(rp); 349: 350: /* Save command name for debugging, ps(1) output, etc. */ 351: phys_name = numap(m_ptr->m_source, (vir_bytes) m_ptr->NAME_PTR, 352: (vir_bytes) NLEN); 353: if (phys_name != 0) { 354: phys_copy(phys_name, vir2phys(rp->p_name), (phys_bytes) NLEN); 355: for (np = rp->p_name; (*np & BYTE) >= ' '; np++) {} 356: *np = 0; 357: } 358: return(OK); 359: } 360: 361: 362: /*===========================================================================* 363: * do_xit * 364: *===========================================================================*/ 365: PRIVATE int do_xit(m_ptr) 366: message *m_ptr; /* pointer to request message */ 367: { 368: /* Handle sys_xit(). A process has exited. */ 369: 370: register struct proc *rp, *rc; 371: struct proc *np, *xp; 372: int parent; /* number of exiting proc's parent */ 373: int proc_nr; /* number of process doing the exit */ 374: phys_clicks base, size; 375: 376: parent = m_ptr->PROC1; /* slot number of parent process */ 377: proc_nr = m_ptr->PROC2; /* slot number of exiting process */ 378: rp = proc_addr(parent); 379: assert(isuserp(rp)); 380: rc = proc_addr(proc_nr); 381: assert(isuserp(rc)); 382: lock(); 383: rp->child_utime += rc->user_time + rc->child_utime; /* accum child times */ 384: rp->child_stime += rc->sys_time + rc->child_stime; 385: unlock(); 386: cancel_alarm(proc_nr); /* turn off alarm timer */ 387: if (rc->p_flags == 0) lock_unready(rc); 388: 389: strcpy(rc->p_name, "<noname>"); /* process no longer has a name */ 390: 391: /* If the process being terminated happens to be queued trying to send a 392: * message (i.e., the process was killed by a signal, rather than it doing an 393: * EXIT), then it must be removed from the message queues. 394: */ 395: if (rc->p_flags & SENDING) { 396: /* Check all proc slots to see if the exiting process is queued. */ 397: for (rp = BEG_PROC_ADDR; rp < END_PROC_ADDR; rp++) { 398: if (rp->p_callerq == NIL_PROC) continue; 399: if (rp->p_callerq == rc) { 400: /* Exiting process is on front of this queue. */ 401: rp->p_callerq = rc->p_sendlink; 402: break; 403: } else { 404: /* See if exiting process is in middle of queue. */ 405: np = rp->p_callerq; 406: while ( ( xp = np->p_sendlink) != NIL_PROC) 407: if (xp == rc) { 408: np->p_sendlink = xp->p_sendlink; 409: break; 410: } else { 411: np = xp; 412: } 413: } 414: } 415: } 416: #if (CHIP == M68000) 417: pmmu_delete(rc); /* we're done remove tables */ 418: #endif 419: 420: if (rc->p_flags & PENDING) --sig_procs; 421: sigemptyset(&rc->p_pending); 422: rc->p_pendcount = 0; 423: rc->p_flags = 0; 424: rc->p_priority = PPRI_NONE; 425: return(OK); 426: } 427: 428: 429: /*===========================================================================* 430: * do_getsp * 431: *===========================================================================*/ 432: PRIVATE int do_getsp(m_ptr) 433: register message *m_ptr; /* pointer to request message */ 434: { 435: /* Handle sys_getsp(). MM wants to know what sp is. */ 436: 437: register struct proc *rp; 438: 439: rp = proc_addr(m_ptr->PROC1); 440: assert(isuserp(rp)); 441: m_ptr->STACK_PTR = (char *) rp->p_reg.sp; /* return sp here (bad type) */ 442: return(OK); 443: } 444: 445: 446: /*===========================================================================* 447: * do_times * 448: *===========================================================================*/ 449: PRIVATE int do_times(m_ptr) 450: register message *m_ptr; /* pointer to request message */ 451: { 452: /* Handle sys_times(). Retrieve the accounting information. */ 453: 454: register struct proc *rp; 455: 456: rp = proc_addr(m_ptr->PROC1); 457: 458: /* Insert the times needed by the TIMES system call in the message. */ 459: lock(); /* halt the volatile time counters in rp */ 460: m_ptr->USER_TIME = rp->user_time; 461: m_ptr->SYSTEM_TIME = rp->sys_time; 462: unlock(); 463: m_ptr->CHILD_UTIME = rp->child_utime; 464: m_ptr->CHILD_STIME = rp->child_stime; 465: m_ptr->BOOT_TICKS = get_uptime(); 466: return(OK); 467: } 468: 469: 470: /*===========================================================================* 471: * do_abort * 472: *===========================================================================*/ 473: PRIVATE int do_abort(m_ptr) 474: message *m_ptr; /* pointer to request message */ 475: { 476: /* Handle sys_abort. MINIX is unable to continue. Terminate operation. */ 477: phys_bytes src_phys; 478: vir_bytes len; 479: 480: if (m_ptr->m1_i1 == RBT_MONITOR) { 481: /* The monitor is to run user specified instructions. */ 482: len = m_ptr->m1_i3 + 1; 483: assert(len <= mon_parmsize); 484: src_phys = numap(m_ptr->m1_i2, (vir_bytes) m_ptr->m1_p1, len); 485: assert(src_phys != 0); 486: phys_copy(src_phys, mon_params, (phys_bytes) len); 487: } 488: wreboot(m_ptr->m1_i1); 489: return(OK); /* pro-forma (really EDISASTER) */ 490: } 491: 492: 493: /*===========================================================================* 494: * do_sendsig * 495: *===========================================================================*/ 496: PRIVATE int do_sendsig(m_ptr) 497: message *m_ptr; /* pointer to request message */ 498: { 499: /* Handle sys_sendsig, POSIX-style signal */ 500: 501: struct sigmsg smsg; 502: register struct proc *rp; 503: phys_bytes src_phys, dst_phys; 504: struct sigcontext sc, *scp; 505: struct sigframe fr, *frp; 506: 507: rp = proc_addr(m_ptr->PROC1); 508: assert(isuserp(rp)); 509: 510: /* Get the sigmsg structure into our address space. */ 511: src_phys = umap(proc_addr(MM_PROC_NR), D, (vir_bytes) m_ptr->SIG_CTXT_PTR, 512: (vir_bytes) sizeof(struct sigmsg)); 513: assert(src_phys != 0); 514: phys_copy(src_phys, vir2phys(&smsg), (phys_bytes) sizeof(struct sigmsg)); 515: 516: /* Compute the usr stack pointer value where sigcontext will be stored. */ 517: scp = (struct sigcontext *) smsg.sm_stkptr - 1; 518: 519: /* Copy the registers to the sigcontext structure. */ 520: memcpy(&sc.sc_regs, &rp->p_reg, sizeof(struct sigregs)); 521: 522: /* Finish the sigcontext initialization. */ 523: sc.sc_flags = SC_SIGCONTEXT; 524: 525: sc.sc_mask = smsg.sm_mask; 526: 527: /* Copy the sigcontext structure to the user's stack. */ 528: dst_phys = umap(rp, D, (vir_bytes) scp, 529: (vir_bytes) sizeof(struct sigcontext)); 530: if (dst_phys == 0) return(EFAULT); 531: phys_copy(vir2phys(&sc), dst_phys, (phys_bytes) sizeof(struct sigcontext)); 532: 533: /* Initialize the sigframe structure. */ 534: frp = (struct sigframe *) scp - 1; 535: fr.sf_scpcopy = scp; 536: fr.sf_retadr2= (void (*)()) rp->p_reg.pc; 537: fr.sf_fp = rp->p_reg.fp; 538: rp->p_reg.fp = (reg_t) &frp->sf_fp; 539: fr.sf_scp = scp; 540: fr.sf_code = 0; /* XXX - should be used for type of FP exception */ 541: fr.sf_signo = smsg.sm_signo; 542: fr.sf_retadr = (void (*)()) smsg.sm_sigreturn; 543: 544: /* Copy the sigframe structure to the user's stack. */ 545: dst_phys = umap(rp, D, (vir_bytes) frp, (vir_bytes) sizeof(struct sigframe)); 546: if (dst_phys == 0) return(EFAULT); 547: phys_copy(vir2phys(&fr), dst_phys, (phys_bytes) sizeof(struct sigframe)); 548: 549: /* Reset user registers to execute the signal handler. */ 550: rp->p_reg.sp = (reg_t) frp; 551: rp->p_reg.pc = (reg_t) smsg.sm_sighandler; 552: 553: return(OK); 554: } 555: 556: /*===========================================================================* 557: * do_sigreturn * 558: *===========================================================================*/ 559: PRIVATE int do_sigreturn(m_ptr) 560: register message *m_ptr; 561: { 562: /* POSIX style signals require sys_sigreturn to put things in order before the 563: * signalled process can resume execution 564: */ 565: 566: struct sigcontext sc; 567: register struct proc *rp; 568: phys_bytes src_phys; 569: 570: rp = proc_addr(m_ptr->PROC1); 571: assert(isuserp(rp)); 572: 573: /* Copy in the sigcontext structure. */ 574: src_phys = umap(rp, D, (vir_bytes) m_ptr->SIG_CTXT_PTR, 575: (vir_bytes) sizeof(struct sigcontext)); 576: if (src_phys == 0) return(EFAULT); 577: phys_copy(src_phys, vir2phys(&sc), (phys_bytes) sizeof(struct sigcontext)); 578: 579: /* Make sure that this is not just a jmp_buf. */ 580: if ((sc.sc_flags & SC_SIGCONTEXT) == 0) return(EINVAL); 581: 582: /* Fix up only certain key registers if the compiler doesn't use 583: * register variables within functions containing setjmp. 584: */ 585: if (sc.sc_flags & SC_NOREGLOCALS) { 586: rp->p_reg.retreg = sc.sc_retreg; 587: rp->p_reg.fp = sc.sc_fp; 588: rp->p_reg.pc = sc.sc_pc; 589: rp->p_reg.sp = sc.sc_sp; 590: return (OK); 591: } 592: sc.sc_psw = rp->p_reg.psw; 593: 594: #if (CHIP == INTEL) 595: /* Don't panic kernel if user gave bad selectors. */ 596: sc.sc_cs = rp->p_reg.cs; 597: sc.sc_ds = rp->p_reg.ds; 598: sc.sc_es = rp->p_reg.es; 599: #if _WORD_SIZE == 4 600: sc.sc_fs = rp->p_reg.fs; 601: sc.sc_gs = rp->p_reg.gs; 602: #endif 603: #endif 604: 605: /* Restore the registers. */ 606: memcpy(&rp->p_reg, (char *)&sc.sc_regs, sizeof(struct sigregs)); 607: 608: return(OK); 609: } 610: 611: /*===========================================================================* 612: * do_kill * 613: *===========================================================================*/ 614: PRIVATE int do_kill(m_ptr) 615: register message *m_ptr; /* pointer to request message */ 616: { 617: /* Handle sys_kill(). Cause a signal to be sent to a process via MM. 618: * Note that this has nothing to do with the kill (2) system call, this 619: * is how the FS (and possibly other servers) get access to cause_sig to 620: * send a KSIG message to MM 621: */ 622: 623: assert(isuserp(proc_addr(m_ptr->PR))); 624: cause_sig(m_ptr->PR, m_ptr->SIGNUM); 625: return(OK); 626: } 627: 628: 629: /*===========================================================================* 630: * do_endsig * 631: *===========================================================================*/ 632: PRIVATE int do_endsig(m_ptr) 633: register message *m_ptr; /* pointer to request message */ 634: { 635: /* Finish up after a KSIG-type signal, caused by a SYS_KILL message or a call 636: * to cause_sig by a task 637: */ 638: 639: register struct proc *rp; 640: 641: rp = proc_addr(m_ptr->PROC1); 642: if (isemptyp(rp)) return(E_BAD_PROC); /* process already dead? */ 643: assert(isuserp(rp)); 644: 645: /* MM has finished one KSIG. */ 646: if (rp->p_pendcount != 0 && --rp->p_pendcount == 0 647: && (rp->p_flags &= ~SIG_PENDING) == 0) 648: lock_ready(rp); 649: return(OK); 650: } 651: 652: /*===========================================================================* 653: * do_copy * 654: *===========================================================================*/ 655: PRIVATE int do_copy(m_ptr) 656: register message *m_ptr; /* pointer to request message */ 657: { 658: /* Handle sys_copy(). Copy data for MM or FS. */ 659: 660: int src_proc, dst_proc, src_space, dst_space; 661: vir_bytes src_vir, dst_vir; 662: phys_bytes src_phys, dst_phys, bytes; 663: 664: /* Dismember the command message. */ 665: src_proc = m_ptr->SRC_PROC_NR; 666: dst_proc = m_ptr->DST_PROC_NR; 667: src_space = m_ptr->SRC_SPACE; 668: dst_space = m_ptr->DST_SPACE; 669: src_vir = (vir_bytes) m_ptr->SRC_BUFFER; 670: dst_vir = (vir_bytes) m_ptr->DST_BUFFER; 671: bytes = (phys_bytes) m_ptr->COPY_BYTES; 672: 673: /* Compute the source and destination addresses and do the copy. */ 674: if (src_proc == ABS) { 675: src_phys = (phys_bytes) m_ptr->SRC_BUFFER; 676: } else { 677: if (bytes != (vir_bytes) bytes) { 678: /* This would happen for 64K segments and 16-bit vir_bytes. 679: * It would happen a lot for do_fork except MM uses ABS 680: * copies for that case. 681: */ 682: panic("overflow in count in do_copy", NO_NUM); 683: } 684: src_phys = umap(proc_addr(src_proc), src_space, src_vir, 685: (vir_bytes) bytes); 686: } 687: 688: if (dst_proc == ABS) { 689: dst_phys = (phys_bytes) m_ptr->DST_BUFFER; 690: } else { 691: dst_phys = umap(proc_addr(dst_proc), dst_space, dst_vir, 692: (vir_bytes) bytes); 693: } 694: 695: if (src_phys == 0 || dst_phys == 0) return(EFAULT); 696: phys_copy(src_phys, dst_phys, bytes); 697: return(OK); 698: } 699: 700: 701: /*===========================================================================* 702: * do_vcopy * 703: *===========================================================================*/ 704: PRIVATE int do_vcopy(m_ptr) 705: register message *m_ptr; /* pointer to request message */ 706: { 707: /* Handle sys_vcopy(). Copy multiple blocks of memory */ 708: 709: int src_proc, dst_proc, vect_s, i; 710: vir_bytes src_vir, dst_vir, vect_addr; 711: phys_bytes src_phys, dst_phys, bytes; 712: cpvec_t cpvec_table[CPVEC_NR]; 713: 714: /* Dismember the command message. */ 715: src_proc = m_ptr->m1_i1; 716: dst_proc = m_ptr->m1_i2; 717: vect_s = m_ptr->m1_i3; 718: vect_addr = (vir_bytes)m_ptr->m1_p1; 719: 720: if (vect_s > CPVEC_NR) return EDOM; 721: 722: src_phys= numap (m_ptr->m_source, vect_addr, vect_s * sizeof(cpvec_t)); 723: if (!src_phys) return EFAULT; 724: phys_copy(src_phys, vir2phys(cpvec_table), 725: (phys_bytes) (vect_s * sizeof(cpvec_t))); 726: 727: for (i = 0; i < vect_s; i++) { 728: src_vir= cpvec_table[i].cpv_src; 729: dst_vir= cpvec_table[i].cpv_dst; 730: bytes= cpvec_table[i].cpv_size; 731: src_phys = numap(src_proc,src_vir,(vir_bytes)bytes); 732: dst_phys = numap(dst_proc,dst_vir,(vir_bytes)bytes); 733: if (src_phys == 0 || dst_phys == 0) return(EFAULT); 734: phys_copy(src_phys, dst_phys, bytes); 735: } 736: return(OK); 737: } 738: 739: 740: /*===========================================================================* 741: * do_mem * 742: *===========================================================================*/ 743: PRIVATE int do_mem(m_ptr) 744: register message *m_ptr; /* pointer to request message */ 745: { 746: /* Return the base and size of the next chunk of memory. */ 747: 748: struct memory *memp; 749: 750: for (memp = mem; memp < &mem[NR_MEMS]; ++memp) { 751: m_ptr->m1_i1 = memp->base; 752: m_ptr->m1_i2 = memp->size; 753: m_ptr->m1_i3 = tot_mem_size; 754: memp->size = 0; 755: if (m_ptr->m1_i2 != 0) break; /* found a chunk */ 756: } 757: return(OK); 758: } 759: 760: 761: /*==========================================================================* 762: * do_umap * 763: *==========================================================================*/ 764: PRIVATE int do_umap(m_ptr) 765: register message *m_ptr; /* pointer to request message */ 766: { 767: /* Same as umap(), for non-kernel processes. */ 768: 769: m_ptr->SRC_BUFFER = umap(proc_addr((int) m_ptr->SRC_PROC_NR), 770: (int) m_ptr->SRC_SPACE, 771: (vir_bytes) m_ptr->SRC_BUFFER, 772: (vir_bytes) m_ptr->COPY_BYTES); 773: return(OK); 774: } 775: 776: 777: /*==========================================================================* 778: * do_trace * 779: *==========================================================================*/ 780: #define TR_PROCNR (m_ptr->m2_i1) 781: #define TR_REQUEST (m_ptr->m2_i2) 782: #define TR_ADDR ((vir_bytes) m_ptr->m2_l1) 783: #define TR_DATA (m_ptr->m2_l2) 784: #define TR_VLSIZE ((vir_bytes) sizeof(long)) 785: 786: PRIVATE int do_trace(m_ptr) 787: register message *m_ptr; 788: { 789: /* Handle the debugging commands supported by the ptrace system call 790: * The commands are: 791: * T_STOP stop the process 792: * T_OK enable tracing by parent for this process 793: * T_GETINS return value from instruction space 794: * T_GETDATA return value from data space 795: * T_GETUSER return value from user process table 796: * T_SETINS set value from instruction space 797: * T_SETDATA set value from data space 798: * T_SETUSER set value in user process table 799: * T_RESUME resume execution 800: * T_EXIT exit 801: * T_STEP set trace bit 802: * 803: * The T_OK and T_EXIT commands are handled completely by the memory manager, 804: * all others come here. 805: */ 806: 807: register struct proc *rp; 808: phys_bytes src, dst; 809: int i; 810: 811: rp = proc_addr(TR_PROCNR); 812: if (isemptyp(rp)) return(EIO); 813: switch (TR_REQUEST) { 814: case T_STOP: /* stop process */ 815: if (rp->p_flags == 0) lock_unready(rp); 816: rp->p_flags |= P_STOP; 817: rp->p_reg.psw &= ~TRACEBIT; /* clear trace bit */ 818: return(OK); 819: 820: case T_GETINS: /* return value from instruction space */ 821: if (rp->p_map[T].mem_len != 0) { 822: if ((src = umap(rp, T, TR_ADDR, TR_VLSIZE)) == 0) return(EIO); 823: phys_copy(src, vir2phys(&TR_DATA), (phys_bytes) sizeof(long)); 824: break; 825: } 826: /* Text space is actually data space - fall through. */ 827: 828: case T_GETDATA: /* return value from data space */ 829: if ((src = umap(rp, D, TR_ADDR, TR_VLSIZE)) == 0) return(EIO); 830: phys_copy(src, vir2phys(&TR_DATA), (phys_bytes) sizeof(long)); 831: break; 832: 833: case T_GETUSER: /* return value from process table */ 834: if ((TR_ADDR & (sizeof(long) - 1)) != 0 || 835: TR_ADDR > sizeof(struct proc) - sizeof(long)) 836: return(EIO); 837: TR_DATA = *(long *) ((char *) rp + (int) TR_ADDR); 838: break; 839: 840: case T_SETINS: /* set value in instruction space */ 841: if (rp->p_map[T].mem_len != 0) { 842: if ((dst = umap(rp, T, TR_ADDR, TR_VLSIZE)) == 0) return(EIO); 843: phys_copy(vir2phys(&TR_DATA), dst, (phys_bytes) sizeof(long)); 844: TR_DATA = 0; 845: break; 846: } 847: /* Text space is actually data space - fall through. */ 848: 849: case T_SETDATA: /* set value in data space */ 850: if ((dst = umap(rp, D, TR_ADDR, TR_VLSIZE)) == 0) return(EIO); 851: phys_copy(vir2phys(&TR_DATA), dst, (phys_bytes) sizeof(long)); 852: TR_DATA = 0; 853: break; 854: 855: case T_SETUSER: /* set value in process table */ 856: if ((TR_ADDR & (sizeof(reg_t) - 1)) != 0 || 857: TR_ADDR > sizeof(struct stackframe_s) - sizeof(reg_t)) 858: return(EIO); 859: i = (int) TR_ADDR; 860: #if (CHIP == INTEL) 861: /* Altering segment registers might crash the kernel when it 862: * tries to load them prior to restarting a process, so do 863: * not allow it. 864: */ 865: if (i == (int) &((struct proc *) 0)->p_reg.cs || 866: i == (int) &((struct proc *) 0)->p_reg.ds || 867: i == (int) &((struct proc *) 0)->p_reg.es || 868: #if _WORD_SIZE == 4 869: i == (int) &((struct proc *) 0)->p_reg.gs || 870: i == (int) &((struct proc *) 0)->p_reg.fs || 871: #endif 872: i == (int) &((struct proc *) 0)->p_reg.ss) 873: return(EIO); 874: #endif 875: if (i == (int) &((struct proc *) 0)->p_reg.psw) 876: /* only selected bits are changeable */ 877: SETPSW(rp, TR_DATA); 878: else 879: *(reg_t *) ((char *) &rp->p_reg + i) = (reg_t) TR_DATA; 880: TR_DATA = 0; 881: break; 882: 883: case T_RESUME: /* resume execution */ 884: rp->p_flags &= ~P_STOP; 885: if (rp->p_flags == 0) lock_ready(rp); 886: TR_DATA = 0; 887: break; 888: 889: case T_STEP: /* set trace bit */ 890: rp->p_reg.psw |= TRACEBIT; 891: rp->p_flags &= ~P_STOP; 892: if (rp->p_flags == 0) lock_ready(rp); 893: TR_DATA = 0; 894: break; 895: 896: default: 897: return(EIO); 898: } 899: return(OK); 900: } 901: 902: /*===========================================================================* 903: * do_sysctl * 904: *===========================================================================*/ 905: PRIVATE int do_sysctl(m_ptr) 906: message *m_ptr; /* pointer to request message */ 907: { 908: int proc_nr, priv; 909: struct proc *pp; 910: int request; 911: vir_bytes argp; 912: 913: proc_nr = m_ptr->m2_i1; 914: pp = proc_addr(proc_nr); 915: request = m_ptr->m2_i2; 916: priv = m_ptr->m2_i3; 917: argp = (vir_bytes) m_ptr->m2_p1; 918: 919: switch (request) { 920: case SYSSIGNON: { 921: struct systaskinfo info; 922: 923: /* Make this process a server. */ 924: if (!priv || !isuserp(pp)) return(EPERM); 925: info.proc_nr = proc_nr; 926: if (vir_copy(SYSTASK, (vir_bytes) &info, 927: proc_nr, argp, sizeof(info)) != OK) return(EFAULT); 928: 929: pp->p_priority = PPRI_SERVER; 930: pp->p_pid = 0; 931: return(OK); } 932: 933: case SYSGETENV: { 934: /* Obtain a kernel environment string, or simply all of it. */ 935: struct sysgetenv sysgetenv; 936: phys_bytes src, dst; 937: char key[32]; 938: char *val; 939: size_t len; 940: 941: if (vir_copy(proc_nr, argp, SYSTASK, (vir_bytes) &sysgetenv, 942: sizeof(sysgetenv)) != OK) return(EFAULT); 943: 944: if (sysgetenv.keylen != 0) { 945: /* Only one string by name. */ 946: if (sysgetenv.keylen > sizeof(key)) return(EINVAL); 947: 948: if (vir_copy(proc_nr, (vir_bytes) sysgetenv.key, 949: SYSTASK, (vir_bytes) key, 950: sysgetenv.keylen) != OK) return(EFAULT); 951: 952: if ((val = getenv(key)) == NULL) return(ESRCH); 953: src = vir2phys(val); 954: len = strlen(val) + 1; 955: } else { 956: /* Whole environment please. */ 957: src = mon_params; 958: len = mon_parmsize; 959: } 960: dst = umap(pp, D, (vir_bytes) sysgetenv.val, sysgetenv.vallen); 961: if (dst == 0) return(EFAULT); 962: if (len > sysgetenv.vallen) return(E2BIG); 963: phys_copy(src, dst, len); 964: return(OK); } 965: 966: default: 967: return(EINVAL); 968: } 969: } 970: 971: /*==========================================================================* 972: * do_puts * 973: *==========================================================================*/ 974: PRIVATE int do_puts(m_ptr) 975: message *m_ptr; /* pointer to request message */ 976: { 977: /* Print a string for a server. */ 978: char c; 979: vir_bytes src; 980: int count; 981: 982: src = (vir_bytes) m_ptr->m1_p1; 983: for (count = m_ptr->m1_i1; count > 0; count--) { 984: if (vir_copy(m_ptr->m_source, src++, 985: SYSTASK, (vir_bytes) &c, 1) != OK) return(EFAULT); 986: putk(c); 987: } 988: putk(0); 989: return(OK); 990: } 991: 992: /*===========================================================================* 993: * do_findproc * 994: *===========================================================================*/ 995: PRIVATE int do_findproc(m_ptr) 996: message *m_ptr; /* pointer to request message */ 997: { 998: /* Determine the task number of a task given its name. This allows a late 999: * started server such as inet to not know any task numbers, so it can be 1000: * used with a kernel whose precise configuration (what task is where?) is 1001: * unknown. 1002: */ 1003: struct proc *pp; 1004: 1005: for (pp= BEG_PROC_ADDR; pp<END_PROC_ADDR; pp++) { 1006: if (!istaskp(pp) && !isservp(pp)) continue; 1007: 1008: if (strncmp(pp->p_name, m_ptr->m3_ca1, M3_STRING) == 0) { 1009: m_ptr->m3_i1 = proc_number(pp); 1010: return(OK); 1011: } 1012: } 1013: return(ESRCH); 1014: } 1015: 1016: /*===========================================================================* 1017: * cause_sig * 1018: *===========================================================================*/ 1019: PUBLIC void cause_sig(proc_nr, sig_nr) 1020: int proc_nr; /* process to be signalled */ 1021: int sig_nr; /* signal to be sent, 1 to _NSIG */ 1022: { 1023: /* A task wants to send a signal to a process. Examples of such tasks are: 1024: * TTY wanting to cause SIGINT upon getting a DEL 1025: * CLOCK wanting to cause SIGALRM when timer expires 1026: * FS also uses this to send a signal, via the SYS_KILL message. 1027: * Signals are handled by sending a message to MM. The tasks don't dare do 1028: * that directly, for fear of what would happen if MM were busy. Instead they 1029: * call cause_sig, which sets bits in p_pending, and then carefully checks to 1030: * see if MM is free. If so, a message is sent to it. If not, when it becomes 1031: * free, a message is sent. The process being signaled is blocked while MM 1032: * has not seen or finished with all signals for it. These signals are 1033: * counted in p_pendcount, and the SIG_PENDING flag is kept nonzero while 1034: * there are some. It is not sufficient to ready the process when MM is 1035: * informed, because MM can block waiting for FS to do a core dump. 1036: */ 1037: 1038: register struct proc *rp, *mmp; 1039: 1040: rp = proc_addr(proc_nr); 1041: if (sigismember(&rp->p_pending, sig_nr)) 1042: return; /* this signal already pending */ 1043: sigaddset(&rp->p_pending, sig_nr); 1044: ++rp->p_pendcount; /* count new signal pending */ 1045: if (rp->p_flags & PENDING) 1046: return; /* another signal already pending */ 1047: if (rp->p_flags == 0) lock_unready(rp); 1048: rp->p_flags |= PENDING | SIG_PENDING; 1049: ++sig_procs; /* count new process pending */ 1050: 1051: mmp = proc_addr(MM_PROC_NR); 1052: if ( ((mmp->p_flags & RECEIVING) == 0) || mmp->p_getfrom != ANY) return; 1053: inform(); 1054: } 1055: 1056: 1057: /*===========================================================================* 1058: * inform * 1059: *===========================================================================*/ 1060: PUBLIC void inform() 1061: { 1062: /* When a signal is detected by the kernel (e.g., DEL), or generated by a task 1063: * (e.g. clock task for SIGALRM), cause_sig() is called to set a bit in the 1064: * p_pending field of the process to signal. Then inform() is called to see 1065: * if MM is idle and can be told about it. Whenever MM blocks, a check is 1066: * made to see if 'sig_procs' is nonzero; if so, inform() is called. 1067: */ 1068: 1069: register struct proc *rp; 1070: 1071: /* MM is waiting for new input. Find a process with pending signals. */ 1072: for (rp = BEG_SERV_ADDR; rp < END_PROC_ADDR; rp++) 1073: if (rp->p_flags & PENDING) { 1074: m.m_type = KSIG; 1075: m.SIG_PROC = proc_number(rp); 1076: m.SIG_MAP = rp->p_pending; 1077: sig_procs--; 1078: if (lock_mini_send(proc_addr(HARDWARE), MM_PROC_NR, &m) != OK) 1079: panic("can't inform MM", NO_NUM); 1080: sigemptyset(&rp->p_pending); /* the ball is now in MM's court */ 1081: rp->p_flags &= ~PENDING;/* remains inhibited by SIG_PENDING */ 1082: lock_pick_proc(); /* avoid delay in scheduling MM */ 1083: return; 1084: } 1085: } 1086: 1087: 1088: /*===========================================================================* 1089: * umap * 1090: *===========================================================================*/ 1091: PUBLIC phys_bytes umap(rp, seg, vir_addr, bytes) 1092: register struct proc *rp; /* pointer to proc table entry for process */ 1093: int seg; /* T, D, or S segment */ 1094: vir_bytes vir_addr; /* virtual address in bytes within the seg */ 1095: vir_bytes bytes; /* # of bytes to be copied */ 1096: { 1097: /* Calculate the physical memory address for a given virtual address. */ 1098: 1099: vir_clicks vc; /* the virtual address in clicks */ 1100: phys_bytes pa; /* intermediate variables as phys_bytes */ 1101: #if (CHIP == INTEL) 1102: phys_bytes seg_base; 1103: #endif 1104: 1105: /* If 'seg' is D it could really be S and vice versa. T really means T. 1106: * If the virtual address falls in the gap, it causes a problem. On the 1107: * 8088 it is probably a legal stack reference, since "stackfaults" are 1108: * not detected by the hardware. On 8088s, the gap is called S and 1109: * accepted, but on other machines it is called D and rejected. 1110: * The Atari ST behaves like the 8088 in this respect. 1111: */ 1112: 1113: if (bytes <= 0) return( (phys_bytes) 0); 1114: vc = (vir_addr + bytes - 1) >> CLICK_SHIFT; /* last click of data */ 1115: 1116: #if (CHIP == INTEL) || (CHIP == M68000) 1117: if (seg != T) 1118: seg = (vc < rp->p_map[D].mem_vir + rp->p_map[D].mem_len ? D : S); 1119: #else 1120: if (seg != T) 1121: seg = (vc < rp->p_map[S].mem_vir ? D : S); 1122: #endif 1123: 1124: if((vir_addr>>CLICK_SHIFT) >= rp->p_map[seg].mem_vir+ rp->p_map[seg].mem_len) 1125: return( (phys_bytes) 0 ); 1126: #if (CHIP == INTEL) 1127: seg_base = (phys_bytes) rp->p_map[seg].mem_phys; 1128: seg_base = seg_base << CLICK_SHIFT; /* segment origin in bytes */ 1129: #endif 1130: pa = (phys_bytes) vir_addr; 1131: #if (CHIP != M68000) 1132: pa -= rp->p_map[seg].mem_vir << CLICK_SHIFT; 1133: return(seg_base + pa); 1134: #endif 1135: #if (CHIP == M68000) 1136: pa -= (phys_bytes)rp->p_map[seg].mem_vir << CLICK_SHIFT; 1137: pa += (phys_bytes)rp->p_map[seg].mem_phys << CLICK_SHIFT; 1138: return(pa); 1139: #endif 1140: } 1141: 1142: 1143: /*==========================================================================* 1144: * numap * 1145: *==========================================================================*/ 1146: PUBLIC phys_bytes numap(proc_nr, vir_addr, bytes) 1147: int proc_nr; /* process number to be mapped */ 1148: vir_bytes vir_addr; /* virtual address in bytes within D seg */ 1149: vir_bytes bytes; /* # of bytes required in segment */ 1150: { 1151: /* Do umap() starting from a process number instead of a pointer. This 1152: * function is used by device drivers, so they need not know about the 1153: * process table. To save time, there is no 'seg' parameter. The segment 1154: * is always D. 1155: */ 1156: 1157: return(umap(proc_addr(proc_nr), D, vir_addr, bytes)); 1158: } 1159: 1160: 1161: /*==========================================================================* 1162: * vir_copy * 1163: *==========================================================================*/ 1164: PUBLIC int vir_copy(src_proc, src_vir, dst_proc, dst_vir, bytes) 1165: int src_proc; /* source process */ 1166: vir_bytes src_vir; /* source virtual address within D seg */ 1167: int dst_proc; /* destination process */ 1168: vir_bytes dst_vir; /* destination virtual address within D seg */ 1169: vir_bytes bytes; /* # of bytes to copy */ 1170: { 1171: /* Copy bytes from one process to another. Meant for the easy cases, where 1172: * speed isn't required. (One can normally do without one of the umaps.) 1173: */ 1174: phys_bytes src_phys, dst_phys; 1175: 1176: src_phys = umap(proc_addr(src_proc), D, src_vir, bytes); 1177: dst_phys = umap(proc_addr(dst_proc), D, dst_vir, bytes); 1178: if (src_phys == 0 || dst_phys == 0) return(EFAULT); 1179: phys_copy(src_phys, dst_phys, (phys_bytes) bytes); 1180: return(OK); 1181: } 1182: 1183: 1184: #if (CHIP == INTEL) 1185: /*==========================================================================* 1186: * alloc_segments * 1187: *==========================================================================*/ 1188: PUBLIC void alloc_segments(rp) 1189: register struct proc *rp; 1190: { 1191: /* This is called only by do_newmap, but is broken out as a separate function 1192: * because so much is hardware-dependent. 1193: */ 1194: 1195: phys_bytes code_bytes; 1196: phys_bytes data_bytes; 1197: int privilege; 1198: 1199: if (protected_mode) { 1200: data_bytes = (phys_bytes) (rp->p_map[S].mem_vir + rp->p_map[S].mem_len) 1201: << CLICK_SHIFT; 1202: if (rp->p_map[T].mem_len == 0) 1203: code_bytes = data_bytes; /* common I&D, poor protect */ 1204: else 1205: code_bytes = (phys_bytes) rp->p_map[T].mem_len << CLICK_SHIFT; 1206: privilege = istaskp(rp) ? TASK_PRIVILEGE : USER_PRIVILEGE; 1207: init_codeseg(&rp->p_ldt[CS_LDT_INDEX], 1208: (phys_bytes) rp->p_map[T].mem_phys << CLICK_SHIFT, 1209: code_bytes, privilege); 1210: init_dataseg(&rp->p_ldt[DS_LDT_INDEX], 1211: (phys_bytes) rp->p_map[D].mem_phys << CLICK_SHIFT, 1212: data_bytes, privilege); 1213: rp->p_reg.cs = (CS_LDT_INDEX * DESC_SIZE) | TI | privilege; 1214: #if _WORD_SIZE == 4 1215: rp->p_reg.gs = 1216: rp->p_reg.fs = 1217: #endif 1218: rp->p_reg.ss = 1219: rp->p_reg.es = 1220: rp->p_reg.ds = (DS_LDT_INDEX*DESC_SIZE) | TI | privilege; 1221: } else { 1222: rp->p_reg.cs = click_to_hclick(rp->p_map[T].mem_phys); 1223: rp->p_reg.ss = 1224: rp->p_reg.es = 1225: rp->p_reg.ds = click_to_hclick(rp->p_map[D].mem_phys); 1226: } 1227: } 1228: #endif /* (CHIP == INTEL) */