24 |
#include "trace.h" |
#include "trace.h" |
25 |
|
|
26 |
#include "vm-object.h" |
#include "vm-object.h" |
27 |
|
#include "vm-page.h" |
28 |
|
#include "vm-fault.h" |
29 |
|
|
30 |
/* Map OBJECT at into the address space of TASK. If ANYWHERE_P is |
/* Map OBJECT at into the address space of TASK. If ANYWHERE_P is |
31 |
false we try to map the object at *OFFSETP, otherwise the kernel |
false we try to map the object at *OFFSETP, otherwise the kernel |
72 |
} |
} |
73 |
return KERN_SUCCESS; |
return KERN_SUCCESS; |
74 |
} |
} |
75 |
|
|
76 |
|
/* Write into TASKs address space at offset DST_OFFSET, from current |
77 |
|
tasks address space at SRC_OFFSET. Copy LENGTH bytes. */ |
78 |
|
|
79 |
|
kern_return_t |
80 |
|
vm_write (struct task *task, vm_offset_t dst_offset, |
81 |
|
vm_offset_t src_offset, vm_size_t length) |
82 |
|
{ |
83 |
|
struct vm_object *object; |
84 |
|
struct vm_map_entry *entry; |
85 |
|
struct vm_map *real_map; |
86 |
|
struct vm_page *page; |
87 |
|
vm_size_t diff, size; |
88 |
|
vm_offset_t address, pa; |
89 |
|
vm_prot_t prot; |
90 |
|
bool wired_p; |
91 |
|
kern_return_t kr; |
92 |
|
|
93 |
|
/* First we try to locate the object we should copy memory |
94 |
|
into. */ |
95 |
|
real_map = task->map; |
96 |
|
kr = vm_map_lookup (&real_map, dst_offset, VM_PROT_WRITE, &object, |
97 |
|
&address, &prot, &wired_p, &entry); |
98 |
|
if (kr != KERN_SUCCESS) |
99 |
|
return kr; |
100 |
|
|
101 |
|
|
102 |
|
while (length) |
103 |
|
{ |
104 |
|
/* Number of bytes we can copy in this page. */ |
105 |
|
diff = (VM_PAGE_SIZE - (dst_offset & VM_PAGE_MASK)); |
106 |
|
|
107 |
|
size = length; |
108 |
|
if (length > diff) |
109 |
|
size = diff; |
110 |
|
|
111 |
|
/* Get page */ |
112 |
|
lookup_page: |
113 |
|
page = vm_page_lookup (object, |
114 |
|
vm_trunc_page ((dst_offset - address))); |
115 |
|
if (! page) |
116 |
|
{ |
117 |
|
vm_offset_t fault_offset; |
118 |
|
|
119 |
|
fault_offset = |
120 |
|
vm_trunc_page (dst_offset) + VM_USER_MIN_ADDRESS; |
121 |
|
|
122 |
|
kr = vm_fault (task->map, fault_offset, VM_PROT_WRITE, false); |
123 |
|
if (kr) |
124 |
|
return kr; |
125 |
|
goto lookup_page; |
126 |
|
} |
127 |
|
|
128 |
|
pa = page->phys_addr + (dst_offset & VM_PAGE_MASK); |
129 |
|
COPYIN ((void *) pa, (void *) src_offset, size); |
130 |
|
|
131 |
|
src_offset += size; |
132 |
|
dst_offset += size; |
133 |
|
length -= size; |
134 |
|
} |
135 |
|
return KERN_SUCCESS; |
136 |
|
} |