aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2008-10-16 22:18:00 -0400
committerTony Luck <tony.luck@intel.com>2008-10-17 13:03:24 -0400
commit4b83ce4367943aa3eb960df56759f45d70722a4c (patch)
tree5016104e05b1293c3f06eb7f039dd8cf978575bb /arch/ia64
parentb5a26e4db818d4647a019d5c462f6778b8213112 (diff)
ia64/pv_ops/xen: define xen pv_cpu_ops.
define xen pv_cpu_ops which implementes xen paravirtualized privileged instructions. 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>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/xen/xen_pv_ops.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/arch/ia64/xen/xen_pv_ops.c b/arch/ia64/xen/xen_pv_ops.c
index fc9d599b62ae..c236f04ffad5 100644
--- a/arch/ia64/xen/xen_pv_ops.c
+++ b/arch/ia64/xen/xen_pv_ops.c
@@ -163,6 +163,119 @@ static const struct pv_init_ops xen_init_ops __initdata = {
163}; 163};
164 164
165/*************************************************************************** 165/***************************************************************************
166 * pv_cpu_ops
167 * intrinsics hooks.
168 */
169
170static void xen_setreg(int regnum, unsigned long val)
171{
172 switch (regnum) {
173 case _IA64_REG_AR_KR0 ... _IA64_REG_AR_KR7:
174 xen_set_kr(regnum - _IA64_REG_AR_KR0, val);
175 break;
176#ifdef CONFIG_IA32_SUPPORT
177 case _IA64_REG_AR_EFLAG:
178 xen_set_eflag(val);
179 break;
180#endif
181 case _IA64_REG_CR_TPR:
182 xen_set_tpr(val);
183 break;
184 case _IA64_REG_CR_ITM:
185 xen_set_itm(val);
186 break;
187 case _IA64_REG_CR_EOI:
188 xen_eoi(val);
189 break;
190 default:
191 ia64_native_setreg_func(regnum, val);
192 break;
193 }
194}
195
196static unsigned long xen_getreg(int regnum)
197{
198 unsigned long res;
199
200 switch (regnum) {
201 case _IA64_REG_PSR:
202 res = xen_get_psr();
203 break;
204#ifdef CONFIG_IA32_SUPPORT
205 case _IA64_REG_AR_EFLAG:
206 res = xen_get_eflag();
207 break;
208#endif
209 case _IA64_REG_CR_IVR:
210 res = xen_get_ivr();
211 break;
212 case _IA64_REG_CR_TPR:
213 res = xen_get_tpr();
214 break;
215 default:
216 res = ia64_native_getreg_func(regnum);
217 break;
218 }
219 return res;
220}
221
222/* turning on interrupts is a bit more complicated.. write to the
223 * memory-mapped virtual psr.i bit first (to avoid race condition),
224 * then if any interrupts were pending, we have to execute a hyperprivop
225 * to ensure the pending interrupt gets delivered; else we're done! */
226static void
227xen_ssm_i(void)
228{
229 int old = xen_get_virtual_psr_i();
230 xen_set_virtual_psr_i(1);
231 barrier();
232 if (!old && xen_get_virtual_pend())
233 xen_hyper_ssm_i();
234}
235
236/* turning off interrupts can be paravirtualized simply by writing
237 * to a memory-mapped virtual psr.i bit (implemented as a 16-bit bool) */
238static void
239xen_rsm_i(void)
240{
241 xen_set_virtual_psr_i(0);
242 barrier();
243}
244
245static unsigned long
246xen_get_psr_i(void)
247{
248 return xen_get_virtual_psr_i() ? IA64_PSR_I : 0;
249}
250
251static void
252xen_intrin_local_irq_restore(unsigned long mask)
253{
254 if (mask & IA64_PSR_I)
255 xen_ssm_i();
256 else
257 xen_rsm_i();
258}
259
260static const struct pv_cpu_ops xen_cpu_ops __initdata = {
261 .fc = xen_fc,
262 .thash = xen_thash,
263 .get_cpuid = xen_get_cpuid,
264 .get_pmd = xen_get_pmd,
265 .getreg = xen_getreg,
266 .setreg = xen_setreg,
267 .ptcga = xen_ptcga,
268 .get_rr = xen_get_rr,
269 .set_rr = xen_set_rr,
270 .set_rr0_to_rr4 = xen_set_rr0_to_rr4,
271 .ssm_i = xen_ssm_i,
272 .rsm_i = xen_rsm_i,
273 .get_psr_i = xen_get_psr_i,
274 .intrin_local_irq_restore
275 = xen_intrin_local_irq_restore,
276};
277
278/***************************************************************************
166 * pv_ops initialization 279 * pv_ops initialization
167 */ 280 */
168 281
@@ -172,4 +285,5 @@ xen_setup_pv_ops(void)
172 xen_info_init(); 285 xen_info_init();
173 pv_info = xen_info; 286 pv_info = xen_info;
174 pv_init_ops = xen_init_ops; 287 pv_init_ops = xen_init_ops;
288 pv_cpu_ops = xen_cpu_ops;
175} 289}