On 08/01/15 15:22, Jan Beulich wrote:
> Unused arguments get clobbered before the call (not affecting caller
> visible state), while used arguments get clobbered afterwards unless
> a continuation is needed (affecting caller visible state).
>
> Signed-off-by: Jan Beulich <jbeul...@suse.com>

After a long time pouring over the Microsoft register calling
conventions documentation, and the Windows PV driver code, I am now
convinced that they are performing appropriate parameter saving.

Reviewed-by: Andrew Cooper <andrew.coop...@citrix.com>

>
> --- a/xen/arch/x86/hvm/hvm.c
> +++ b/xen/arch/x86/hvm/hvm.c
> @@ -4818,6 +4818,8 @@ static hvm_hypercall_t *const pvh_hyperc
>      [ __HYPERVISOR_arch_1 ] = (hvm_hypercall_t *)paging_domctl_continuation
>  };
>  
> +extern const uint8_t hypercall_args_table[], compat_hypercall_args_table[];
> +
>  int hvm_do_hypercall(struct cpu_user_regs *regs)
>  {
>      struct vcpu *curr = current;
> @@ -4856,36 +4858,95 @@ int hvm_do_hypercall(struct cpu_user_reg
>  
>      if ( mode == 8 )
>      {
> +        unsigned long rdi = regs->rdi;
> +        unsigned long rsi = regs->rsi;
> +        unsigned long rdx = regs->rdx;
> +        unsigned long r10 = regs->r10;
> +        unsigned long r8 = regs->r8;
> +        unsigned long r9 = regs->r9;
> +
>          HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u(%lx, %lx, %lx, %lx, %lx, %lx)",
> -                    eax, regs->rdi, regs->rsi, regs->rdx,
> -                    regs->r10, regs->r8, regs->r9);
> +                    eax, rdi, rsi, rdx, r10, r8, r9);
> +
> +#ifndef NDEBUG
> +        /* Deliberately corrupt parameter regs not used by this hypercall. */
> +        switch ( hypercall_args_table[eax] )
> +        {
> +        case 0: rdi = 0xdeadbeefdeadf00dUL;
> +        case 1: rsi = 0xdeadbeefdeadf00dUL;
> +        case 2: rdx = 0xdeadbeefdeadf00dUL;
> +        case 3: r10 = 0xdeadbeefdeadf00dUL;
> +        case 4: r8 = 0xdeadbeefdeadf00dUL;
> +        case 5: r9 = 0xdeadbeefdeadf00dUL;
> +        }
> +#endif
>  
>          curr->arch.hvm_vcpu.hcall_64bit = 1;
> -        if ( is_pvh_vcpu(curr) )
> -            regs->rax = pvh_hypercall64_table[eax](regs->rdi, regs->rsi,
> -                                                   regs->rdx, regs->r10,
> -                                                   regs->r8, regs->r9);
> -        else
> -            regs->rax = hvm_hypercall64_table[eax](regs->rdi, regs->rsi,
> -                                                   regs->rdx, regs->r10,
> -                                                   regs->r8, regs->r9);
> +        regs->rax = (is_pvh_vcpu(curr)
> +                     ? pvh_hypercall64_table
> +                     : hvm_hypercall64_table)[eax](rdi, rsi, rdx, r10, r8, 
> r9);
>          curr->arch.hvm_vcpu.hcall_64bit = 0;
> +
> +#ifndef NDEBUG
> +        if ( !curr->arch.hvm_vcpu.hcall_preempted )
> +        {
> +            /* Deliberately corrupt parameter regs used by this hypercall. */
> +            switch ( hypercall_args_table[eax] )
> +            {
> +            case 6: regs->r9  = 0xdeadbeefdeadf00dUL;
> +            case 5: regs->r8  = 0xdeadbeefdeadf00dUL;
> +            case 4: regs->r10 = 0xdeadbeefdeadf00dUL;
> +            case 3: regs->edx = 0xdeadbeefdeadf00dUL;
> +            case 2: regs->esi = 0xdeadbeefdeadf00dUL;
> +            case 1: regs->edi = 0xdeadbeefdeadf00dUL;
> +            }
> +        }
> +#endif
>      }
>      else if ( unlikely(is_pvh_vcpu(curr)) )
>          regs->_eax = -ENOSYS; /* PVH 32bitfixme. */
>      else
>      {
> +        unsigned int ebx = regs->_ebx;
> +        unsigned int ecx = regs->_ecx;
> +        unsigned int edx = regs->_edx;
> +        unsigned int esi = regs->_esi;
> +        unsigned int edi = regs->_edi;
> +        unsigned int ebp = regs->_ebp;
> +
>          HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u(%x, %x, %x, %x, %x, %x)", eax,
> -                    (uint32_t)regs->ebx, (uint32_t)regs->ecx,
> -                    (uint32_t)regs->edx, (uint32_t)regs->esi,
> -                    (uint32_t)regs->edi, (uint32_t)regs->ebp);
> -
> -        regs->eax = hvm_hypercall32_table[eax]((uint32_t)regs->ebx,
> -                                               (uint32_t)regs->ecx,
> -                                               (uint32_t)regs->edx,
> -                                               (uint32_t)regs->esi,
> -                                               (uint32_t)regs->edi,
> -                                               (uint32_t)regs->ebp);
> +                    ebx, ecx, edx, esi, edi, ebp);
> +
> +#ifndef NDEBUG
> +        /* Deliberately corrupt parameter regs not used by this hypercall. */
> +        switch ( compat_hypercall_args_table[eax] )
> +        {
> +        case 0: ebx = 0xdeadf00d;
> +        case 1: ecx = 0xdeadf00d;
> +        case 2: edx = 0xdeadf00d;
> +        case 3: esi = 0xdeadf00d;
> +        case 4: edi = 0xdeadf00d;
> +        case 5: ebp = 0xdeadf00d;
> +        }
> +#endif
> +
> +        regs->_eax = hvm_hypercall32_table[eax](ebx, ecx, edx, esi, edi, 
> ebp);
> +
> +#ifndef NDEBUG
> +        if ( !curr->arch.hvm_vcpu.hcall_preempted )
> +        {
> +            /* Deliberately corrupt parameter regs used by this hypercall. */
> +            switch ( compat_hypercall_args_table[eax] )
> +            {
> +            case 6: regs->ebp = 0xdeadf00d;
> +            case 5: regs->edi = 0xdeadf00d;
> +            case 4: regs->esi = 0xdeadf00d;
> +            case 3: regs->edx = 0xdeadf00d;
> +            case 2: regs->ecx = 0xdeadf00d;
> +            case 1: regs->ebx = 0xdeadf00d;
> +            }
> +        }
> +#endif
>      }
>  
>      HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u -> %lx",
>
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

Reply via email to