blob: c1b1d5c241e4b2c14f7ca2fa71b69b6b064d3f46 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
/******************************************************************************
* Arch-specific dom0_ops.c
*
* Process command requests from domain-0 guest OS.
*
* Copyright (c) 2002, K A Fraser
*/
#include <xen/config.h>
#include <xen/types.h>
#include <xen/lib.h>
#include <xen/mm.h>
#include <public/dom0_ops.h>
#include <xen/sched.h>
#include <xen/event.h>
#include <asm/pdb.h>
#include <xen/trace.h>
#include <xen/console.h>
#include <public/sched_ctl.h>
long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
{
long ret = 0;
if ( !IS_PRIV(current->domain) )
return -EPERM;
switch ( op->cmd )
{
/*
* NOTE: DOM0_GETMEMLIST has somewhat different semantics on IA64 -
* it actually allocates and maps pages.
*/
case DOM0_GETMEMLIST:
{
unsigned long i;
struct domain *d = find_domain_by_id(op->u.getmemlist.domain);
unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
unsigned long pfn;
unsigned long *buffer = op->u.getmemlist.buffer;
struct page *page;
ret = -EINVAL;
if ( d != NULL )
{
ret = 0;
for ( i = start_page; i < (start_page + nr_pages); i++ )
{
page = map_new_domain_page(d, i << PAGE_SHIFT);
if ( page == NULL )
{
ret = -ENOMEM;
break;
}
pfn = page_to_pfn(page);
if ( put_user(pfn, buffer) )
{
ret = -EFAULT;
break;
}
buffer++;
}
op->u.getmemlist.num_pfns = i - start_page;
copy_to_user(u_dom0_op, op, sizeof(*op));
put_domain(d);
}
}
break;
default:
ret = -ENOSYS;
}
return ret;
}
|