[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/hypercall: Move hypercall continuation logic
commit e004384bb371f5ab76a79b83da79981f4c400b83 Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Wed Feb 15 19:15:41 2017 +0000 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Thu Feb 16 14:15:25 2017 +0000 x86/hypercall: Move hypercall continuation logic The newly-repurposed arch/x86/hypercall.c is a more appropriate place for the hypercall continuation logic to live. This is purely code motion. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Acked-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/domain.c | 177 ----------------------------------------------- xen/arch/x86/hypercall.c | 177 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 177 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 694d2dc..130da29 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -2183,183 +2183,6 @@ void sync_vcpu_execstate(struct vcpu *v) flush_tlb_mask(v->vcpu_dirty_cpumask); } -#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; \ -}) - -void hypercall_cancel_continuation(void) -{ - current->hcall_preempted = false; -} - -unsigned long hypercall_create_continuation( - unsigned int op, const char *format, ...) -{ - struct vcpu *curr = current; - struct mc_state *mcs = &curr->mc_state; - const char *p = format; - unsigned long arg; - unsigned int i; - va_list args; - - curr->hcall_preempted = true; - - va_start(args, format); - - if ( mcs->flags & MCSF_in_multicall ) - { - for ( i = 0; *p != '\0'; i++ ) - mcs->call.args[i] = next_arg(p, args); - } - else - { - struct cpu_user_regs *regs = guest_cpu_user_regs(); - - regs->rax = op; - - if ( !curr->hcall_compat ) - { - for ( i = 0; *p != '\0'; i++ ) - { - arg = next_arg(p, args); - switch ( i ) - { - case 0: regs->rdi = arg; break; - case 1: regs->rsi = arg; break; - case 2: regs->rdx = arg; break; - case 3: regs->r10 = arg; break; - case 4: regs->r8 = arg; break; - case 5: regs->r9 = arg; break; - } - } - } - else - { - for ( i = 0; *p != '\0'; i++ ) - { - arg = next_arg(p, args); - switch ( i ) - { - case 0: regs->rbx = arg; break; - case 1: regs->rcx = arg; break; - case 2: regs->rdx = arg; break; - case 3: regs->rsi = arg; break; - case 4: regs->rdi = arg; break; - case 5: regs->rbp = arg; break; - } - } - } - } - - va_end(args); - - return op; -} - -int hypercall_xlat_continuation(unsigned int *id, unsigned int nr, - unsigned int mask, ...) -{ - int rc = 0; - struct mc_state *mcs = ¤t->mc_state; - struct cpu_user_regs *regs; - unsigned int i, cval = 0; - unsigned long nval = 0; - va_list args; - - ASSERT(nr <= ARRAY_SIZE(mcs->call.args)); - ASSERT(!(mask >> nr)); - ASSERT(!id || *id < nr); - ASSERT(!id || !(mask & (1U << *id))); - - va_start(args, mask); - - if ( mcs->flags & MCSF_in_multicall ) - { - if ( !current->hcall_preempted ) - { - va_end(args); - return 0; - } - - for ( i = 0; i < nr; ++i, mask >>= 1 ) - { - if ( mask & 1 ) - { - nval = va_arg(args, unsigned long); - cval = va_arg(args, unsigned int); - if ( cval == nval ) - mask &= ~1U; - else - BUG_ON(nval == (unsigned int)nval); - } - else if ( id && *id == i ) - { - *id = mcs->call.args[i]; - id = NULL; - } - if ( (mask & 1) && mcs->call.args[i] == nval ) - { - mcs->call.args[i] = cval; - ++rc; - } - else - BUG_ON(mcs->call.args[i] != (unsigned int)mcs->call.args[i]); - } - } - else - { - regs = guest_cpu_user_regs(); - for ( i = 0; i < nr; ++i, mask >>= 1 ) - { - unsigned long *reg; - - switch ( i ) - { - case 0: reg = ®s->rbx; break; - case 1: reg = ®s->rcx; break; - case 2: reg = ®s->rdx; break; - case 3: reg = ®s->rsi; break; - case 4: reg = ®s->rdi; break; - case 5: reg = ®s->rbp; break; - default: BUG(); reg = NULL; break; - } - if ( (mask & 1) ) - { - nval = va_arg(args, unsigned long); - cval = va_arg(args, unsigned int); - if ( cval == nval ) - mask &= ~1U; - else - BUG_ON(nval == (unsigned int)nval); - } - else if ( id && *id == i ) - { - *id = *reg; - id = NULL; - } - if ( (mask & 1) && *reg == nval ) - { - *reg = cval; - ++rc; - } - else - BUG_ON(*reg != (unsigned int)*reg); - } - } - - va_end(args); - - return rc; -} - static int relinquish_memory( struct domain *d, struct page_list_head *list, unsigned long type) { diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index f807332..e301818 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -74,6 +74,183 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = #undef COMP #undef 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(); \ + } \ + __arg; \ +}) + +void hypercall_cancel_continuation(void) +{ + current->hcall_preempted = false; +} + +unsigned long hypercall_create_continuation( + unsigned int op, const char *format, ...) +{ + struct vcpu *curr = current; + struct mc_state *mcs = &curr->mc_state; + const char *p = format; + unsigned long arg; + unsigned int i; + va_list args; + + curr->hcall_preempted = true; + + va_start(args, format); + + if ( mcs->flags & MCSF_in_multicall ) + { + for ( i = 0; *p != '\0'; i++ ) + mcs->call.args[i] = next_arg(p, args); + } + else + { + struct cpu_user_regs *regs = guest_cpu_user_regs(); + + regs->rax = op; + + if ( !curr->hcall_compat ) + { + for ( i = 0; *p != '\0'; i++ ) + { + arg = next_arg(p, args); + switch ( i ) + { + case 0: regs->rdi = arg; break; + case 1: regs->rsi = arg; break; + case 2: regs->rdx = arg; break; + case 3: regs->r10 = arg; break; + case 4: regs->r8 = arg; break; + case 5: regs->r9 = arg; break; + } + } + } + else + { + for ( i = 0; *p != '\0'; i++ ) + { + arg = next_arg(p, args); + switch ( i ) + { + case 0: regs->rbx = arg; break; + case 1: regs->rcx = arg; break; + case 2: regs->rdx = arg; break; + case 3: regs->rsi = arg; break; + case 4: regs->rdi = arg; break; + case 5: regs->rbp = arg; break; + } + } + } + } + + va_end(args); + + return op; +} + +int hypercall_xlat_continuation(unsigned int *id, unsigned int nr, + unsigned int mask, ...) +{ + int rc = 0; + struct mc_state *mcs = ¤t->mc_state; + struct cpu_user_regs *regs; + unsigned int i, cval = 0; + unsigned long nval = 0; + va_list args; + + ASSERT(nr <= ARRAY_SIZE(mcs->call.args)); + ASSERT(!(mask >> nr)); + ASSERT(!id || *id < nr); + ASSERT(!id || !(mask & (1U << *id))); + + va_start(args, mask); + + if ( mcs->flags & MCSF_in_multicall ) + { + if ( !current->hcall_preempted ) + { + va_end(args); + return 0; + } + + for ( i = 0; i < nr; ++i, mask >>= 1 ) + { + if ( mask & 1 ) + { + nval = va_arg(args, unsigned long); + cval = va_arg(args, unsigned int); + if ( cval == nval ) + mask &= ~1U; + else + BUG_ON(nval == (unsigned int)nval); + } + else if ( id && *id == i ) + { + *id = mcs->call.args[i]; + id = NULL; + } + if ( (mask & 1) && mcs->call.args[i] == nval ) + { + mcs->call.args[i] = cval; + ++rc; + } + else + BUG_ON(mcs->call.args[i] != (unsigned int)mcs->call.args[i]); + } + } + else + { + regs = guest_cpu_user_regs(); + for ( i = 0; i < nr; ++i, mask >>= 1 ) + { + unsigned long *reg; + + switch ( i ) + { + case 0: reg = ®s->rbx; break; + case 1: reg = ®s->rcx; break; + case 2: reg = ®s->rdx; break; + case 3: reg = ®s->rsi; break; + case 4: reg = ®s->rdi; break; + case 5: reg = ®s->rbp; break; + default: BUG(); reg = NULL; break; + } + if ( (mask & 1) ) + { + nval = va_arg(args, unsigned long); + cval = va_arg(args, unsigned int); + if ( cval == nval ) + mask &= ~1U; + else + BUG_ON(nval == (unsigned int)nval); + } + else if ( id && *id == i ) + { + *id = *reg; + id = NULL; + } + if ( (mask & 1) && *reg == nval ) + { + *reg = cval; + ++rc; + } + else + BUG_ON(*reg != (unsigned int)*reg); + } + } + + va_end(args); + + return rc; +} + /* * Local variables: * mode: C -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |