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

RE: [PATCH v8 1/2] IOMMU/VT-d: wire common device reserved memory API


  • To: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Henry Wang <Henry.Wang@xxxxxxx>
  • Date: Mon, 17 Oct 2022 01:20:02 +0000
  • Accept-language: zh-CN, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uMVfwCMTa6hADqBJ7X+oJkbnQ7zM2WKTFKjj92Cu6tc=; b=LWzqBIsOPDDZePNUn5HTjfHtML8HrfSivdfcOQf/u7wCbnAD0o/mb8qEWx0DGo4yeYytub4Xm+Jvhd7ADnqnHyT3mnckTD+e3/ND1H2VdvMlzHhErsBhp14jvsdU+9R6g8axKFji+nB0OUsakRgwHQ6RXDpVgc0QtchQ+ObhjkCuNZNqoAAbxgoM7URiI/PCgOXUun2/p6uo7ss+WEVwEUcMqbbDAFvAI0YbmZuX7oPut83YhKu9uMy9HUKE2VuqpbJXRM9gfL6vh7PcaYA/Jc+JHxeBPLS4MTrSMw/MmbryowYPTQeEvhQEE76hOjOuzdMux9+pIX8udH0QNktLlA==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=uMVfwCMTa6hADqBJ7X+oJkbnQ7zM2WKTFKjj92Cu6tc=; b=XAhxGR/j6vUsX+SWOpWFXaSMtlMSX/ZFVqf9x4Bu44TbOxBXPw7lN2C6sVU+lTCN4alRaGz33Xh7VuY4eYcO23d6H4mEkw3IoZNRyr9bim32dmnGoeoAqgM9KHX4xMPzv/B9aQnHt1yfxxX2g2FI7XvFg857gecHZnAzL7fk7OZryjqmf1yvYetwrxErAboTNHoR9OhdWOvlLpBxe3mwj/3IrfatcQL1OjELCrEJelKHKMpzU/8YreOuZZG46qdzTne4ouWsGK51Rp47sPnySuJa3km073nAXvNxv1LFa9pQR9rNJ8ihRF3zwE15M+Qe4paHEJF46IDasdnLjhjMSA==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=i32NPsmMmKHrqxffGg+mQz++eczoGC9qoNWd50hEjTU8G8zh5O/Atk3rv2bn5DgE4AD74LmkQYA9tcbwEg3WqiZjR0ABcie+jVq7wlg90ifOBVzVxxJ91NSS91s0rSaWzJ7yoe0KSvs7nslOBgHVxMZYIZAj3Rrbe1iJ4dj0WeXWD2eXWlRxdvB50FtbN4PQFYLbLgdePl3XUyyTCc/YKFTVRK973zCC4I+RRpTNCnQOOS5jp5JeF1of2n2q7QE6FUQPln1Uo8+7YJghuEcDgCR2N2LXWkBDmQwl51Qy3lIdee1tFtzJLAb5giNGH4hg63cm7SMlLRyhbpg2BJx0qQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MmdHk7w/Xf/M9guvDXd2HRjAmuQufzANxQbdjyxgNd1R9ylm55sPggjQtMFZKK81QAnkqU2wQkRJNT2AEOhH7wPuOhzJ4IWAnYM3ViTRQXsBv+qXaHsLH1JPq9i68svZZWImGz7ivfSHdklBY8iE9X22g1Z39wA2uo2K1B4zbAqJcilkhmbmZpHHP4oDW6LM4d/Dj9RcFrMx76IQuQRktJ+1w6Ry/oh6PmDkgCcaocP6vMpG2WUkgHPrnZDiFmnzn4yixnfklTdTiPeI0dewFpD9f6Kdh3ZQVdbPDizrOQwGLmWDRZsoAi3E8ulnQdqr3fhriK02jeHt7yrVGyf6Fw==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: Kevin Tian <kevin.tian@xxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Mon, 17 Oct 2022 01:20:32 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHY1AgeJwq4WhKefkGyVS1JhkdRo64QKSwAgAG7SUA=
  • Thread-topic: [PATCH v8 1/2] IOMMU/VT-d: wire common device reserved memory API

Hi Marek,

