All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Roger Pau Monné" <roger.pau@citrix.com>
To: Jan Beulich <jbeulich@suse.com>
Cc: Paul Durrant <paul@xen.org>, xen-devel@lists.xenproject.org
Subject: Re: [PATCH v3 4/7] x86/iommu: introduce a rangeset to perform hwdom IOMMU setup
Date: Wed, 20 Dec 2023 10:52:01 +0100	[thread overview]
Message-ID: <ZYK5QXmbHhxKdS31@macbook> (raw)
In-Reply-To: <454027bf-b07e-49cf-97de-009d431e5f4b@suse.com>

On Tue, Dec 19, 2023 at 05:06:32PM +0100, Jan Beulich wrote:
> On 15.12.2023 15:18, Roger Pau Monne wrote:
> > --- a/xen/drivers/passthrough/x86/iommu.c
> > +++ b/xen/drivers/passthrough/x86/iommu.c
> > @@ -370,10 +370,88 @@ static unsigned int __hwdom_init hwdom_iommu_map(const struct domain *d,
> >      return perms;
> >  }
> >  
> > +struct map_data {
> > +    struct domain *d;
> > +    unsigned int flush_flags;
> > +    bool mmio_ro;
> > +};
> > +
> > +static int __hwdom_init cf_check identity_map(unsigned long s, unsigned long e,
> > +                                              void *data)
> > +{
> > +    struct map_data *info = data;
> > +    struct domain *d = info->d;
> > +    long rc;
> > +
> > +    if ( iommu_verbose )
> > +        printk(XENLOG_INFO " [%010lx, %010lx] R%c\n",
> > +               s, e, info->mmio_ro ? 'O' : 'W');
> > +
> > +    if ( paging_mode_translate(d) )
> > +    {
> > +        if ( info->mmio_ro )
> > +        {
> > +            ASSERT_UNREACHABLE();
> > +            return 0;
> 
> Is this meant to be in line with the main return statement's comment?
> I'm inclined to ask for an actual error code (-EOPNOTSUPP?) here.

Hm, yes, for that one it might make sense to return -EOPNOTSUPP, as
all attempts to map will end up failing anyway.

> > +        }
> > +        while ( (rc = map_mmio_regions(d, _gfn(s), e - s + 1, _mfn(s))) > 0 )
> > +        {
> > +            s += rc;
> > +            process_pending_softirqs();
> > +        }
> > +    }
> > +    else
> > +    {
> > +        const unsigned int perms = IOMMUF_readable | IOMMUF_preempt |
> > +                                   (info->mmio_ro ? 0 : IOMMUF_writable);
> > +
> > +        /*
> > +         * Read-only ranges are only created based on the contents of mmio
> > +         * read-only rangeset, and hence need the additional iomem permissions
> > +         * check.
> > +         */
> > +        while( info->mmio_ro && s <= e && !iomem_access_permitted(d, s, e) )
> 
> Nit: Missing blank after "while".
> 
> > +        {
> > +            /*
> > +             * Consume a frame per iteration until the reminder is accessible
> 
> Nit: remainder?
> 
> > +             * or there's nothing left to map.
> > +             */
> > +            if ( iomem_access_permitted(d, s, s) )
> > +            {
> > +                rc = iommu_map(d, _dfn(s), _mfn(s), 1, perms,
> > +                               &info->flush_flags);
> > +                if ( rc < 0 )
> > +                    break;
> > +                /* Must map a frame at least, which is what we request for. */
> > +                ASSERT(rc == 1);
> > +                process_pending_softirqs();
> > +            }
> > +            s++;
> > +        }
> > +        while ( (rc = iommu_map(d, _dfn(s), _mfn(s), e - s + 1,
> > +                                perms, &info->flush_flags)) > 0 )
> > +        {
> > +            s += rc;
> > +            process_pending_softirqs();
> > +        }
> > +    }
> > +    ASSERT(rc <= 0);
> > +    if ( rc )
> > +        printk(XENLOG_WARNING
> > +               "IOMMU identity mapping of [%lx, %lx] failed: %ld\n",
> > +               s, e, rc);
> > +
> > +    /* Ignore errors and attempt to map the remaining regions. */
> > +    return 0;
> > +}
> > +
> >  void __hwdom_init arch_iommu_hwdom_init(struct domain *d)
> >  {
> >      unsigned long i, top, max_pfn, start, count;
> >      unsigned int flush_flags = 0, start_perms = 0;
> > +    struct rangeset *map;
> > +    struct map_data map_data = { .d = d };
> > +    int rc;
> >  
> >      BUG_ON(!is_hardware_domain(d));
> >  
> > @@ -397,6 +475,10 @@ void __hwdom_init arch_iommu_hwdom_init(struct domain *d)
> >      if ( iommu_hwdom_passthrough )
> >          return;
> >  
> > +    map = rangeset_new(NULL, NULL, 0);
> > +    if ( !map )
> > +        panic("IOMMU init: unable to allocate rangeset\n");
> > +
> >      max_pfn = (GB(4) >> PAGE_SHIFT) - 1;
> >      top = max(max_pdx, pfn_to_pdx(max_pfn) + 1);
> >  
> > @@ -451,8 +533,26 @@ void __hwdom_init arch_iommu_hwdom_init(struct domain *d)
> >              goto commit;
> >      }
> >  
> > +    if ( iommu_verbose )
> > +        printk(XENLOG_INFO "%pd: identity mappings for IOMMU:\n", d);
> > +
> > +    rc = rangeset_report_ranges(map, 0, ~0UL, identity_map, &map_data);
> > +    if ( rc )
> > +        panic("IOMMU unable to create mappings: %d\n", rc);
> > +    rangeset_destroy(map);
> > +
> > +    if ( is_pv_domain(d) )
> > +    {
> > +        map_data.mmio_ro = true;
> > +        rc = rangeset_report_ranges(mmio_ro_ranges, 0, ~0UL, identity_map,
> > +                                    &map_data);
> > +        if ( rc )
> > +            panic("IOMMU unable to create read-only mappings: %d\n", rc);
> > +    }
> 
> As it stands identity_map() deliberately returns no error. Yet here
> you panic() in case of receiving an error, despite that being impossible?

