source: trunk/packages/xen-3.1/xen-3.1/xen/arch/x86/platform_hypercall.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 4.1 KB
Line 
1/******************************************************************************
2 * platform_hypercall.c
3 *
4 * Hardware platform operations. Intended for use by domain-0 kernel.
5 *
6 * Copyright (c) 2002-2006, K Fraser
7 */
8
9#include <xen/config.h>
10#include <xen/types.h>
11#include <xen/lib.h>
12#include <xen/mm.h>
13#include <xen/sched.h>
14#include <xen/domain.h>
15#include <xen/event.h>
16#include <xen/domain_page.h>
17#include <xen/trace.h>
18#include <xen/console.h>
19#include <xen/iocap.h>
20#include <xen/guest_access.h>
21#include <asm/current.h>
22#include <public/platform.h>
23#include <asm/mtrr.h>
24#include "cpu/mtrr/mtrr.h"
25
26#ifndef COMPAT
27typedef long ret_t;
28DEFINE_SPINLOCK(xenpf_lock);
29#else
30extern spinlock_t xenpf_lock;
31#endif
32
33ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
34{
35    ret_t ret = 0;
36    struct xen_platform_op curop, *op = &curop;
37
38    if ( !IS_PRIV(current->domain) )
39        return -EPERM;
40
41    if ( copy_from_guest(op, u_xenpf_op, 1) )
42        return -EFAULT;
43
44    if ( op->interface_version != XENPF_INTERFACE_VERSION )
45        return -EACCES;
46
47    spin_lock(&xenpf_lock);
48
49    switch ( op->cmd )
50    {
51    case XENPF_settime:
52    {
53        do_settime(op->u.settime.secs, 
54                   op->u.settime.nsecs, 
55                   op->u.settime.system_time);
56        ret = 0;
57    }
58    break;
59
60    case XENPF_add_memtype:
61    {
62        ret = mtrr_add_page(
63            op->u.add_memtype.mfn,
64            op->u.add_memtype.nr_mfns,
65            op->u.add_memtype.type,
66            1);
67        if ( ret >= 0 )
68        {
69            op->u.add_memtype.handle = 0;
70            op->u.add_memtype.reg    = ret;
71            ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
72            if ( ret != 0 )
73                mtrr_del_page(ret, 0, 0);
74        }
75    }
76    break;
77
78    case XENPF_del_memtype:
79    {
80        if (op->u.del_memtype.handle == 0
81            /* mtrr/main.c otherwise does a lookup */
82            && (int)op->u.del_memtype.reg >= 0)
83        {
84            ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0);
85            if ( ret > 0 )
86                ret = 0;
87        }
88        else
89            ret = -EINVAL;
90    }
91    break;
92
93    case XENPF_read_memtype:
94    {
95        unsigned long mfn;
96        unsigned int  nr_mfns;
97        mtrr_type     type;
98
99        ret = -EINVAL;
100        if ( op->u.read_memtype.reg < num_var_ranges )
101        {
102            mtrr_if->get(op->u.read_memtype.reg, &mfn, &nr_mfns, &type);
103            op->u.read_memtype.mfn     = mfn;
104            op->u.read_memtype.nr_mfns = nr_mfns;
105            op->u.read_memtype.type    = type;
106            ret = copy_to_guest(u_xenpf_op, op, 1) ? -EFAULT : 0;
107        }
108    }
109    break;
110
111    case XENPF_microcode_update:
112    {
113        extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
114#ifndef COMPAT
115        ret = microcode_update(op->u.microcode.data,
116                               op->u.microcode.length);
117#else
118        XEN_GUEST_HANDLE(void) data;
119
120        guest_from_compat_handle(data, op->u.microcode.data);
121        ret = microcode_update(data, op->u.microcode.length);
122#endif
123    }
124    break;
125
126    case XENPF_platform_quirk:
127    {
128        extern int opt_noirqbalance;
129        int quirk_id = op->u.platform_quirk.quirk_id;
130        switch ( quirk_id )
131        {
132        case QUIRK_NOIRQBALANCING:
133            printk("Platform quirk -- Disabling IRQ balancing/affinity.\n");
134            opt_noirqbalance = 1;
135            setup_ioapic_dest();
136            break;
137        case QUIRK_IOAPIC_BAD_REGSEL:
138        case QUIRK_IOAPIC_GOOD_REGSEL:
139#ifndef sis_apic_bug
140            sis_apic_bug = (quirk_id == QUIRK_IOAPIC_BAD_REGSEL);
141            dprintk(XENLOG_INFO, "Domain 0 says that IO-APIC REGSEL is %s\n",
142                    sis_apic_bug ? "bad" : "good");
143#else
144            BUG_ON(sis_apic_bug != (quirk_id == QUIRK_IOAPIC_BAD_REGSEL));
145#endif
146            break;
147        default:
148            ret = -EINVAL;
149            break;
150        }
151    }
152    break;
153
154    default:
155        ret = -ENOSYS;
156        break;
157    }
158
159    spin_unlock(&xenpf_lock);
160
161    return ret;
162}
163
164/*
165 * Local variables:
166 * mode: C
167 * c-set-style: "BSD"
168 * c-basic-offset: 4
169 * tab-width: 4
170 * indent-tabs-mode: nil
171 * End:
172 */
Note: See TracBrowser for help on using the repository browser.