[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH 1/3] x86/hvm: give HVMOP_set_param and HVMOP_get_param their own functions



> -----Original Message-----
> From: Andrew Cooper [mailto:andrew.cooper3@xxxxxxxxxx]
> Sent: 25 April 2015 01:12
> To: Paul Durrant; xen-devel@xxxxxxxxxxxxxxxxxxxx
> Cc: Keir (Xen.org); Jan Beulich
> Subject: Re: [PATCH 1/3] x86/hvm: give HVMOP_set_param and
> HVMOP_get_param their own functions
> 
> On 24/04/15 17:21, Paul Durrant wrote:
> > The level of switch nesting in those ops is getting unreadable. Giving
> > them their own functions does introduce some code duplication in the
> > the pre-op checks but the overall result is easier to follow.
> >
> > This patch is code movement. There is no functional change.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
> > Cc: Keir Fraser <keir@xxxxxxx>
> > Cc: Jan Beulich <jbeulich@xxxxxxxx>
> > Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
> 
> Please latch current at the top of the function, and fix Xen style
> during motion. (newlines between break and case lines, drop superfluous
> braces, brace layout around get bufiorq_evtchn).
>

Sure, will do.
 
> With that fixed, Reviewed-by: Andrew Cooper
> <andrew.cooper3@xxxxxxxxxx>
> 

Cool.

  Paul

