aboutsummaryrefslogtreecommitdiffstats
path: root/xen/arch/ia64/dom0_ops.c
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;
}