debuggers.hg

changeset 21017:6b7283d7cbc1

[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@jp.fujitsu.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Feb 24 10:47:34 2010 +0000 (2010-02-24)
parents ec5c9373e821
children 1bc860c790d9
files xen/arch/ia64/xen/hypercall.c
line diff
     1.1 --- a/xen/arch/ia64/xen/hypercall.c	Wed Feb 24 10:46:49 2010 +0000
     1.2 +++ b/xen/arch/ia64/xen/hypercall.c	Wed Feb 24 10:47:34 2010 +0000
     1.3 @@ -404,6 +404,18 @@ ia64_hypercall(struct pt_regs *regs)
     1.4  	return IA64_NO_FAULT;
     1.5  }
     1.6  
     1.7 +#define next_arg(fmt, args) ({                                              \
     1.8 +    unsigned long __arg;                                                    \
     1.9 +    switch ( *(fmt)++ )                                                     \
    1.10 +    {                                                                       \
    1.11 +    case 'i': __arg = (unsigned long)va_arg(args, unsigned int);  break;    \
    1.12 +    case 'l': __arg = (unsigned long)va_arg(args, unsigned long); break;    \
    1.13 +    case 'h': __arg = (unsigned long)va_arg(args, void *);        break;    \
    1.14 +    default:  __arg = 0; BUG();                                             \
    1.15 +    }                                                                       \
    1.16 +    __arg;                                                                  \
    1.17 +})
    1.18 +
    1.19  unsigned long hypercall_create_continuation(
    1.20  	unsigned int op, const char *format, ...)
    1.21  {
    1.22 @@ -415,43 +427,36 @@ unsigned long hypercall_create_continuat
    1.23      va_list args;
    1.24  
    1.25      va_start(args, format);
    1.26 -    if (test_bit(_MCSF_in_multicall, &mcs->flags))
    1.27 -        panic("PREEMPT happen in multicall\n");	// Not support yet
    1.28  
    1.29 -    vcpu_set_gr(v, 15, op, 0);
    1.30 +    if (test_bit(_MCSF_in_multicall, &mcs->flags)) {
    1.31 +        dprintk(XENLOG_DEBUG, "PREEMPT happen in multicall\n");
    1.32 +        __set_bit(_MCSF_call_preempted, &mcs->flags);
    1.33 +        for (i = 0; *p != '\0'; i++)
    1.34 +            mcs->call.args[i] = next_arg(p, args);
    1.35 +    }
    1.36 +    else {
    1.37 +        vcpu_set_gr(v, 15, op, 0);
    1.38  
    1.39 -    for (i = 0; *p != '\0'; i++) {
    1.40 -        switch ( *p++ )
    1.41 -        {
    1.42 -        case 'i':
    1.43 -            arg = (unsigned long)va_arg(args, unsigned int);
    1.44 -            break;
    1.45 -        case 'l':
    1.46 -            arg = (unsigned long)va_arg(args, unsigned long);
    1.47 -            break;
    1.48 -        case 'h':
    1.49 -            arg = (unsigned long)va_arg(args, void *);
    1.50 -            break;
    1.51 -        default:
    1.52 -            arg = 0;
    1.53 -            BUG();
    1.54 +        for (i = 0; *p != '\0'; i++) {
    1.55 +            arg = next_arg(p, args);
    1.56 +            vcpu_set_gr(v, 16 + i, arg, 0);
    1.57          }
    1.58 -        vcpu_set_gr(v, 16 + i, arg, 0);
    1.59 -    }
    1.60      
    1.61 -    if (i >= 6)
    1.62 -        panic("Too many args for hypercall continuation\n");
    1.63 +        if (i >= 6)
    1.64 +            panic("Too many args for hypercall continuation\n");
    1.65  
    1.66 -    // Clean other argument to 0
    1.67 -    while (i < 6) {
    1.68 -        vcpu_set_gr(v, 16 + i, 0, 0);
    1.69 -        i++;
    1.70 +        // Clean other argument to 0
    1.71 +        while (i < 6) {
    1.72 +            vcpu_set_gr(v, 16 + i, 0, 0);
    1.73 +            i++;
    1.74 +        }
    1.75 +
    1.76 +        // re-execute break;
    1.77 +        vcpu_decrement_iip(v);
    1.78 +    
    1.79 +        v->arch.hypercall_continuation = 1;
    1.80      }
    1.81  
    1.82 -    // re-execute break;
    1.83 -    vcpu_decrement_iip(v);
    1.84 -    
    1.85 -    v->arch.hypercall_continuation = 1;
    1.86      va_end(args);
    1.87      return op;
    1.88  }