1 /* The kernel call implemented in this file:
2 * m_type: SYS_UMAP_REMOTE
4 * The parameters for this kernel call are:
5 * m_lsys_krn_sys_umap.src_endpt (process number)
6 * m_lsys_krn_sys_umap.segment (segment where address is: T, D, or S)
7 * m_lsys_krn_sys_umap.src_addr (virtual address)
8 * m_lsys_krn_sys_umap.dst_endpt (process number of grantee to check access for)
9 * m_krn_lsys_sys_umap.dst_addr (returns physical address)
10 * m_lsys_krn_sys_umap.nr_bytes (size of datastructure)
13 #include "kernel/system.h"
15 #include <minix/endpoint.h>
17 #if USE_UMAP || USE_UMAP_REMOTE
23 /*==========================================================================*
25 *==========================================================================*/
26 int do_umap_remote(struct proc
* caller
, message
* m_ptr
)
28 /* Map virtual address to physical, for non-kernel processes. */
29 int seg_type
= m_ptr
->m_lsys_krn_sys_umap
.segment
& SEGMENT_TYPE
;
30 int seg_index
= m_ptr
->m_lsys_krn_sys_umap
.segment
& SEGMENT_INDEX
;
31 vir_bytes offset
= m_ptr
->m_lsys_krn_sys_umap
.src_addr
;
32 int count
= m_ptr
->m_lsys_krn_sys_umap
.nr_bytes
;
33 endpoint_t endpt
= m_ptr
->m_lsys_krn_sys_umap
.src_endpt
;
34 endpoint_t grantee
= m_ptr
->m_lsys_krn_sys_umap
.dst_endpt
;
35 int proc_nr
, proc_nr_grantee
;
36 phys_bytes phys_addr
= 0, lin_addr
= 0;
37 struct proc
*targetpr
;
39 /* Verify process number. */
41 okendpt(caller
->p_endpoint
, &proc_nr
);
43 if (! isokendpt(endpt
, &proc_nr
))
45 targetpr
= proc_addr(proc_nr
);
47 /* Verify grantee endpoint */
48 if (grantee
== SELF
) {
49 grantee
= caller
->p_endpoint
;
50 } else if (grantee
== NONE
||
52 seg_index
!= MEM_GRANT
||
53 !isokendpt(grantee
, &proc_nr_grantee
)) {
57 /* See which mapping should be made. */
60 if(seg_index
== MEM_GRANT
) {
64 cp_grant_id_t grant
= (cp_grant_id_t
) offset
;
66 if(verify_grant(targetpr
->p_endpoint
, grantee
, grant
, count
,
67 0, 0, &newoffset
, &newep
, NULL
) != OK
) {
68 printf("SYSTEM: do_umap: verify_grant in %s, grant %d, bytes 0x%lx, failed, caller %s\n", targetpr
->p_name
, offset
, count
, caller
->p_name
);
69 proc_stacktrace(caller
);
73 if(!isokendpt(newep
, &new_proc_nr
)) {
74 printf("SYSTEM: do_umap: isokendpt failed\n");
80 targetpr
= proc_addr(new_proc_nr
);
84 if(seg_index
== VIR_ADDR
) {
85 phys_addr
= lin_addr
= offset
;
87 printf("SYSTEM: bogus seg type 0x%lx\n", seg_index
);
91 printf("SYSTEM:do_umap: umap_local failed\n");
94 if(vm_lookup(targetpr
, lin_addr
, &phys_addr
, NULL
) != OK
) {
95 printf("SYSTEM:do_umap: vm_lookup failed\n");
99 panic("vm_lookup returned zero physical address");
102 printf("umap: peculiar type\n");
106 if(vm_running
&& vm_lookup_range(targetpr
, lin_addr
, NULL
, count
) != count
) {
107 printf("SYSTEM:do_umap: not contiguous\n");
111 m_ptr
->m_krn_lsys_sys_umap
.dst_addr
= phys_addr
;
113 printf("kernel: umap 0x%x done by %d / %s, pc 0x%lx, 0x%lx -> 0x%lx\n",
114 seg_type
, caller
->p_endpoint
, caller
->p_name
,
115 caller
->p_reg
.pc
, offset
, phys_addr
);
116 printf("caller stack: ");
117 proc_stacktrace(caller
);
119 return (phys_addr
== 0) ? EFAULT
: OK
;
122 #endif /* USE_UMAP || USE_UMAP_REMOTE */