> -----Original Message-----
> From: Marek Marczykowski-Górecki <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
> Subject: Re: [PATCH v8 1/2] IOMMU/VT-d: wire common device reserved
> memory API
> 
> On Thu, Sep 29, 2022 at 03:33:12PM +0200, Marek Marczykowski-Górecki
> wrote:
> > Re-use rmrr= parameter handling code to handle common device reserved
> > memory.
> >
> > Move MAX_USER_RMRR_PAGES limit enforcement to apply only to
> > user-configured ranges, but not those from internal callers.
> >
> > Signed-off-by: Marek Marczykowski-Górecki
> <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
> > Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
> 
> Henry, can this be included in 4.17? The AMD counterpart went in
> earlier, but due to late review on Intel part, this one didn't.

Thanks for the information. I agree this is a valid reason, but to be
safe I would like to hear opinions from the x86 maintainers (added
in CC).

Andrew/Jan/Roger: May I have your feedback about this? Thanks!

Kind regards,
Henry

> 
> > ---
> > Changes in v8:
> > - move add_one_user_rmrr() function earlier
> > - extend commit message
> > Changes in v3:
> > - make MAX_USER_RMRR_PAGES applicable only to user-configured RMRR
> > ---
> >  xen/drivers/passthrough/vtd/dmar.c | 196 +++++++++++++++++-------------
> >  1 file changed, 114 insertions(+), 82 deletions(-)
> >
> > diff --git a/xen/drivers/passthrough/vtd/dmar.c
> b/xen/drivers/passthrough/vtd/dmar.c
> > index 367304c8739c..78c8bad1515a 100644
> > --- a/xen/drivers/passthrough/vtd/dmar.c
> > +++ b/xen/drivers/passthrough/vtd/dmar.c
> > @@ -861,113 +861,136 @@ static struct user_rmrr __initdata
> user_rmrrs[MAX_USER_RMRR];
> >
> >  /* Macro for RMRR inclusive range formatting. */
> >  #define ERMRRU_FMT "[%lx-%lx]"
> > -#define ERMRRU_ARG(eru) eru.base_pfn, eru.end_pfn
> > +#define ERMRRU_ARG base_pfn, end_pfn
> >
> > -static int __init add_user_rmrr(void)
> > +/* Returns 1 on success, 0 when ignoring and < 0 on error. */
> > +static int __init add_one_user_rmrr(unsigned long base_pfn,
> > +                                    unsigned long end_pfn,
> > +                                    unsigned int dev_count,
> > +                                    uint32_t *sbdf)
> >  {
> >      struct acpi_rmrr_unit *rmrr, *rmrru;
> > -    unsigned int idx, seg, i;
> > -    unsigned long base, end;
> > +    unsigned int idx, seg;
> > +    unsigned long base_iter;
> >      bool overlap;
> >
> > -    for ( i = 0; i < nr_rmrr; i++ )
> > +    if ( iommu_verbose )
> > +        printk(XENLOG_DEBUG VTDPREFIX
> > +               "Adding RMRR for %d device ([0]: %#x) range "ERMRRU_FMT"\n",
> > +               dev_count, sbdf[0], ERMRRU_ARG);
> > +
> > +    if ( base_pfn > end_pfn )
> >      {
> > -        base = user_rmrrs[i].base_pfn;
> > -        end = user_rmrrs[i].end_pfn;
> > +        printk(XENLOG_ERR VTDPREFIX
> > +               "Invalid RMRR Range "ERMRRU_FMT"\n",
> > +               ERMRRU_ARG);
> > +        return 0;
> > +    }
> >
> > -        if ( base > end )
> > +    overlap = false;
> > +    list_for_each_entry(rmrru, &acpi_rmrr_units, list)
> > +    {
> > +        if ( pfn_to_paddr(base_pfn) <= rmrru->end_address &&
> > +             rmrru->base_address <= pfn_to_paddr(end_pfn) )
> >          {
> >              printk(XENLOG_ERR VTDPREFIX
> > -                   "Invalid RMRR Range "ERMRRU_FMT"\n",
> > -                   ERMRRU_ARG(user_rmrrs[i]));
> > -            continue;
> > +                   "Overlapping RMRRs: "ERMRRU_FMT" and [%lx-%lx]\n",
> > +                   ERMRRU_ARG,
> > +                   paddr_to_pfn(rmrru->base_address),
> > +                   paddr_to_pfn(rmrru->end_address));
> > +            overlap = true;
> > +            break;
> >          }
> > +    }
> > +    /* Don't add overlapping RMRR. */
> > +    if ( overlap )
> > +        return 0;
> >
> > -        if ( (end - base) >= MAX_USER_RMRR_PAGES )
> > +    base_iter = base_pfn;
> > +    do
> > +    {
> > +        if ( !mfn_valid(_mfn(base_iter)) )
> >          {
> >              printk(XENLOG_ERR VTDPREFIX
> > -                   "RMRR range "ERMRRU_FMT" exceeds "\
> > -                   __stringify(MAX_USER_RMRR_PAGES)" pages\n",
> > -                   ERMRRU_ARG(user_rmrrs[i]));
> > -            continue;
> > +                   "Invalid pfn in RMRR range "ERMRRU_FMT"\n",
> > +                   ERMRRU_ARG);
> > +            break;
> >          }
> > +    } while ( base_iter++ < end_pfn );
> >
> > -        overlap = false;
> > -        list_for_each_entry(rmrru, &acpi_rmrr_units, list)
> > -        {
> > -            if ( pfn_to_paddr(base) <= rmrru->end_address &&
> > -                 rmrru->base_address <= pfn_to_paddr(end) )
> > -            {
> > -                printk(XENLOG_ERR VTDPREFIX
> > -                       "Overlapping RMRRs: "ERMRRU_FMT" and [%lx-%lx]\n",
> > -                       ERMRRU_ARG(user_rmrrs[i]),
> > -                       paddr_to_pfn(rmrru->base_address),
> > -                       paddr_to_pfn(rmrru->end_address));
> > -                overlap = true;
> > -                break;
> > -            }
> > -        }
> > -        /* Don't add overlapping RMRR. */
> > -        if ( overlap )
> > -            continue;
> > +    /* Invalid pfn in range as the loop ended before end_pfn was reached.
> */
> > +    if ( base_iter <= end_pfn )
> > +        return 0;
> >
> > -        do
> > -        {
> > -            if ( !mfn_valid(_mfn(base)) )
> > -            {
> > -                printk(XENLOG_ERR VTDPREFIX
> > -                       "Invalid pfn in RMRR range "ERMRRU_FMT"\n",
> > -                       ERMRRU_ARG(user_rmrrs[i]));
> > -                break;
> > -            }
> > -        } while ( base++ < end );
> > +    rmrr = xzalloc(struct acpi_rmrr_unit);
> > +    if ( !rmrr )
> > +        return -ENOMEM;
> >
> > -        /* Invalid pfn in range as the loop ended before end_pfn was 
> > reached.
> */
> > -        if ( base <= end )
> > -            continue;
> > +    rmrr->scope.devices = xmalloc_array(u16, dev_count);
> > +    if ( !rmrr->scope.devices )
> > +    {
> > +        xfree(rmrr);
> > +        return -ENOMEM;
> > +    }
> >
> > -        rmrr = xzalloc(struct acpi_rmrr_unit);
> > -        if ( !rmrr )
> > -            return -ENOMEM;
> > +    seg = 0;
> > +    for ( idx = 0; idx < dev_count; idx++ )
> > +    {
> > +        rmrr->scope.devices[idx] = sbdf[idx];
> > +        seg |= PCI_SEG(sbdf[idx]);
> > +    }
> > +    if ( seg != PCI_SEG(sbdf[0]) )
> > +    {
> > +        printk(XENLOG_ERR VTDPREFIX
> > +               "Segments are not equal for RMRR range "ERMRRU_FMT"\n",
> > +               ERMRRU_ARG);
> > +        scope_devices_free(&rmrr->scope);
> > +        xfree(rmrr);
> > +        return 0;
> > +    }
> >
> > -        rmrr->scope.devices = xmalloc_array(u16, user_rmrrs[i].dev_count);
> > -        if ( !rmrr->scope.devices )
> > -        {
> > -            xfree(rmrr);
> > -            return -ENOMEM;
> > -        }
> > +    rmrr->segment = seg;
> > +    rmrr->base_address = pfn_to_paddr(base_pfn);
> > +    /* Align the end_address to the end of the page */
> > +    rmrr->end_address = pfn_to_paddr(end_pfn) | ~PAGE_MASK;
> > +    rmrr->scope.devices_cnt = dev_count;
> >
> > -        seg = 0;
> > -        for ( idx = 0; idx < user_rmrrs[i].dev_count; idx++ )
> > -        {
> > -            rmrr->scope.devices[idx] = user_rmrrs[i].sbdf[idx];
> > -            seg |= PCI_SEG(user_rmrrs[i].sbdf[idx]);
> > -        }
> > -        if ( seg != PCI_SEG(user_rmrrs[i].sbdf[0]) )
> > -        {
> > -            printk(XENLOG_ERR VTDPREFIX
> > -                   "Segments are not equal for RMRR range "ERMRRU_FMT"\n",
> > -                   ERMRRU_ARG(user_rmrrs[i]));
> > -            scope_devices_free(&rmrr->scope);
> > -            xfree(rmrr);
> > -            continue;
> > -        }
> > +    if ( register_one_rmrr(rmrr) )
> > +        printk(XENLOG_ERR VTDPREFIX
> > +               "Could not register RMMR range "ERMRRU_FMT"\n",
> > +               ERMRRU_ARG);
> >
> > -        rmrr->segment = seg;
> > -        rmrr->base_address = pfn_to_paddr(user_rmrrs[i].base_pfn);
> > -        /* Align the end_address to the end of the page */
> > -        rmrr->end_address = pfn_to_paddr(user_rmrrs[i].end_pfn) |
> ~PAGE_MASK;
> > -        rmrr->scope.devices_cnt = user_rmrrs[i].dev_count;
> > +    return 1;
> > +}
> >
> > -        if ( register_one_rmrr(rmrr) )
> > -            printk(XENLOG_ERR VTDPREFIX
> > -                   "Could not register RMMR range "ERMRRU_FMT"\n",
> > -                   ERMRRU_ARG(user_rmrrs[i]));
> > -    }
> > +static int __init add_user_rmrr(void)
> > +{
> > +    unsigned int i;
> > +    int ret;
> >
> > +    for ( i = 0; i < nr_rmrr; i++ )
> > +    {
> > +        ret = add_one_user_rmrr(user_rmrrs[i].base_pfn,
> > +                                user_rmrrs[i].end_pfn,
> > +                                user_rmrrs[i].dev_count,
> > +                                user_rmrrs[i].sbdf);
> > +        if ( ret < 0 )
> > +            return ret;
> > +    }
> >      return 0;
> >  }
> >
> > +static int __init cf_check add_one_extra_rmrr(xen_pfn_t start,
> xen_ulong_t nr, u32 id, void *ctxt)
> > +{
> > +    u32 sbdf_array[] = { id };
> > +    return add_one_user_rmrr(start, start+nr, 1, sbdf_array);
> > +}
> > +
> > +static int __init add_extra_rmrr(void)
> > +{
> > +    return
> iommu_get_extra_reserved_device_memory(add_one_extra_rmrr, NULL);
> > +}
> > +
> >  #include <asm/tboot.h>
> >  /* ACPI tables may not be DMA protected by tboot, so use DMAR copy */
> >  /* SINIT saved in SinitMleData in TXT heap (which is DMA protected) */
> > @@ -1010,7 +1033,7 @@ int __init acpi_dmar_init(void)
> >      {
> >          iommu_init_ops = &intel_iommu_init_ops;
> >
> > -        return add_user_rmrr();
> > +        return add_user_rmrr() || add_extra_rmrr();
> >      }
> >
> >      return ret;
> > @@ -1108,6 +1131,15 @@ static int __init cf_check
> parse_rmrr_param(const char *str)
> >          else
> >              end = start;
> >
> > +        if ( (end - start) >= MAX_USER_RMRR_PAGES )
> > +        {
> > +            printk(XENLOG_ERR VTDPREFIX
> > +                    "RMRR range "ERMRRU_FMT" exceeds "\
> > +                    __stringify(MAX_USER_RMRR_PAGES)" pages\n",
> > +                    start, end);
> > +            return -E2BIG;
> > +        }
> > +
> >          user_rmrrs[nr_rmrr].base_pfn = start;
> >          user_rmrrs[nr_rmrr].end_pfn = end;
> >
> > --
> > git-series 0.9.1
> >
> 
> --
> Best Regards,
> Marek Marczykowski-Górecki
> Invisible Things Lab

 


Rackspace

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