ia64/xen-unstable

view xen/arch/ia64/xen/dom0_ops.c @ 11710:0c7e58ba4fbd

[IA64] add perfcounter of dom0vp_phystomach and dom0vp_machtophys

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Mon Oct 02 21:39:44 2006 -0600 (2006-10-02)
parents 74db626d2fcf
children 0bb486157ff5
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/domctl.h>
14 #include <public/sysctl.h>
15 #include <xen/sched.h>
16 #include <xen/event.h>
17 #include <asm/pdb.h>
18 #include <xen/trace.h>
19 #include <xen/console.h>
20 #include <xen/guest_access.h>
21 #include <asm/vmx.h>
22 #include <asm/dom_fw.h>
23 #include <xen/iocap.h>
24 #include <xen/errno.h>
26 void build_physmap_table(struct domain *d);
28 extern unsigned long total_pages;
30 long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
31 {
32 long ret = 0;
34 if ( !IS_PRIV(current->domain) )
35 return -EPERM;
37 switch ( op->cmd )
38 {
39 case XEN_DOMCTL_getmemlist:
40 {
41 unsigned long i;
42 struct domain *d = find_domain_by_id(op->domain);
43 unsigned long start_page = op->u.getmemlist.start_pfn;
44 unsigned long nr_pages = op->u.getmemlist.max_pfns;
45 unsigned long mfn;
47 if ( d == NULL ) {
48 ret = -EINVAL;
49 break;
50 }
51 for (i = 0 ; i < nr_pages ; i++) {
52 pte_t *pte;
54 pte = (pte_t *)lookup_noalloc_domain_pte(d,
55 (start_page + i) << PAGE_SHIFT);
56 if (pte && pte_present(*pte))
57 mfn = pte_pfn(*pte);
58 else
59 mfn = INVALID_MFN;
61 if ( copy_to_guest_offset(op->u.getmemlist.buffer, i, &mfn, 1) ) {
62 ret = -EFAULT;
63 break;
64 }
65 }
67 op->u.getmemlist.num_pfns = i;
68 if (copy_to_guest(u_domctl, op, 1))
69 ret = -EFAULT;
71 put_domain(d);
72 }
73 break;
75 case XEN_DOMCTL_arch_setup:
76 {
77 xen_domctl_arch_setup_t *ds = &op->u.arch_setup;
78 struct domain *d = find_domain_by_id(op->domain);
80 if ( d == NULL) {
81 ret = -EINVAL;
82 break;
83 }
85 if (ds->flags & XEN_DOMAINSETUP_query) {
86 /* Set flags. */
87 if (d->arch.is_vti)
88 ds->flags |= XEN_DOMAINSETUP_hvm_guest;
89 /* Set params. */
90 ds->bp = 0; /* unknown. */
91 ds->maxmem = 0; /* unknown. */
92 ds->xsi_va = d->arch.shared_info_va;
93 ds->hypercall_imm = d->arch.breakimm;
94 /* Copy back. */
95 if ( copy_to_guest(u_domctl, op, 1) )
96 ret = -EFAULT;
97 }
98 else {
99 if (ds->flags & XEN_DOMAINSETUP_hvm_guest) {
100 if (!vmx_enabled) {
101 printk("No VMX hardware feature for vmx domain.\n");
102 ret = -EINVAL;
103 break;
104 }
105 if (!d->arch.is_vti) {
106 struct vcpu *v;
107 for_each_vcpu(d, v) {
108 BUG_ON(v->arch.privregs == NULL);
109 free_domheap_pages(virt_to_page(v->arch.privregs),
110 get_order_from_shift(XMAPPEDREGS_SHIFT));
111 relinquish_vcpu_resources(v);
112 }
113 }
114 d->arch.is_vti = 1;
115 vmx_setup_platform(d);
116 }
117 else {
118 build_physmap_table(d);
119 dom_fw_setup(d, ds->bp, ds->maxmem);
120 if (ds->xsi_va)
121 d->arch.shared_info_va = ds->xsi_va;
122 if (ds->hypercall_imm) {
123 struct vcpu *v;
124 d->arch.breakimm = ds->hypercall_imm;
125 for_each_vcpu (d, v)
126 v->arch.breakimm = d->arch.breakimm;
127 }
128 }
129 }
131 put_domain(d);
132 }
133 break;
135 case XEN_DOMCTL_shadow_op:
136 {
137 struct domain *d;
138 ret = -ESRCH;
139 d = find_domain_by_id(op->domain);
140 if ( d != NULL )
141 {
142 ret = shadow_mode_control(d, &op->u.shadow_op);
143 put_domain(d);
144 copy_to_guest(u_domctl, op, 1);
145 }
146 }
147 break;
149 case XEN_DOMCTL_ioport_permission:
150 {
151 struct domain *d;
152 unsigned int fp = op->u.ioport_permission.first_port;
153 unsigned int np = op->u.ioport_permission.nr_ports;
154 unsigned int lp = fp + np - 1;
156 ret = -ESRCH;
157 d = find_domain_by_id(op->domain);
158 if (unlikely(d == NULL))
159 break;
161 if (np == 0)
162 ret = 0;
163 else {
164 if (op->u.ioport_permission.allow_access)
165 ret = ioports_permit_access(d, fp, lp);
166 else
167 ret = ioports_deny_access(d, fp, lp);
168 }
170 put_domain(d);
171 }
172 break;
173 default:
174 printf("arch_do_domctl: unrecognized domctl: %d!!!\n",op->cmd);
175 ret = -ENOSYS;
177 }
179 return ret;
180 }
182 long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
183 {
184 long ret = 0;
186 if ( !IS_PRIV(current->domain) )
187 return -EPERM;
189 switch ( op->cmd )
190 {
191 case XEN_SYSCTL_physinfo:
192 {
193 xen_sysctl_physinfo_t *pi = &op->u.physinfo;
195 pi->threads_per_core =
196 cpus_weight(cpu_sibling_map[0]);
197 pi->cores_per_socket =
198 cpus_weight(cpu_core_map[0]) / pi->threads_per_core;
199 pi->sockets_per_node =
200 num_online_cpus() / cpus_weight(cpu_core_map[0]);
201 pi->nr_nodes = 1;
202 pi->total_pages = total_pages;
203 pi->free_pages = avail_domheap_pages();
204 pi->cpu_khz = local_cpu_data->proc_freq / 1000;
205 memset(pi->hw_cap, 0, sizeof(pi->hw_cap));
206 //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
207 ret = 0;
208 if ( copy_to_guest(u_sysctl, op, 1) )
209 ret = -EFAULT;
210 }
211 break;
213 default:
214 printf("arch_do_sysctl: unrecognized sysctl: %d!!!\n",op->cmd);
215 ret = -ENOSYS;
217 }
219 return ret;
220 }
222 static unsigned long
223 dom0vp_ioremap(struct domain *d, unsigned long mpaddr, unsigned long size)
224 {
225 unsigned long end;
227 /* Linux may use a 0 size! */
228 if (size == 0)
229 size = PAGE_SIZE;
231 end = PAGE_ALIGN(mpaddr + size);
233 if (!iomem_access_permitted(d, mpaddr >> PAGE_SHIFT,
234 (end >> PAGE_SHIFT) - 1))
235 return -EPERM;
237 return assign_domain_mmio_page(d, mpaddr, size);
238 }
240 unsigned long
241 do_dom0vp_op(unsigned long cmd,
242 unsigned long arg0, unsigned long arg1, unsigned long arg2,
243 unsigned long arg3)
244 {
245 unsigned long ret = 0;
246 struct domain *d = current->domain;
248 switch (cmd) {
249 case IA64_DOM0VP_ioremap:
250 ret = dom0vp_ioremap(d, arg0, arg1);
251 break;
252 case IA64_DOM0VP_phystomach:
253 ret = ____lookup_domain_mpa(d, arg0 << PAGE_SHIFT);
254 if (ret == INVALID_MFN) {
255 DPRINTK("%s:%d INVALID_MFN ret: 0x%lx\n", __func__, __LINE__, ret);
256 } else {
257 ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
258 }
259 perfc_incrc(dom0vp_phystomach);
260 break;
261 case IA64_DOM0VP_machtophys:
262 if (!mfn_valid(arg0)) {
263 ret = INVALID_M2P_ENTRY;
264 break;
265 }
266 ret = get_gpfn_from_mfn(arg0);
267 perfc_incrc(dom0vp_machtophys);
268 break;
269 case IA64_DOM0VP_zap_physmap:
270 ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
271 break;
272 case IA64_DOM0VP_add_physmap:
273 ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
274 (domid_t)arg3);
275 break;
276 default:
277 ret = -1;
278 printf("unknown dom0_vp_op 0x%lx\n", cmd);
279 break;
280 }
282 return ret;
283 }
285 /*
286 * Local variables:
287 * mode: C
288 * c-set-style: "BSD"
289 * c-basic-offset: 4
290 * tab-width: 4
291 * indent-tabs-mode: nil
292 * End:
293 */