> > ---
> >  xen/arch/x86/hvm/hvm.c |  562 ++++++++++++++++++++++++++----------
> ------------
> >  1 file changed, 300 insertions(+), 262 deletions(-)
> >
> > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
> > index 3c62b80..87c47b1 100644
> > --- a/xen/arch/x86/hvm/hvm.c
> > +++ b/xen/arch/x86/hvm/hvm.c
> > @@ -5640,6 +5640,300 @@ static int hvmop_set_evtchn_upcall_vector(
> >      return 0;
> >  }
> >
> > +static int hvmop_set_param(
> > +    XEN_GUEST_HANDLE_PARAM(xen_hvm_param_t) arg)
> > +{
> > +    struct xen_hvm_param a;
> > +    struct domain *d;
> > +    struct vcpu *v;
> > +    int rc = 0;
> > +
> > +    if ( copy_from_guest(&a, arg, 1) )
> > +        return -EFAULT;
> > +
> > +    if ( a.index >= HVM_NR_PARAMS )
> > +        return -EINVAL;
> > +
> > +    d = rcu_lock_domain_by_any_id(a.domid);
> > +    if ( d == NULL )
> > +        return -ESRCH;
> > +
> > +    rc = -EINVAL;
> > +    if ( !has_hvm_container_domain(d) )
> > +        goto out;
> > +
> > +    if ( is_pvh_domain(d)
> > +         && (a.index != HVM_PARAM_CALLBACK_IRQ) )
> > +        goto out;
> > +
> > +    rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_set_param);
> > +    if ( rc )
> > +        goto out;
> > +
> > +    switch ( a.index )
> > +    {
> > +    case HVM_PARAM_CALLBACK_IRQ:
> > +        hvm_set_callback_via(d, a.value);
> > +        hvm_latch_shinfo_size(d);
> > +        break;
> > +    case HVM_PARAM_TIMER_MODE:
> > +        if ( a.value > HVMPTM_one_missed_tick_pending )
> > +            rc = -EINVAL;
> > +        break;
> > +    case HVM_PARAM_VIRIDIAN:
> > +        /* This should only ever be set once by the tools and read by the
> guest. */
> > +        rc = -EPERM;
> > +        if ( d == current->domain )
> > +            break;
> > +
> > +        if ( a.value != d->arch.hvm_domain.params[a.index] )
> > +        {
> > +            rc = -EEXIST;
> > +            if ( d->arch.hvm_domain.params[a.index] != 0 )
> > +                break;
> > +
> > +            rc = -EINVAL;
> > +            if ( (a.value & ~HVMPV_feature_mask) ||
> > +                 !(a.value & HVMPV_base_freq) )
> > +                break;
> > +        }
> > +
> > +        rc = 0;
> > +        break;
> > +    case HVM_PARAM_IDENT_PT:
> > +        /* Not reflexive, as we must domain_pause(). */
> > +        rc = -EPERM;
> > +        if ( d == current->domain )
> > +            break;
> > +
> > +        rc = -EINVAL;
> > +        if ( d->arch.hvm_domain.params[a.index] != 0 )
> > +            break;
> > +
> > +        rc = 0;
> > +        if ( !paging_mode_hap(d) )
> > +            break;
> > +
> > +        /*
> > +         * Update GUEST_CR3 in each VMCS to point at identity map.
> > +         * All foreign updates to guest state must synchronise on
> > +         * the domctl_lock.
> > +         */
> > +        rc = -ERESTART;
> > +        if ( !domctl_lock_acquire() )
> > +            break;
> > +
> > +        rc = 0;
> > +        domain_pause(d);
> > +        d->arch.hvm_domain.params[a.index] = a.value;
> > +        for_each_vcpu ( d, v )
> > +            paging_update_cr3(v);
> > +        domain_unpause(d);
> > +
> > +        domctl_lock_release();
> > +        break;
> > +    case HVM_PARAM_DM_DOMAIN:
> > +        /* Not reflexive, as we may need to domain_pause(). */
> > +        rc = -EPERM;
> > +        if ( d == current->domain )
> > +            break;
> > +
> > +        if ( a.value == DOMID_SELF )
> > +            a.value = current->domain->domain_id;
> > +
> > +        rc = hvm_set_dm_domain(d, a.value);
> > +        break;
> > +    case HVM_PARAM_ACPI_S_STATE:
> > +        /* Not reflexive, as we must domain_pause(). */
> > +        rc = -EPERM;
> > +        if ( current->domain == d )
> > +            break;
> > +
> > +        rc = 0;
> > +        if ( a.value == 3 )
> > +            hvm_s3_suspend(d);
> > +        else if ( a.value == 0 )
> > +            hvm_s3_resume(d);
> > +        else
> > +            rc = -EINVAL;
> > +
> > +        break;
> > +    case HVM_PARAM_ACPI_IOPORTS_LOCATION:
> > +        rc = pmtimer_change_ioport(d, a.value);
> > +        break;
> > +    case HVM_PARAM_MEMORY_EVENT_CR0:
> > +    case HVM_PARAM_MEMORY_EVENT_CR3:
> > +    case HVM_PARAM_MEMORY_EVENT_CR4:
> > +        if ( d == current->domain )
> > +            rc = -EPERM;
> > +        break;
> > +    case HVM_PARAM_MEMORY_EVENT_INT3:
> > +    case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
> > +    case HVM_PARAM_MEMORY_EVENT_MSR:
> > +        if ( d == current->domain )
> > +        {
> > +            rc = -EPERM;
> > +            break;
> > +        }
> > +        if ( a.value & HVMPME_onchangeonly )
> > +            rc = -EINVAL;
> > +        break;
> > +    case HVM_PARAM_NESTEDHVM:
> > +        rc = xsm_hvm_param_nested(XSM_PRIV, d);
> > +        if ( rc )
> > +            break;
> > +        if ( a.value > 1 )
> > +            rc = -EINVAL;
> > +        /* Remove the check below once we have
> > +         * shadow-on-shadow.
> > +         */
> > +        if ( cpu_has_svm && !paging_mode_hap(d) && a.value )
> > +            rc = -EINVAL;
> > +        /* Set up NHVM state for any vcpus that are already up */
> > +        if ( a.value &&
> > +             !d->arch.hvm_domain.params[HVM_PARAM_NESTEDHVM] )
> > +            for_each_vcpu(d, v)
> > +                if ( rc == 0 )
> > +                    rc = nestedhvm_vcpu_initialise(v);
> > +        if ( !a.value || rc )
> > +            for_each_vcpu(d, v)
> > +                nestedhvm_vcpu_destroy(v);
> > +        break;
> > +    case HVM_PARAM_BUFIOREQ_EVTCHN:
> > +        rc = -EINVAL;
> > +        break;
> > +    case HVM_PARAM_TRIPLE_FAULT_REASON:
> > +        if ( a.value > SHUTDOWN_MAX )
> > +            rc = -EINVAL;
> > +        break;
> > +    case HVM_PARAM_IOREQ_SERVER_PFN:
> > +        if ( d == current->domain )
> > +        {
> > +            rc = -EPERM;
> > +            break;
> > +        }
> > +        d->arch.hvm_domain.ioreq_gmfn.base = a.value;
> > +        break;
> > +    case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
> > +    {
> > +        unsigned int i;
> > +
> > +        if ( d == current->domain )
> > +        {
> > +            rc = -EPERM;
> > +            break;
> > +        }
> > +        if ( a.value == 0 ||
> > +             a.value > sizeof(d->arch.hvm_domain.ioreq_gmfn.mask) * 8 )
> > +        {
> > +            rc = -EINVAL;
> > +            break;
> > +        }
> > +        for ( i = 0; i < a.value; i++ )
> > +            set_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
> > +
> > +        break;
> > +    }
> > +    }
> > +
> > +    if ( rc != 0 )
> > +        goto out;
> > +
> > +    d->arch.hvm_domain.params[a.index] = a.value;
> > +
> > +    switch( a.index )
> > +    {
> > +    case HVM_PARAM_MEMORY_EVENT_INT3:
> > +    case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
> > +    {
> > +        domain_pause(d);
> > +        domain_unpause(d); /* Causes guest to latch new status */
> > +        break;
> > +    }
> > +    case HVM_PARAM_MEMORY_EVENT_CR3:
> > +    {
> > +        for_each_vcpu ( d, v )
> > +            hvm_funcs.update_guest_cr(v, 0); /* Latches new CR3 mask
> through CR0 code */
> > +        break;
> > +    }
> > +    }
> > +
> > +    HVM_DBG_LOG(DBG_LEVEL_HCALL, "set param %u = %"PRIx64,
> > +                a.index, a.value);
> > +
> > + out:
> > +    rcu_unlock_domain(d);
> > +    return rc;
> > +}
> > +
> > +static int hvmop_get_param(
> > +    XEN_GUEST_HANDLE_PARAM(xen_hvm_param_t) arg)
> > +{
> > +    struct xen_hvm_param a;
> > +    struct domain *d;
> > +    int rc = 0;
> > +
> > +    if ( copy_from_guest(&a, arg, 1) )
> > +        return -EFAULT;
> > +
> > +    if ( a.index >= HVM_NR_PARAMS )
> > +        return -EINVAL;
> > +
> > +    d = rcu_lock_domain_by_any_id(a.domid);
> > +    if ( d == NULL )
> > +        return -ESRCH;
> > +
> > +    rc = -EINVAL;
> > +    if ( !has_hvm_container_domain(d) )
> > +        goto out;
> > +
> > +    if ( is_pvh_domain(d)
> > +         && (a.index != HVM_PARAM_CALLBACK_IRQ) )
> > +        goto out;
> > +
> > +    rc = xsm_hvm_param(XSM_TARGET, d, HVMOP_get_param);
> > +    if ( rc )
> > +        goto out;
> > +
> > +    switch ( a.index )
> > +    {
> > +    case HVM_PARAM_ACPI_S_STATE:
> > +        a.value = d->arch.hvm_domain.is_s3_suspended ? 3 : 0;
> > +        break;
> > +    case HVM_PARAM_IOREQ_SERVER_PFN:
> > +    case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
> > +        if ( d == current->domain )
> > +        {
> > +            rc = -EPERM;
> > +            goto out;
> > +        }
> > +    case HVM_PARAM_IOREQ_PFN:
> > +    case HVM_PARAM_BUFIOREQ_PFN:
> > +    case HVM_PARAM_BUFIOREQ_EVTCHN: {
> > +        domid_t domid;
> > +
> > +        /* May need to create server */
> > +        domid = d->arch.hvm_domain.params[HVM_PARAM_DM_DOMAIN];
> > +        rc = hvm_create_ioreq_server(d, domid, 1, 1, NULL);
> > +        if ( rc != 0 && rc != -EEXIST )
> > +            goto out;
> > +        /*FALLTHRU*/
> > +    }
> > +    default:
> > +        a.value = d->arch.hvm_domain.params[a.index];
> > +        break;
> > +    }
> > +
> > +    rc = __copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
> > +
> > +    HVM_DBG_LOG(DBG_LEVEL_HCALL, "get param %u = %"PRIx64,
> > +                a.index, a.value);
> > +
> > + out:
> > +    rcu_unlock_domain(d);
> > +    return rc;
> > +}
> > +
> >  /*
> >   * Note that this value is effectively part of the ABI, even if we don't 
> > need
> >   * to make it a formal part of it: A guest suspended for migration in the
> > @@ -5651,7 +5945,6 @@ static int hvmop_set_evtchn_upcall_vector(
> >  long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE_PARAM(void)
> arg)
> >
> >  {
> > -    struct domain *curr_d = current->domain;
> >      unsigned long start_iter, mask;
> >      long rc = 0;
> >
> > @@ -5705,269 +5998,14 @@ long do_hvm_op(unsigned long op,
> XEN_GUEST_HANDLE_PARAM(void) arg)
> >          break;
> >
> >      case HVMOP_set_param:
> > -    case HVMOP_get_param:
> > -    {
> > -        struct xen_hvm_param a;
> > -        struct domain *d;
> > -        struct vcpu *v;
> > -
> > -        if ( copy_from_guest(&a, arg, 1) )
> > -            return -EFAULT;
> > -
> > -        if ( a.index >= HVM_NR_PARAMS )
> > -            return -EINVAL;
> > -
> > -        d = rcu_lock_domain_by_any_id(a.domid);
> > -        if ( d == NULL )
> > -            return -ESRCH;
> > -
> > -        rc = -EINVAL;
> > -        if ( !has_hvm_container_domain(d) )
> > -            goto param_fail;
> > -
> > -        if ( is_pvh_domain(d)
> > -             && (a.index != HVM_PARAM_CALLBACK_IRQ) )
> > -            goto param_fail;
> > -
> > -        rc = xsm_hvm_param(XSM_TARGET, d, op);
> > -        if ( rc )
> > -            goto param_fail;
> > -
> > -        if ( op == HVMOP_set_param )
> > -        {
> > -            rc = 0;
> > -
> > -            switch ( a.index )
> > -            {
> > -            case HVM_PARAM_CALLBACK_IRQ:
> > -                hvm_set_callback_via(d, a.value);
> > -                hvm_latch_shinfo_size(d);
> > -                break;
> > -            case HVM_PARAM_TIMER_MODE:
> > -                if ( a.value > HVMPTM_one_missed_tick_pending )
> > -                    rc = -EINVAL;
> > -                break;
> > -            case HVM_PARAM_VIRIDIAN:
> > -                /* This should only ever be set once by the tools and read 
> > by the
> guest. */
> > -                rc = -EPERM;
> > -                if ( curr_d == d )
> > -                    break;
> > -
> > -                if ( a.value != d->arch.hvm_domain.params[a.index] )
> > -                {
> > -                    rc = -EEXIST;
> > -                    if ( d->arch.hvm_domain.params[a.index] != 0 )
> > -                        break;
> > -
> > -                    rc = -EINVAL;
> > -                    if ( (a.value & ~HVMPV_feature_mask) ||
> > -                         !(a.value & HVMPV_base_freq) )
> > -                        break;
> > -                }
> > -
> > -                rc = 0;
> > -                break;
> > -            case HVM_PARAM_IDENT_PT:
> > -                /* Not reflexive, as we must domain_pause(). */
> > -                rc = -EPERM;
> > -                if ( curr_d == d )
> > -                    break;
> > -
> > -                rc = -EINVAL;
> > -                if ( d->arch.hvm_domain.params[a.index] != 0 )
> > -                    break;
> > -
> > -                rc = 0;
> > -                if ( !paging_mode_hap(d) )
> > -                    break;
> > -
> > -                /*
> > -                 * Update GUEST_CR3 in each VMCS to point at identity map.
> > -                 * All foreign updates to guest state must synchronise on
> > -                 * the domctl_lock.
> > -                 */
> > -                rc = -ERESTART;
> > -                if ( !domctl_lock_acquire() )
> > -                    break;
> > -
> > -                rc = 0;
> > -                domain_pause(d);
> > -                d->arch.hvm_domain.params[a.index] = a.value;
> > -                for_each_vcpu ( d, v )
> > -                    paging_update_cr3(v);
> > -                domain_unpause(d);
> > -
> > -                domctl_lock_release();
> > -                break;
> > -            case HVM_PARAM_DM_DOMAIN:
> > -                /* Not reflexive, as we may need to domain_pause(). */
> > -                rc = -EPERM;
> > -                if ( curr_d == d )
> > -                    break;
> > -
> > -                if ( a.value == DOMID_SELF )
> > -                    a.value = curr_d->domain_id;
> > -
> > -                rc = hvm_set_dm_domain(d, a.value);
> > -                break;
> > -            case HVM_PARAM_ACPI_S_STATE:
> > -                /* Not reflexive, as we must domain_pause(). */
> > -                rc = -EPERM;
> > -                if ( curr_d == d )
> > -                    break;
> > -
> > -                rc = 0;
> > -                if ( a.value == 3 )
> > -                    hvm_s3_suspend(d);
> > -                else if ( a.value == 0 )
> > -                    hvm_s3_resume(d);
> > -                else
> > -                    rc = -EINVAL;
> > -
> > -                break;
> > -            case HVM_PARAM_ACPI_IOPORTS_LOCATION:
> > -                rc = pmtimer_change_ioport(d, a.value);
> > -                break;
> > -            case HVM_PARAM_MEMORY_EVENT_CR0:
> > -            case HVM_PARAM_MEMORY_EVENT_CR3:
> > -            case HVM_PARAM_MEMORY_EVENT_CR4:
> > -                if ( d == current->domain )
> > -                    rc = -EPERM;
> > -                break;
> > -            case HVM_PARAM_MEMORY_EVENT_INT3:
> > -            case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
> > -            case HVM_PARAM_MEMORY_EVENT_MSR:
> > -                if ( d == current->domain )
> > -                {
> > -                    rc = -EPERM;
> > -                    break;
> > -                }
> > -                if ( a.value & HVMPME_onchangeonly )
> > -                    rc = -EINVAL;
> > -                break;
> > -            case HVM_PARAM_NESTEDHVM:
> > -                rc = xsm_hvm_param_nested(XSM_PRIV, d);
> > -                if ( rc )
> > -                    break;
> > -                if ( a.value > 1 )
> > -                    rc = -EINVAL;
> > -                /* Remove the check below once we have
> > -                 * shadow-on-shadow.
> > -                 */
> > -                if ( cpu_has_svm && !paging_mode_hap(d) && a.value )
> > -                    rc = -EINVAL;
> > -                /* Set up NHVM state for any vcpus that are already up */
> > -                if ( a.value &&
> > -                     !d->arch.hvm_domain.params[HVM_PARAM_NESTEDHVM] )
> > -                    for_each_vcpu(d, v)
> > -                        if ( rc == 0 )
> > -                            rc = nestedhvm_vcpu_initialise(v);
> > -                if ( !a.value || rc )
> > -                    for_each_vcpu(d, v)
> > -                        nestedhvm_vcpu_destroy(v);
> > -                break;
> > -            case HVM_PARAM_BUFIOREQ_EVTCHN:
> > -                rc = -EINVAL;
> > -                break;
> > -            case HVM_PARAM_TRIPLE_FAULT_REASON:
> > -                if ( a.value > SHUTDOWN_MAX )
> > -                    rc = -EINVAL;
> > -                break;
> > -            case HVM_PARAM_IOREQ_SERVER_PFN:
> > -                if ( d == current->domain )
> > -                {
> > -                    rc = -EPERM;
> > -                    break;
> > -                }
> > -                d->arch.hvm_domain.ioreq_gmfn.base = a.value;
> > -                break;
> > -            case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
> > -            {
> > -                unsigned int i;
> > -
> > -                if ( d == current->domain )
> > -                {
> > -                    rc = -EPERM;
> > -                    break;
> > -                }
> > -                if ( a.value == 0 ||
> > -                     a.value > sizeof(d->arch.hvm_domain.ioreq_gmfn.mask) 
> > * 8 )
> > -                {
> > -                    rc = -EINVAL;
> > -                    break;
> > -                }
> > -                for ( i = 0; i < a.value; i++ )
> > -                    set_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
> > -
> > -                break;
> > -            }
> > -            }
> > -
> > -            if ( rc == 0 )
> > -            {
> > -                d->arch.hvm_domain.params[a.index] = a.value;
> > -
> > -                switch( a.index )
> > -                {
> > -                case HVM_PARAM_MEMORY_EVENT_INT3:
> > -                case HVM_PARAM_MEMORY_EVENT_SINGLE_STEP:
> > -                {
> > -                    domain_pause(d);
> > -                    domain_unpause(d); /* Causes guest to latch new status 
> > */
> > -                    break;
> > -                }
> > -                case HVM_PARAM_MEMORY_EVENT_CR3:
> > -                {
> > -                    for_each_vcpu ( d, v )
> > -                        hvm_funcs.update_guest_cr(v, 0); /* Latches new 
> > CR3 mask
> through CR0 code */
> > -                    break;
> > -                }
> > -                }
> > -
> > -            }
> > -
> > -        }
> > -        else
> > -        {
> > -            switch ( a.index )
> > -            {
> > -            case HVM_PARAM_ACPI_S_STATE:
> > -                a.value = d->arch.hvm_domain.is_s3_suspended ? 3 : 0;
> > -                break;
> > -            case HVM_PARAM_IOREQ_SERVER_PFN:
> > -            case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
> > -                if ( d == current->domain )
> > -                {
> > -                    rc = -EPERM;
> > -                    break;
> > -                }
> > -            case HVM_PARAM_IOREQ_PFN:
> > -            case HVM_PARAM_BUFIOREQ_PFN:
> > -            case HVM_PARAM_BUFIOREQ_EVTCHN: {
> > -                domid_t domid;
> > -
> > -                /* May need to create server */
> > -                domid = d-
> >arch.hvm_domain.params[HVM_PARAM_DM_DOMAIN];
> > -                rc = hvm_create_ioreq_server(d, domid, 1, 1, NULL);
> > -                if ( rc != 0 && rc != -EEXIST )
> > -                    goto param_fail;
> > -                /*FALLTHRU*/
> > -            }
> > -            default:
> > -                a.value = d->arch.hvm_domain.params[a.index];
> > -                break;
> > -            }
> > -            rc = __copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
> > -        }
> > -
> > -        HVM_DBG_LOG(DBG_LEVEL_HCALL, "%s param %u = %"PRIx64,
> > -                    op == HVMOP_set_param ? "set" : "get",
> > -                    a.index, a.value);
> > +        rc = hvmop_set_param(
> > +            guest_handle_cast(arg, xen_hvm_param_t));
> > +        break;
> >
> > -    param_fail:
> > -        rcu_unlock_domain(d);
> > +    case HVMOP_get_param:
> > +        rc = hvmop_get_param(
> > +            guest_handle_cast(arg, xen_hvm_param_t));
> >          break;
> > -    }
> >
> >      case HVMOP_set_pci_intx_level:
> >          rc = hvmop_set_pci_intx_level(


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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.