direct-io.hg

view xen/arch/ia64/xen/dom0_ops.c @ 10613:59d4c1863330

[IA64] dom0vp machtophys fix argument check

fix argument check of dom0vp machtophys hypercall. use valid_mfn()

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Fri Jun 23 15:26:01 2006 -0600 (2006-06-23)
parents 299f048c4855
children 74018b65c369 8dc4af3f192c
line source
1 /******************************************************************************
2 * Arch-specific dom0_ops.c
3 *
4 * Process command requests from domain-0 guest OS.
5 *
6 * Copyright (c) 2002, K A Fraser
7 */
9 #include <xen/config.h>
10 #include <xen/types.h>
11 #include <xen/lib.h>
12 #include <xen/mm.h>
13 #include <public/dom0_ops.h>
14 #include <xen/sched.h>
15 #include <xen/event.h>
16 #include <asm/pdb.h>
17 #include <xen/trace.h>
18 #include <xen/console.h>
19 #include <xen/guest_access.h>
20 #include <public/sched_ctl.h>
21 #include <asm/vmx.h>
22 extern unsigned long total_pages;
23 long arch_do_dom0_op(dom0_op_t *op, XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
24 {
25 long ret = 0;
27 if ( !IS_PRIV(current->domain) )
28 return -EPERM;
30 switch ( op->cmd )
31 {
32 case DOM0_GETPAGEFRAMEINFO:
33 {
34 struct page_info *page;
35 unsigned long mfn = op->u.getpageframeinfo.mfn;
36 domid_t dom = op->u.getpageframeinfo.domain;
37 struct domain *d;
39 ret = -EINVAL;
41 if ( unlikely(!mfn_valid(mfn)) ||
42 unlikely((d = find_domain_by_id(dom)) == NULL) )
43 break;
45 page = mfn_to_page(mfn);
47 if ( likely(get_page(page, d)) )
48 {
49 ret = 0;
51 op->u.getpageframeinfo.type = NOTAB;
53 if ( (page->u.inuse.type_info & PGT_count_mask) != 0 )
54 {
55 switch ( page->u.inuse.type_info & PGT_type_mask )
56 {
57 default:
58 panic("No such page type\n");
59 break;
60 }
61 }
63 put_page(page);
64 }
66 put_domain(d);
68 copy_to_guest(u_dom0_op, op, 1);
69 }
70 break;
72 case DOM0_GETPAGEFRAMEINFO2:
73 {
74 #define GPF2_BATCH 128
75 int n,j;
76 int num = op->u.getpageframeinfo2.num;
77 domid_t dom = op->u.getpageframeinfo2.domain;
78 struct domain *d;
79 unsigned long *l_arr;
80 ret = -ESRCH;
82 if ( unlikely((d = find_domain_by_id(dom)) == NULL) )
83 break;
85 if ( unlikely(num > 1024) )
86 {
87 ret = -E2BIG;
88 break;
89 }
91 l_arr = (unsigned long *)alloc_xenheap_page();
93 ret = 0;
94 for( n = 0; n < num; )
95 {
96 int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n);
98 if ( copy_from_guest_offset(l_arr, op->u.getpageframeinfo2.array,
99 n, k) )
100 {
101 ret = -EINVAL;
102 break;
103 }
105 for( j = 0; j < k; j++ )
106 {
107 struct page_info *page;
108 unsigned long mfn = l_arr[j];
110 if ( unlikely(mfn >= max_page) )
111 goto e2_err;
113 page = mfn_to_page(mfn);
115 if ( likely(get_page(page, d)) )
116 {
117 unsigned long type = 0;
119 switch( page->u.inuse.type_info & PGT_type_mask )
120 {
121 default:
122 panic("No such page type\n");
123 break;
124 }
126 if ( page->u.inuse.type_info & PGT_pinned )
127 type |= LPINTAB;
128 l_arr[j] |= type;
129 put_page(page);
130 }
131 else
132 {
133 e2_err:
134 l_arr[j] |= XTAB;
135 }
137 }
139 if ( copy_to_guest_offset(op->u.getpageframeinfo2.array,
140 n, l_arr, k) )
141 {
142 ret = -EINVAL;
143 break;
144 }
146 n += j;
147 }
149 free_xenheap_page((void *) l_arr);
151 put_domain(d);
152 }
153 break;
155 case DOM0_GETMEMLIST:
156 {
157 unsigned long i = 0;
158 struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
159 unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
160 unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
161 unsigned long mfn;
162 struct list_head *list_ent;
164 ret = -EINVAL;
165 if ( d != NULL )
166 {
167 ret = 0;
169 list_ent = d->page_list.next;
170 while ( (i != start_page) && (list_ent != &d->page_list)) {
171 mfn = page_to_mfn(list_entry(
172 list_ent, struct page_info, list));
173 i++;
174 list_ent = mfn_to_page(mfn)->list.next;
175 }
177 if (i == start_page)
178 {
179 while((i < (start_page + nr_pages)) &&
180 (list_ent != &d->page_list))
181 {
182 mfn = page_to_mfn(list_entry(
183 list_ent, struct page_info, list));
185 if ( copy_to_guest_offset(op->u.getmemlist.buffer,
186 i - start_page, &mfn, 1) )
187 {
188 ret = -EFAULT;
189 break;
190 }
191 i++;
192 list_ent = mfn_to_page(mfn)->list.next;
193 }
194 } else
195 ret = -ENOMEM;
197 op->u.getmemlist.num_pfns = i - start_page;
198 if (copy_to_guest(u_dom0_op, op, 1))
199 ret = -EFAULT;
201 put_domain(d);
202 }
203 }
204 break;
206 case DOM0_PHYSINFO:
207 {
208 dom0_physinfo_t *pi = &op->u.physinfo;
210 pi->threads_per_core =
211 cpus_weight(cpu_sibling_map[0]);
212 pi->cores_per_socket =
213 cpus_weight(cpu_core_map[0]) / pi->threads_per_core;
214 pi->sockets_per_node =
215 num_online_cpus() / cpus_weight(cpu_core_map[0]);
216 pi->nr_nodes = 1;
217 pi->total_pages = total_pages;
218 pi->free_pages = avail_domheap_pages();
219 pi->cpu_khz = local_cpu_data->proc_freq / 1000;
220 memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
221 //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
222 ret = 0;
223 if ( copy_to_guest(u_dom0_op, op, 1) )
224 ret = -EFAULT;
225 }
226 break;
228 default:
229 printf("arch_do_dom0_op: unrecognized dom0 op: %d!!!\n",op->cmd);
230 ret = -ENOSYS;
232 }
234 return ret;
235 }
237 #ifdef CONFIG_XEN_IA64_DOM0_VP
238 unsigned long
239 do_dom0vp_op(unsigned long cmd,
240 unsigned long arg0, unsigned long arg1, unsigned long arg2,
241 unsigned long arg3)
242 {
243 unsigned long ret = 0;
244 struct domain *d = current->domain;
246 switch (cmd) {
247 case IA64_DOM0VP_ioremap:
248 ret = assign_domain_mmio_page(d, arg0, arg1);
249 break;
250 case IA64_DOM0VP_phystomach:
251 ret = ____lookup_domain_mpa(d, arg0 << PAGE_SHIFT);
252 if (ret == INVALID_MFN) {
253 DPRINTK("%s:%d INVALID_MFN ret: 0x%lx\n", __func__, __LINE__, ret);
254 } else {
255 ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
256 }
257 break;
258 case IA64_DOM0VP_machtophys:
259 if (!mfn_valid(arg0)) {
260 ret = INVALID_M2P_ENTRY;
261 break;
262 }
263 ret = get_gpfn_from_mfn(arg0);
264 break;
265 case IA64_DOM0VP_zap_physmap:
266 ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
267 break;
268 case IA64_DOM0VP_add_physmap:
269 ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
270 (domid_t)arg3);
271 break;
272 default:
273 ret = -1;
274 printf("unknown dom0_vp_op 0x%lx\n", cmd);
275 break;
276 }
278 return ret;
279 }
280 #endif
282 /*
283 * Local variables:
284 * mode: C
285 * c-set-style: "BSD"
286 * c-basic-offset: 4
287 * tab-width: 4
288 * indent-tabs-mode: nil
289 * End:
290 */