# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1267008454 0
# Node ID 6b7283d7cbc141befb31fbf71e0cc0f3bdb68a4b
# Parent ec5c9373e82192483b1b6459d1ff88b75ab182a2
[IA64] Support preemption in multicall
After 19946:91407452cdb6, preemption in multicall may happen while HVM
domains are running. It cause hypervisor's panic on ia64.
This patch implements it in the same way to x86.
Signed-off-by: KUWAMURA Shin'ya <kuwa@xxxxxxxxxxxxxx>
---
xen/arch/ia64/xen/hypercall.c | 73 ++++++++++++++++++++++--------------------
1 files changed, 39 insertions(+), 34 deletions(-)
diff -r ec5c9373e821 -r 6b7283d7cbc1 xen/arch/ia64/xen/hypercall.c
--- a/xen/arch/ia64/xen/hypercall.c Wed Feb 24 10:46:49 2010 +0000
+++ b/xen/arch/ia64/xen/hypercall.c Wed Feb 24 10:47:34 2010 +0000
@@ -404,6 +404,18 @@ ia64_hypercall(struct pt_regs *regs)
return IA64_NO_FAULT;
}
+#define next_arg(fmt, args) ({ \
+ unsigned long __arg; \
+ switch ( *(fmt)++ ) \
+ { \
+ case 'i': __arg = (unsigned long)va_arg(args, unsigned int); break; \
+ case 'l': __arg = (unsigned long)va_arg(args, unsigned long); break; \
+ case 'h': __arg = (unsigned long)va_arg(args, void *); break; \
+ default: __arg = 0; BUG(); \
+ } \
+ __arg; \
+})
+
unsigned long hypercall_create_continuation(
unsigned int op, const char *format, ...)
{
@@ -415,43 +427,36 @@ unsigned long hypercall_create_continuat
va_list args;
va_start(args, format);
- if (test_bit(_MCSF_in_multicall, &mcs->flags))
- panic("PREEMPT happen in multicall\n"); // Not support yet
-
- vcpu_set_gr(v, 15, op, 0);
-
- for (i = 0; *p != '\0'; i++) {
- switch ( *p++ )
- {
- case 'i':
- arg = (unsigned long)va_arg(args, unsigned int);
- break;
- case 'l':
- arg = (unsigned long)va_arg(args, unsigned long);
- break;
- case 'h':
- arg = (unsigned long)va_arg(args, void *);
- break;
- default:
- arg = 0;
- BUG();
+
+ if (test_bit(_MCSF_in_multicall, &mcs->flags)) {
+ dprintk(XENLOG_DEBUG, "PREEMPT happen in multicall\n");
+ __set_bit(_MCSF_call_preempted, &mcs->flags);
+ for (i = 0; *p != '\0'; i++)
+ mcs->call.args[i] = next_arg(p, args);
+ }
+ else {
+ vcpu_set_gr(v, 15, op, 0);
+
+ for (i = 0; *p != '\0'; i++) {
+ arg = next_arg(p, args);
+ vcpu_set_gr(v, 16 + i, arg, 0);
}
- vcpu_set_gr(v, 16 + i, arg, 0);
- }
- if (i >= 6)
- panic("Too many args for hypercall continuation\n");
-
- // Clean other argument to 0
- while (i < 6) {
- vcpu_set_gr(v, 16 + i, 0, 0);
- i++;
- }
-
- // re-execute break;
- vcpu_decrement_iip(v);
+ if (i >= 6)
+ panic("Too many args for hypercall continuation\n");
+
+ // Clean other argument to 0
+ while (i < 6) {
+ vcpu_set_gr(v, 16 + i, 0, 0);
+ i++;
+ }
+
+ // re-execute break;
+ vcpu_decrement_iip(v);
- v->arch.hypercall_continuation = 1;
+ v->arch.hypercall_continuation = 1;
+ }
+
va_end(args);
return op;
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|