aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2008-10-16 22:17:52 -0400
committerTony Luck <tony.luck@intel.com>2008-10-17 12:58:58 -0400
commited50bd6096dab96e4c501d600776b75687dd2cf0 (patch)
treeb1fd38c695c2c5aa1f11c0d7cdd98e8b9de56659
parent67fe8d27a8b0845d6a5237af340fe5039335bf99 (diff)
ia64/xen: define helper functions for xen hypercalls.
introduce helper functions for xen hypercalls which traps to hypervisor. Signed-off-by: Yaozu (Eddie) Dong <eddie.dong@intel.com> Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/include/asm/xen/hypercall.h265
-rw-r--r--arch/ia64/include/asm/xen/privop.h129
-rw-r--r--arch/ia64/xen/Makefile5
-rw-r--r--arch/ia64/xen/hypercall.S91
4 files changed, 490 insertions, 0 deletions
diff --git a/arch/ia64/include/asm/xen/hypercall.h b/arch/ia64/include/asm/xen/hypercall.h
new file mode 100644
index 000000000000..96fc62366aa4
--- /dev/null
+++ b/arch/ia64/include/asm/xen/hypercall.h
@@ -0,0 +1,265 @@
1/******************************************************************************
2 * hypercall.h
3 *
4 * Linux-specific hypervisor handling.
5 *
6 * Copyright (c) 2002-2004, K A Fraser
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation; or, when distributed
11 * separately from the Linux kernel or incorporated into other
12 * software packages, subject to the following license:
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this source file (the "Software"), to deal in the Software without
16 * restriction, including without limitation the rights to use, copy, modify,
17 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
18 * and to permit persons to whom the Software is furnished to do so, subject to
19 * the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
32
33#ifndef _ASM_IA64_XEN_HYPERCALL_H
34#define _ASM_IA64_XEN_HYPERCALL_H
35
36#include <xen/interface/xen.h>
37#include <xen/interface/physdev.h>
38#include <xen/interface/sched.h>
39#include <asm/xen/xcom_hcall.h>
40struct xencomm_handle;
41extern unsigned long __hypercall(unsigned long a1, unsigned long a2,
42 unsigned long a3, unsigned long a4,
43 unsigned long a5, unsigned long cmd);
44
45/*
46 * Assembler stubs for hyper-calls.
47 */
48
49#define _hypercall0(type, name) \
50({ \
51 long __res; \
52 __res = __hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name);\
53 (type)__res; \
54})
55
56#define _hypercall1(type, name, a1) \
57({ \
58 long __res; \
59 __res = __hypercall((unsigned long)a1, \
60 0, 0, 0, 0, __HYPERVISOR_##name); \
61 (type)__res; \
62})
63
64#define _hypercall2(type, name, a1, a2) \
65({ \
66 long __res; \
67 __res = __hypercall((unsigned long)a1, \
68 (unsigned long)a2, \
69 0, 0, 0, __HYPERVISOR_##name); \
70 (type)__res; \
71})
72
73#define _hypercall3(type, name, a1, a2, a3) \
74({ \
75 long __res; \
76 __res = __hypercall((unsigned long)a1, \
77 (unsigned long)a2, \
78 (unsigned long)a3, \
79 0, 0, __HYPERVISOR_##name); \
80 (type)__res; \
81})
82
83#define _hypercall4(type, name, a1, a2, a3, a4) \
84({ \
85 long __res; \
86 __res = __hypercall((unsigned long)a1, \
87 (unsigned long)a2, \
88 (unsigned long)a3, \
89 (unsigned long)a4, \
90 0, __HYPERVISOR_##name); \
91 (type)__res; \
92})
93
94#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
95({ \
96 long __res; \
97 __res = __hypercall((unsigned long)a1, \
98 (unsigned long)a2, \
99 (unsigned long)a3, \
100 (unsigned long)a4, \
101 (unsigned long)a5, \
102 __HYPERVISOR_##name); \
103 (type)__res; \
104})
105
106
107static inline int
108xencomm_arch_hypercall_sched_op(int cmd, struct xencomm_handle *arg)
109{
110 return _hypercall2(int, sched_op_new, cmd, arg);
111}
112
113static inline long
114HYPERVISOR_set_timer_op(u64 timeout)
115{
116 unsigned long timeout_hi = (unsigned long)(timeout >> 32);
117 unsigned long timeout_lo = (unsigned long)timeout;
118 return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
119}
120
121static inline int
122xencomm_arch_hypercall_multicall(struct xencomm_handle *call_list,
123 int nr_calls)
124{
125 return _hypercall2(int, multicall, call_list, nr_calls);
126}
127
128static inline int
129xencomm_arch_hypercall_memory_op(unsigned int cmd, struct xencomm_handle *arg)
130{
131 return _hypercall2(int, memory_op, cmd, arg);
132}
133
134static inline int
135xencomm_arch_hypercall_event_channel_op(int cmd, struct xencomm_handle *arg)
136{
137 return _hypercall2(int, event_channel_op, cmd, arg);
138}
139
140static inline int
141xencomm_arch_hypercall_xen_version(int cmd, struct xencomm_handle *arg)
142{
143 return _hypercall2(int, xen_version, cmd, arg);
144}
145
146static inline int
147xencomm_arch_hypercall_console_io(int cmd, int count,
148 struct xencomm_handle *str)
149{
150 return _hypercall3(int, console_io, cmd, count, str);
151}
152
153static inline int
154xencomm_arch_hypercall_physdev_op(int cmd, struct xencomm_handle *arg)
155{
156 return _hypercall2(int, physdev_op, cmd, arg);
157}
158
159static inline int
160xencomm_arch_hypercall_grant_table_op(unsigned int cmd,
161 struct xencomm_handle *uop,
162 unsigned int count)
163{
164 return _hypercall3(int, grant_table_op, cmd, uop, count);
165}
166
167int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
168
169extern int xencomm_arch_hypercall_suspend(struct xencomm_handle *arg);
170
171static inline int
172xencomm_arch_hypercall_callback_op(int cmd, struct xencomm_handle *arg)
173{
174 return _hypercall2(int, callback_op, cmd, arg);
175}
176
177static inline long
178xencomm_arch_hypercall_vcpu_op(int cmd, int cpu, void *arg)
179{
180 return _hypercall3(long, vcpu_op, cmd, cpu, arg);
181}
182
183static inline int
184HYPERVISOR_physdev_op(int cmd, void *arg)
185{
186 switch (cmd) {
187 case PHYSDEVOP_eoi:
188 return _hypercall1(int, ia64_fast_eoi,
189 ((struct physdev_eoi *)arg)->irq);
190 default:
191 return xencomm_hypercall_physdev_op(cmd, arg);
192 }
193}
194
195static inline long
196xencomm_arch_hypercall_opt_feature(struct xencomm_handle *arg)
197{
198 return _hypercall1(long, opt_feature, arg);
199}
200
201/* for balloon driver */
202#define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
203
204/* Use xencomm to do hypercalls. */
205#define HYPERVISOR_sched_op xencomm_hypercall_sched_op
206#define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
207#define HYPERVISOR_callback_op xencomm_hypercall_callback_op
208#define HYPERVISOR_multicall xencomm_hypercall_multicall
209#define HYPERVISOR_xen_version xencomm_hypercall_xen_version
210#define HYPERVISOR_console_io xencomm_hypercall_console_io
211#define HYPERVISOR_memory_op xencomm_hypercall_memory_op
212#define HYPERVISOR_suspend xencomm_hypercall_suspend
213#define HYPERVISOR_vcpu_op xencomm_hypercall_vcpu_op
214#define HYPERVISOR_opt_feature xencomm_hypercall_opt_feature
215
216/* to compile gnttab_copy_grant_page() in drivers/xen/core/gnttab.c */
217#define HYPERVISOR_mmu_update(req, count, success_count, domid) ({ BUG(); 0; })
218
219static inline int
220HYPERVISOR_shutdown(
221 unsigned int reason)
222{
223 struct sched_shutdown sched_shutdown = {
224 .reason = reason
225 };
226
227 int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
228
229 return rc;
230}
231
232/* for netfront.c, netback.c */
233#define MULTI_UVMFLAGS_INDEX 0 /* XXX any value */
234
235static inline void
236MULTI_update_va_mapping(
237 struct multicall_entry *mcl, unsigned long va,
238 pte_t new_val, unsigned long flags)
239{
240 mcl->op = __HYPERVISOR_update_va_mapping;
241 mcl->result = 0;
242}
243
244static inline void
245MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd,
246 void *uop, unsigned int count)
247{
248 mcl->op = __HYPERVISOR_grant_table_op;
249 mcl->args[0] = cmd;
250 mcl->args[1] = (unsigned long)uop;
251 mcl->args[2] = count;
252}
253
254static inline void
255MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,
256 int count, int *success_count, domid_t domid)
257{
258 mcl->op = __HYPERVISOR_mmu_update;
259 mcl->args[0] = (unsigned long)req;
260 mcl->args[1] = count;
261 mcl->args[2] = (unsigned long)success_count;
262 mcl->args[3] = domid;
263}
264
265#endif /* _ASM_IA64_XEN_HYPERCALL_H */
diff --git a/arch/ia64/include/asm/xen/privop.h b/arch/ia64/include/asm/xen/privop.h
new file mode 100644
index 000000000000..71ec7546e100
--- /dev/null
+++ b/arch/ia64/include/asm/xen/privop.h
@@ -0,0 +1,129 @@
1#ifndef _ASM_IA64_XEN_PRIVOP_H
2#define _ASM_IA64_XEN_PRIVOP_H
3
4/*
5 * Copyright (C) 2005 Hewlett-Packard Co
6 * Dan Magenheimer <dan.magenheimer@hp.com>
7 *
8 * Paravirtualizations of privileged operations for Xen/ia64
9 *
10 *
11 * inline privop and paravirt_alt support
12 * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
13 * VA Linux Systems Japan K.K.
14 *
15 */
16
17#ifndef __ASSEMBLY__
18#include <linux/types.h> /* arch-ia64.h requires uint64_t */
19#endif
20#include <asm/xen/interface.h>
21
22/* At 1 MB, before per-cpu space but still addressable using addl instead
23 of movl. */
24#define XSI_BASE 0xfffffffffff00000
25
26/* Address of mapped regs. */
27#define XMAPPEDREGS_BASE (XSI_BASE + XSI_SIZE)
28
29#ifdef __ASSEMBLY__
30#define XEN_HYPER_RFI break HYPERPRIVOP_RFI
31#define XEN_HYPER_RSM_PSR_DT break HYPERPRIVOP_RSM_DT
32#define XEN_HYPER_SSM_PSR_DT break HYPERPRIVOP_SSM_DT
33#define XEN_HYPER_COVER break HYPERPRIVOP_COVER
34#define XEN_HYPER_ITC_D break HYPERPRIVOP_ITC_D
35#define XEN_HYPER_ITC_I break HYPERPRIVOP_ITC_I
36#define XEN_HYPER_SSM_I break HYPERPRIVOP_SSM_I
37#define XEN_HYPER_GET_IVR break HYPERPRIVOP_GET_IVR
38#define XEN_HYPER_THASH break HYPERPRIVOP_THASH
39#define XEN_HYPER_ITR_D break HYPERPRIVOP_ITR_D
40#define XEN_HYPER_SET_KR break HYPERPRIVOP_SET_KR
41#define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR
42#define XEN_HYPER_SET_RR0_TO_RR4 break HYPERPRIVOP_SET_RR0_TO_RR4
43
44#define XSI_IFS (XSI_BASE + XSI_IFS_OFS)
45#define XSI_PRECOVER_IFS (XSI_BASE + XSI_PRECOVER_IFS_OFS)
46#define XSI_IFA (XSI_BASE + XSI_IFA_OFS)
47#define XSI_ISR (XSI_BASE + XSI_ISR_OFS)
48#define XSI_IIM (XSI_BASE + XSI_IIM_OFS)
49#define XSI_ITIR (XSI_BASE + XSI_ITIR_OFS)
50#define XSI_PSR_I_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS)
51#define XSI_PSR_IC (XSI_BASE + XSI_PSR_IC_OFS)
52#define XSI_IPSR (XSI_BASE + XSI_IPSR_OFS)
53#define XSI_IIP (XSI_BASE + XSI_IIP_OFS)
54#define XSI_B1NAT (XSI_BASE + XSI_B1NATS_OFS)
55#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS)
56#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS)
57#define XSI_IHA (XSI_BASE + XSI_IHA_OFS)
58#endif
59
60#ifndef __ASSEMBLY__
61
62/************************************************/
63/* Instructions paravirtualized for correctness */
64/************************************************/
65
66/* "fc" and "thash" are privilege-sensitive instructions, meaning they
67 * may have different semantics depending on whether they are executed
68 * at PL0 vs PL!=0. When paravirtualized, these instructions mustn't
69 * be allowed to execute directly, lest incorrect semantics result. */
70extern void xen_fc(unsigned long addr);
71extern unsigned long xen_thash(unsigned long addr);
72
73/* Note that "ttag" and "cover" are also privilege-sensitive; "ttag"
74 * is not currently used (though it may be in a long-format VHPT system!)
75 * and the semantics of cover only change if psr.ic is off which is very
76 * rare (and currently non-existent outside of assembly code */
77
78/* There are also privilege-sensitive registers. These registers are
79 * readable at any privilege level but only writable at PL0. */
80extern unsigned long xen_get_cpuid(int index);
81extern unsigned long xen_get_pmd(int index);
82
83extern unsigned long xen_get_eflag(void); /* see xen_ia64_getreg */
84extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */
85
86/************************************************/
87/* Instructions paravirtualized for performance */
88/************************************************/
89
90/* Xen uses memory-mapped virtual privileged registers for access to many
91 * performance-sensitive privileged registers. Some, like the processor
92 * status register (psr), are broken up into multiple memory locations.
93 * Others, like "pend", are abstractions based on privileged registers.
94 * "Pend" is guaranteed to be set if reading cr.ivr would return a
95 * (non-spurious) interrupt. */
96#define XEN_MAPPEDREGS ((struct mapped_regs *)XMAPPEDREGS_BASE)
97
98#define XSI_PSR_I \
99 (*XEN_MAPPEDREGS->interrupt_mask_addr)
100#define xen_get_virtual_psr_i() \
101 (!XSI_PSR_I)
102#define xen_set_virtual_psr_i(_val) \
103 ({ XSI_PSR_I = (uint8_t)(_val) ? 0 : 1; })
104#define xen_set_virtual_psr_ic(_val) \
105 ({ XEN_MAPPEDREGS->interrupt_collection_enabled = _val ? 1 : 0; })
106#define xen_get_virtual_pend() \
107 (*(((uint8_t *)XEN_MAPPEDREGS->interrupt_mask_addr) - 1))
108
109/* Although all privileged operations can be left to trap and will
110 * be properly handled by Xen, some are frequent enough that we use
111 * hyperprivops for performance. */
112extern unsigned long xen_get_psr(void);
113extern unsigned long xen_get_ivr(void);
114extern unsigned long xen_get_tpr(void);
115extern void xen_hyper_ssm_i(void);
116extern void xen_set_itm(unsigned long);
117extern void xen_set_tpr(unsigned long);
118extern void xen_eoi(unsigned long);
119extern unsigned long xen_get_rr(unsigned long index);
120extern void xen_set_rr(unsigned long index, unsigned long val);
121extern void xen_set_rr0_to_rr4(unsigned long val0, unsigned long val1,
122 unsigned long val2, unsigned long val3,
123 unsigned long val4);
124extern void xen_set_kr(unsigned long index, unsigned long val);
125extern void xen_ptcga(unsigned long addr, unsigned long size);
126
127#endif /* !__ASSEMBLY__ */
128
129#endif /* _ASM_IA64_XEN_PRIVOP_H */
diff --git a/arch/ia64/xen/Makefile b/arch/ia64/xen/Makefile
new file mode 100644
index 000000000000..c200704e2333
--- /dev/null
+++ b/arch/ia64/xen/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for Xen components
3#
4
5obj-y := hypercall.o
diff --git a/arch/ia64/xen/hypercall.S b/arch/ia64/xen/hypercall.S
new file mode 100644
index 000000000000..d4ff0b9e79f1
--- /dev/null
+++ b/arch/ia64/xen/hypercall.S
@@ -0,0 +1,91 @@
1/*
2 * Support routines for Xen hypercalls
3 *
4 * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
5 * Copyright (C) 2008 Yaozu (Eddie) Dong <eddie.dong@intel.com>
6 */
7
8#include <asm/asmmacro.h>
9#include <asm/intrinsics.h>
10#include <asm/xen/privop.h>
11
12/*
13 * Hypercalls without parameter.
14 */
15#define __HCALL0(name,hcall) \
16 GLOBAL_ENTRY(name); \
17 break hcall; \
18 br.ret.sptk.many rp; \
19 END(name)
20
21/*
22 * Hypercalls with 1 parameter.
23 */
24#define __HCALL1(name,hcall) \
25 GLOBAL_ENTRY(name); \
26 mov r8=r32; \
27 break hcall; \
28 br.ret.sptk.many rp; \
29 END(name)
30
31/*
32 * Hypercalls with 2 parameters.
33 */
34#define __HCALL2(name,hcall) \
35 GLOBAL_ENTRY(name); \
36 mov r8=r32; \
37 mov r9=r33; \
38 break hcall; \
39 br.ret.sptk.many rp; \
40 END(name)
41
42__HCALL0(xen_get_psr, HYPERPRIVOP_GET_PSR)
43__HCALL0(xen_get_ivr, HYPERPRIVOP_GET_IVR)
44__HCALL0(xen_get_tpr, HYPERPRIVOP_GET_TPR)
45__HCALL0(xen_hyper_ssm_i, HYPERPRIVOP_SSM_I)
46
47__HCALL1(xen_set_tpr, HYPERPRIVOP_SET_TPR)
48__HCALL1(xen_eoi, HYPERPRIVOP_EOI)
49__HCALL1(xen_thash, HYPERPRIVOP_THASH)
50__HCALL1(xen_set_itm, HYPERPRIVOP_SET_ITM)
51__HCALL1(xen_get_rr, HYPERPRIVOP_GET_RR)
52__HCALL1(xen_fc, HYPERPRIVOP_FC)
53__HCALL1(xen_get_cpuid, HYPERPRIVOP_GET_CPUID)
54__HCALL1(xen_get_pmd, HYPERPRIVOP_GET_PMD)
55
56__HCALL2(xen_ptcga, HYPERPRIVOP_PTC_GA)
57__HCALL2(xen_set_rr, HYPERPRIVOP_SET_RR)
58__HCALL2(xen_set_kr, HYPERPRIVOP_SET_KR)
59
60#ifdef CONFIG_IA32_SUPPORT
61__HCALL1(xen_get_eflag, HYPERPRIVOP_GET_EFLAG)
62__HCALL1(xen_set_eflag, HYPERPRIVOP_SET_EFLAG) // refer SDM vol1 3.1.8
63#endif /* CONFIG_IA32_SUPPORT */
64
65GLOBAL_ENTRY(xen_set_rr0_to_rr4)
66 mov r8=r32
67 mov r9=r33
68 mov r10=r34
69 mov r11=r35
70 mov r14=r36
71 XEN_HYPER_SET_RR0_TO_RR4
72 br.ret.sptk.many rp
73 ;;
74END(xen_set_rr0_to_rr4)
75
76GLOBAL_ENTRY(xen_send_ipi)
77 mov r14=r32
78 mov r15=r33
79 mov r2=0x400
80 break 0x1000
81 ;;
82 br.ret.sptk.many rp
83 ;;
84END(xen_send_ipi)
85
86GLOBAL_ENTRY(__hypercall)
87 mov r2=r37
88 break 0x1000
89 br.ret.sptk.many b0
90 ;;
91END(__hypercall)