source: branches/minix3-book/kernel/system/do_vcopy.c@ 9

Last change on this file since 9 was 4, checked in by Mattia Monga, 14 years ago

Importazione sorgenti libro

File size: 2.2 KB
Line 
1/* The kernel call implemented in this file:
2 * m_type: SYS_VIRVCOPY, SYS_PHYSVCOPY
3 *
4 * The parameters for this kernel call are:
5 * m1_i3: VCP_VEC_SIZE size of copy request vector
6 * m1_p1: VCP_VEC_ADDR address of vector at caller
7 * m1_i2: VCP_NR_OK number of successfull copies
8 */
9
10#include "../system.h"
11#include <minix/type.h>
12
13#if (USE_VIRVCOPY || USE_PHYSVCOPY)
14
15/* Buffer to hold copy request vector from user. */
16PRIVATE struct vir_cp_req vir_cp_req[VCOPY_VEC_SIZE];
17
18/*===========================================================================*
19 * do_vcopy *
20 *===========================================================================*/
21PUBLIC int do_vcopy(m_ptr)
22register message *m_ptr; /* pointer to request message */
23{
24/* Handle sys_virvcopy() and sys_physvcopy() that pass a vector with copy
25 * requests. Although a single handler function is used, there are two
26 * different kernel calls so that permissions can be checked.
27 */
28 int nr_req;
29 int caller_pid;
30 vir_bytes caller_vir;
31 phys_bytes caller_phys;
32 phys_bytes kernel_phys;
33 phys_bytes bytes;
34 int i,s;
35 struct vir_cp_req *req;
36
37 /* Check if request vector size is ok. */
38 nr_req = (unsigned) m_ptr->VCP_VEC_SIZE;
39 if (nr_req > VCOPY_VEC_SIZE) return(EINVAL);
40 bytes = nr_req * sizeof(struct vir_cp_req);
41
42 /* Calculate physical addresses and copy (port,value)-pairs from user. */
43 caller_pid = (int) m_ptr->m_source;
44 caller_vir = (vir_bytes) m_ptr->VCP_VEC_ADDR;
45 caller_phys = umap_local(proc_addr(caller_pid), D, caller_vir, bytes);
46 if (0 == caller_phys) return(EFAULT);
47 kernel_phys = vir2phys(vir_cp_req);
48 phys_copy(caller_phys, kernel_phys, (phys_bytes) bytes);
49
50 /* Assume vector with requests is correct. Try to copy everything. */
51 m_ptr->VCP_NR_OK = 0;
52 for (i=0; i<nr_req; i++) {
53
54 req = &vir_cp_req[i];
55
56 /* Check if physical addressing is used without SYS_PHYSVCOPY. */
57 if (((req->src.segment | req->dst.segment) & PHYS_SEG) &&
58 m_ptr->m_type != SYS_PHYSVCOPY) return(EPERM);
59 if ((s=virtual_copy(&req->src, &req->dst, req->count)) != OK)
60 return(s);
61 m_ptr->VCP_NR_OK ++;
62 }
63 return(OK);
64}
65
66#endif /* (USE_VIRVCOPY || USE_PHYSVCOPY) */
67
Note: See TracBrowser for help on using the repository browser.