aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.24-sparse/arch/xeno/drivers/dom0/dom0_core.c
blob: 08144d967891789006117705cdb0b54d756d94c9 (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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/******************************************************************************
 * dom0_core.c
 * 
 * Interface to privileged domain-0 commands.
 * 
 * Copyright (c) 2002-2003, K A Fraser, B Dragovic
 */

#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/swap.h>
#include <linux/smp_lock.h>
#include <linux/swapctl.h>
#include <linux/iobuf.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/seq_file.h>

#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
#include <asm/tlb.h>
#include <asm/proc_cmd.h>
#include <asm/hypervisor-ifs/dom0_ops.h>
#include <asm/xeno_proc.h>

#include "../block/xl_block.h"

static struct proc_dir_entry *privcmd_intf;


static int privcmd_ioctl(struct inode *inode, struct file *file,
                         unsigned int cmd, unsigned long data)
{
    int ret = 0;

    switch ( cmd )
    {
    case IOCTL_PRIVCMD_HYPERCALL:
    {
        privcmd_hypercall_t hypercall;
  
        if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
            return -EFAULT;

        __asm__ __volatile__ (
            "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
            "movl  4(%%eax),%%ebx ;"
            "movl  8(%%eax),%%ecx ;"
            "movl 12(%%eax),%%edx ;"
            "movl 16(%%eax),%%esi ;"
            "movl 20(%%eax),%%edi ;"
            "movl   (%%eax),%%eax ;"
            TRAP_INSTR "; "
            "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
            : "=a" (ret) : "0" (&hypercall) : "memory" );

    }
    break;

    default:
        ret = -EINVAL;
    	break;
	}
    return ret;
}


static struct file_operations privcmd_file_ops = {
  ioctl : privcmd_ioctl
};


static int __init init_module(void)
{
    if ( !(start_info.flags & SIF_PRIVILEGED) )
        return 0;

    /* xeno control interface */
    privcmd_intf = create_xeno_proc_entry("privcmd", 0400);
    if ( privcmd_intf != NULL )
    {
        privcmd_intf->owner      = THIS_MODULE;
        privcmd_intf->nlink      = 1;
	privcmd_intf->proc_fops  = &privcmd_file_ops;
    }

    return 0;
}


static void __exit cleanup_module(void)
{
    if ( privcmd_intf == NULL ) return;
    remove_xeno_proc_entry("privcmd");
    privcmd_intf = NULL;
}


module_init(init_module);
module_exit(cleanup_module);