1 /* The kernel call implemented in this file:
2 * m_type: SYS_VIRVCOPY, SYS_PHYSVCOPY
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
10 #include "../system.h"
11 #include <minix/type.h>
13 #if (USE_VIRVCOPY || USE_PHYSVCOPY)
15 /* Buffer to hold copy request vector from user. */
16 PRIVATE
struct vir_cp_req vir_cp_req
[VCOPY_VEC_SIZE
];
18 /*===========================================================================*
20 *===========================================================================*/
21 PUBLIC
int do_vcopy(m_ptr
)
22 register message
*m_ptr
; /* pointer to request message */
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.
30 phys_bytes caller_phys
;
31 phys_bytes kernel_phys
;
34 struct vir_cp_req
*req
;
40 kprintf("do_vcopy: got request from %d\n", m_ptr
->m_source
);
44 /* Check if request vector size is ok. */
45 nr_req
= (unsigned) m_ptr
->VCP_VEC_SIZE
;
46 if (nr_req
> VCOPY_VEC_SIZE
) return(EINVAL
);
47 bytes
= nr_req
* sizeof(struct vir_cp_req
);
49 /* Calculate physical addresses and copy (port,value)-pairs from user. */
50 caller_vir
= (vir_bytes
) m_ptr
->VCP_VEC_ADDR
;
51 caller_phys
= umap_local(proc_addr(who_p
), D
, caller_vir
, bytes
);
52 if (0 == caller_phys
) return(EFAULT
);
53 kernel_phys
= vir2phys(vir_cp_req
);
54 phys_copy(caller_phys
, kernel_phys
, (phys_bytes
) bytes
);
56 /* Assume vector with requests is correct. Try to copy everything. */
58 for (i
=0; i
<nr_req
; i
++) {
62 /* Check if physical addressing is used without SYS_PHYSVCOPY. */
63 if (((req
->src
.segment
| req
->dst
.segment
) & PHYS_SEG
) &&
64 m_ptr
->m_type
!= SYS_PHYSVCOPY
) return(EPERM
);
65 if ((s
=virtual_copy(&req
->src
, &req
->dst
, req
->count
)) != OK
)
72 #endif /* (USE_VIRVCOPY || USE_PHYSVCOPY) */