diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 460e968e97..5380fbb081 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -386,14 +386,15 @@ void sync_vcpu_execstate(struct vcpu *v) /* Nothing to do -- no lazy switching */ } -#define next_arg(fmt, args) ({ \ +#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(); \ + default: goto bad_fmt; \ } \ __arg; \ }) @@ -408,9 +409,6 @@ unsigned long hypercall_create_continuation( unsigned int i; va_list args; - /* All hypercalls take at least one argument */ - BUG_ON( !p || *p == '\0' ); - current->hcall_preempted = true; va_start(args, format); @@ -418,7 +416,7 @@ unsigned long hypercall_create_continuation( if ( mcs->flags & MCSF_in_multicall ) { for ( i = 0; *p != '\0'; i++ ) - mcs->call.args[i] = next_arg(p, args); + mcs->call.args[i] = NEXT_ARG(p, args); /* Return value gets written back to mcs->call.result */ rc = mcs->call.result; @@ -434,7 +432,7 @@ unsigned long hypercall_create_continuation( for ( i = 0; *p != '\0'; i++ ) { - arg = next_arg(p, args); + arg = NEXT_ARG(p, args); switch ( i ) { @@ -457,7 +455,7 @@ unsigned long hypercall_create_continuation( for ( i = 0; *p != '\0'; i++ ) { - arg = next_arg(p, args); + arg = NEXT_ARG(p, args); switch ( i ) { @@ -478,8 +476,16 @@ unsigned long hypercall_create_continuation( va_end(args); return rc; + + bad_fmt: + gprintk(XENLOG_ERR, "Bad hypercall continuation format '%c'\n", *p); + ASSERT_UNREACHABLE(); + domain_crash(current->domain); + return 0; } +#undef NEXT_ARG + void startup_cpu_idle_loop(void) { struct vcpu *v = current; diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index d483dbaa6b..4643e5eb43 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -80,14 +80,15 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = #undef COMP #undef ARGS -#define next_arg(fmt, args) ({ \ +#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(); \ + default: goto bad_fmt; \ } \ __arg; \ }) @@ -109,7 +110,7 @@ unsigned long hypercall_create_continuation( if ( mcs->flags & MCSF_in_multicall ) { for ( i = 0; *p != '\0'; i++ ) - mcs->call.args[i] = next_arg(p, args); + mcs->call.args[i] = NEXT_ARG(p, args); } else { @@ -121,7 +122,7 @@ unsigned long hypercall_create_continuation( { for ( i = 0; *p != '\0'; i++ ) { - arg = next_arg(p, args); + arg = NEXT_ARG(p, args); switch ( i ) { case 0: regs->rdi = arg; break; @@ -137,7 +138,7 @@ unsigned long hypercall_create_continuation( { for ( i = 0; *p != '\0'; i++ ) { - arg = next_arg(p, args); + arg = NEXT_ARG(p, args); switch ( i ) { case 0: regs->rbx = arg; break; @@ -154,8 +155,16 @@ unsigned long hypercall_create_continuation( va_end(args); return op; + + bad_fmt: + gprintk(XENLOG_ERR, "Bad hypercall continuation format '%c'\n", *p); + ASSERT_UNREACHABLE(); + domain_crash(curr->domain); + return 0; } +#undef NEXT_ARG + int hypercall_xlat_continuation(unsigned int *id, unsigned int nr, unsigned int mask, ...) { diff --git a/xen/common/compat/domain.c b/xen/common/compat/domain.c index 39877b3ab2..2531fa7421 100644 --- a/xen/common/compat/domain.c +++ b/xen/common/compat/domain.c @@ -81,7 +81,7 @@ int compat_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) ar } if ( rc == -ERESTART ) - rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iuh", + rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih", cmd, vcpuid, arg); break; diff --git a/xen/common/domain.c b/xen/common/domain.c index 9c7360ed2a..3addb54ebb 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -1422,7 +1422,7 @@ long do_vcpu_op(int cmd, unsigned int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) rc = arch_initialise_vcpu(v, arg); if ( rc == -ERESTART ) - rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iuh", + rc = hypercall_create_continuation(__HYPERVISOR_vcpu_op, "iih", cmd, vcpuid, arg); break;