I wasn't sure whether rangeset_report_ranges() itself could return an
error.  Thinking twice, we might want to print a message and attempt
to continue, as in the worst case dom0 might be missing maps.

> Also if we want/need to panic() here, can we avoid having two instances
> of almost the same string literal in .rodata? Along the lines of
> 
>     rc = rangeset_report_ranges(map, 0, ~0UL, identity_map, &map_data);
>     rangeset_destroy(map);
>     if ( !rc && is_pv_domain(d) )
>     {
>         map_data.mmio_ro = true;
>         rc = rangeset_report_ranges(mmio_ro_ranges, 0, ~0UL, identity_map,
>                                     &map_data);
>     }
>     if ( rc )
>         panic("IOMMU unable to create %smappings: %d\n",
>               map_data.mmio_ro ? "read-only " : "", rc);
> 
> ?
> 
> > +    map_data.flush_flags |= flush_flags;
> 
> So you decided to still keep the standalone "flush_flags" around. Is
> there a particular reason?

Oh, git distracted with the other changes and forgot about this one.

Thanks, Roger.


  reply	other threads:[~2023-12-20  9:52 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-15 14:18 [PATCH v3 0/7] x86/iommu: improve setup time of hwdom IOMMU Roger Pau Monne
2023-12-15 14:18 ` [PATCH v3 1/7] iommu/vt-d: do not assume page table levels for quarantine domain Roger Pau Monne
2023-12-15 14:18 ` [PATCH v3 2/7] x86/p2m: move and rename paging_max_paddr_bits() Roger Pau Monne
2023-12-19 15:38   ` Jan Beulich
2023-12-15 14:18 ` [PATCH v3 3/7] amd-vi: set IOMMU page table levels based on guest reported paddr width Roger Pau Monne
2023-12-19 15:40   ` Jan Beulich
2023-12-15 14:18 ` [PATCH v3 4/7] x86/iommu: introduce a rangeset to perform hwdom IOMMU setup Roger Pau Monne
2023-12-19 16:06   ` Jan Beulich
2023-12-20  9:52     ` Roger Pau Monné [this message]
2023-12-15 14:18 ` [PATCH v3 5/7] x86/iommu: remove regions not to be mapped Roger Pau Monne
2023-12-19 16:18   ` Jan Beulich
2023-12-20 10:22     ` Roger Pau Monné
2023-12-15 14:18 ` [PATCH v3 6/7] x86/iommu: switch hwdom IOMMU to use a rangeset Roger Pau Monne
2023-12-19 16:21   ` Jan Beulich
2023-12-15 14:18 ` [PATCH v3 7/7] x86/iommu: cleanup unused functions Roger Pau Monne
2023-12-19 16:23   ` Jan Beulich
2023-12-20 10:31     ` Roger Pau Monné
2023-12-20 10:36       ` Jan Beulich

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=ZYK5QXmbHhxKdS31@macbook \
    --to=roger.pau@citrix.com \
    --cc=jbeulich@suse.com \
    --cc=paul@xen.org \
    --cc=xen-devel@lists.xenproject.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.