xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: Chao Peng <chao.p.peng@linux.intel.com>
Cc: keir@xen.org, Ian.Campbell@citrix.com,
	stefano.stabellini@eu.citrix.com, George.Dunlap@eu.citrix.com,
	andrew.cooper3@citrix.com, Ian.Jackson@eu.citrix.com,
	xen-devel@lists.xen.org, dgdegra@tycho.nsa.gov
Subject: Re: [PATCH v19 01/10] x86: add generic resource (e.g. MSR) access hypercall
Date: Thu, 02 Oct 2014 15:22:52 +0100	[thread overview]
Message-ID: <542D7BDC020000780003C095@mail.emea.novell.com> (raw)
In-Reply-To: <1412249735-4215-2-git-send-email-chao.p.peng@linux.intel.com>

>>> On 02.10.14 at 13:35, <chao.p.peng@linux.intel.com> wrote:
> +static void check_resource_access(struct xen_resource_access *ra)
> +{
> +    xenpf_resource_entry_t *entry;
> +    int ret = 0;
> +    unsigned int i;
> +
> +    for ( i = 0; i < ra->nr_entries; i++ )
> +    {
> +        entry = ra->entries + i;
> +
> +        if ( entry->rsvd )
> +        {
> +            entry->u.ret = -EINVAL;
> +            break;
> +        }
> +
> +        switch ( entry->u.cmd )
> +        {
> +        case XEN_RESOURCE_OP_MSR_READ:
> +        case XEN_RESOURCE_OP_MSR_WRITE:
> +            if ( entry->idx >> 32 )
> +                ret = -EINVAL;
> +            else if ( !allow_access_msr(entry->idx) )
> +                ret = -EACCES;
> +            break;
> +        default:
> +            ret = -EOPNOTSUPP;
> +            break;
> +        }
> +
> +        if ( ret )
> +        {
> +           entry->u.ret = ret;
> +           break;
> +        }
> +    }
> +
> +    ra->idx_done = i;

This is slightly abusing the field (considering its name) when all
entries succeeded, but I guess we can live with that. Beyond
that I have only cosmetic remarks to make, which I could equally
well address when committing (unless other issue get noticed by
someone else):

> +static void resource_access(void *info)
> +{
> +    struct xen_resource_access *ra = info;
> +    xenpf_resource_entry_t *entry;
> +    int ret;

I'd prefer these two to be inside the loop (also again in the earlier
function).

> +    unsigned int i;
> +
> +    for ( i = 0; i < ra->idx_done; i++ )
> +    {
> +        entry = ra->entries + i;
> +
> +        switch ( entry->u.cmd )
> +        {
> +        case XEN_RESOURCE_OP_MSR_READ:
> +            ret = rdmsr_safe(entry->idx, entry->val);
> +            break;
> +        case XEN_RESOURCE_OP_MSR_WRITE:
> +            ret = wrmsr_safe(entry->idx, entry->val);
> +            break;
> +        default:
> +            BUG();
> +            break;
> +        }
> +
> +        entry->u.ret = ret;
> +        if ( ret )
> +           break;

I continue to wonder whether we wouldn't be better off not
overwriting the command in the success case.

> @@ -601,6 +685,80 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
>      }
>      break;
>  
> +    case XENPF_resource_op:
> +    {
> +        struct xen_resource_access ra;
> +        uint32_t cpu;

unsigned int

> +        XEN_GUEST_HANDLE(xenpf_resource_entry_t) guest_entries;
> +
> +        ra.nr_entries = op->u.resource_op.nr_entries;
> +        if ( ra.nr_entries == 0 )
> +        {
> +            ret = 0;
> +            break;
> +        }
> +        else if ( ra.nr_entries > RESOURCE_ACCESS_MAX_ENTRIES )

Pointless "else".

> +        {
> +            ret = -EINVAL;
> +            break;
> +        }
> +
> +        ra.entries = xmalloc_array(xenpf_resource_entry_t, ra.nr_entries);
> +        if ( !ra.entries )
> +        {
> +            ret = -ENOMEM;
> +            break;
> +        }
> +
> +        guest_from_compat_handle(guest_entries, op->u.resource_op.entries);
> +
> +        if ( copy_from_guest(ra.entries, guest_entries, ra.nr_entries) )
> +        {
> +            xfree(ra.entries);
> +            ret = -EFAULT;
> +            break;
> +        }
> +
> +        /* Do sanity check earlier to omit the potential IPI overhead. */
> +        check_resource_access(&ra);
> +        if ( ra.idx_done == 0 )
> +        {
> +            /* Copy the return value for entry 0 if it failed. */
> +            if ( __copy_to_guest_offset(guest_entries, 0, ra.entries, 1) )

__copy_to_guest()

> +                ret = -EFAULT;
> +            else
> +                ret = 0;
> +
> +            xfree(ra.entries);
> +            break;
> +        }
> +
> +        cpu = op->u.resource_op.cpu;
> +        if ( (cpu >= nr_cpu_ids) || !cpu_online(cpu) )
> +        {
> +            xfree(ra.entries);
> +            ret = -ENODEV;
> +            break;
> +        }
> +        else if ( cpu == smp_processor_id() )

Pointless "else" again.

> +            resource_access(&ra);
> +        else
> +            on_selected_cpus(cpumask_of(cpu), resource_access, &ra, 1);
> +
> +        /* Copy all if succeeded or up to the failed entry. */
> +        if ( __copy_to_guest_offset(guest_entries, 0, ra.entries,

__copy_to_guest()

> +                                    min(ra.nr_entries, ra.idx_done + 1)) )

I still think it would be more natural to code

ra.idx_done < ra.nr_entries ? ra.idx_done + 1 : ra.nr_entries

This has the same effect, but avoids the slight abuse of min() here
(and would look even more natural if idx_done was renamed to
nr_done or nr_valid).

> +        {
> +            xfree(ra.entries);
> +            ret = -EFAULT;
> +            break;
> +        }
> +
> +        ret = ra.idx_done;

And this again is a slight abuse. Also, handling this as an "else" to the
preceding "if" would save you an xfree() invocation and a "break".

> --- a/xen/include/public/platform.h
> +++ b/xen/include/public/platform.h
> @@ -528,6 +528,40 @@ typedef struct xenpf_core_parking xenpf_core_parking_t;
>  DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t);
>  
>  /*
> + * Access generic platform resources(e.g., accessing MSR, port I/O, etc)
> + * in unified way. Batch resource operations in one call are supported and
> + * thay are always non-preemptible and executed in their original order.

they

> + * The batch itself returns a negative integer for general errors, or a
> + * non-negative integer for the number of successful operations. For latter

For the latter

> + * case, the @ret in the failed entry(if have) indicates the exact error and

entry (if any)

> + * it's meaningful only when it has a negative value.

???

> + */
> +#define XENPF_resource_op   61
> +
> +#define XEN_RESOURCE_OP_MSR_READ  0
> +#define XEN_RESOURCE_OP_MSR_WRITE 1
> +
> +struct xenpf_resource_entry {
> +    union {
> +        uint32_t cmd;   /* IN: XEN_RESOURCE_OP_* */
> +        int32_t  ret;   /* OUT: return value for this entry */

Imprecise comment (not all entries have this set).

Jan

  reply	other threads:[~2014-10-02 14:22 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-02 11:35 [PATCH v19 00/10] enable Cache Monitoring Technology (CMT) feature Chao Peng
2014-10-02 11:35 ` [PATCH v19 01/10] x86: add generic resource (e.g. MSR) access hypercall Chao Peng
2014-10-02 14:22   ` Jan Beulich [this message]
2014-10-02 11:35 ` [PATCH v19 02/10] xsm: add resource operation related xsm policy Chao Peng
2014-10-02 11:35 ` [PATCH v19 03/10] tools: provide interface for generic resource access Chao Peng
2014-10-02 11:35 ` [PATCH v19 04/10] x86: detect and initialize Cache Monitoring Technology feature Chao Peng
2014-10-02 14:29   ` Jan Beulich
2014-10-02 11:35 ` [PATCH v19 05/10] x86: dynamically attach/detach CMT service for a guest Chao Peng
2014-10-02 11:35 ` [PATCH v19 06/10] x86: collect global CMT information Chao Peng
2014-10-02 11:35 ` [PATCH v19 07/10] x86: enable CMT for each domain RMID Chao Peng
2014-10-02 11:35 ` [PATCH v19 08/10] x86: add CMT related MSRs in allowed list Chao Peng
2014-10-02 11:35 ` [PATCH v19 09/10] xsm: add CMT related xsm policies Chao Peng
2014-10-02 11:35 ` [PATCH v19 10/10] tools: CMDs and APIs for Cache Monitoring Technology Chao Peng
2014-10-02 14:33 ` [PATCH v19 00/10] enable Cache Monitoring Technology (CMT) feature Jan Beulich
2014-10-02 20:07   ` Konrad Rzeszutek Wilk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=542D7BDC020000780003C095@mail.emea.novell.com \
    --to=jbeulich@suse.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=chao.p.peng@linux.intel.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=keir@xen.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).