ia64/xen-unstable

view xen/arch/ia64/xen/dom0_ops.c @ 9494:71e0c2ed4447

[IA64] Fixed DOM0_PHYSINFO

This patch fixed the DOM0_PHYSINFO hypercall.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
author awilliam@xenbuild.aw
date Fri Apr 07 11:35:29 2006 -0600 (2006-04-07)
parents 827c65c06a66
children f6e8c269f6af
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>
23 long arch_do_dom0_op(dom0_op_t *op, 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 = &frame_table[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 = &frame_table[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;
154 /*
155 * NOTE: DOM0_GETMEMLIST has somewhat different semantics on IA64 -
156 * it actually allocates and maps pages.
157 */
158 case DOM0_GETMEMLIST:
159 {
160 unsigned long i = 0;
161 struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
162 unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
163 unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
164 unsigned long mfn;
165 struct list_head *list_ent;
167 ret = -EINVAL;
168 if ( d != NULL )
169 {
170 ret = 0;
172 list_ent = d->page_list.next;
173 while ( (i != start_page) && (list_ent != &d->page_list)) {
174 mfn = page_to_mfn(list_entry(
175 list_ent, struct page_info, list));
176 i++;
177 list_ent = mfn_to_page(mfn)->list.next;
178 }
180 if (i == start_page)
181 {
182 while((i < (start_page + nr_pages)) &&
183 (list_ent != &d->page_list))
184 {
185 mfn = page_to_mfn(list_entry(
186 list_ent, struct page_info, list));
188 if ( copy_to_guest_offset(op->u.getmemlist.buffer,
189 i - start_page, &mfn, 1) )
190 {
191 ret = -EFAULT;
192 break;
193 }
194 i++;
195 list_ent = mfn_to_page(mfn)->list.next;
196 }
197 } else
198 ret = -ENOMEM;
200 op->u.getmemlist.num_pfns = i - start_page;
201 copy_to_guest(u_dom0_op, op, 1);
203 put_domain(d);
204 }
205 }
206 break;
208 case DOM0_PHYSINFO:
209 {
210 dom0_physinfo_t *pi = &op->u.physinfo;
212 pi->threads_per_core =
213 cpus_weight(cpu_sibling_map[0]);
214 pi->cores_per_socket =
215 cpus_weight(cpu_core_map[0]) / pi->threads_per_core;
216 pi->sockets_per_node =
217 num_online_cpus() / cpus_weight(cpu_core_map[0]);
218 pi->nr_nodes = 1;
219 pi->total_pages = 99; // FIXME
220 pi->free_pages = avail_domheap_pages();
221 pi->cpu_khz = local_cpu_data->proc_freq / 1000;
222 memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
223 //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
224 ret = 0;
225 if ( copy_to_guest(u_dom0_op, op, 1) )
226 ret = -EFAULT;
227 }
228 break;
230 default:
231 printf("arch_do_dom0_op: unrecognized dom0 op: %d!!!\n",op->cmd);
232 ret = -ENOSYS;
234 }
236 return ret;
237 }
239 /*
240 * Local variables:
241 * mode: C
242 * c-set-style: "BSD"
243 * c-basic-offset: 4
244 * tab-width: 4
245 * indent-tabs-mode: nil
246 * End:
247 */