linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>,
	linux-arm-kernel@lists.infradead.org, linux-acpi@vger.kernel.org,
	iommu@lists.linux-foundation.org
Cc: linuxarm@huawei.com, lorenzo.pieralisi@arm.com, joro@8bytes.org,
	wanghuiqiang@huawei.com, guohanjun@huawei.com,
	steven.price@arm.com, Sami.Mujawar@arm.com, jon@solid-run.com,
	eric.auger@redhat.com, yangyicong@huawei.com
Subject: Re: [PATCH v5 1/8] ACPI/IORT: Add support for RMR node parsing
Date: Mon, 14 Jun 2021 12:14:38 +0100	[thread overview]
Message-ID: <15c7fac0-11a8-0cdb-aac3-b5d8feb8f066@arm.com> (raw)
In-Reply-To: <20210524110222.2212-2-shameerali.kolothum.thodi@huawei.com>

On 2021-05-24 12:02, Shameer Kolothum wrote:
> Add support for parsing RMR node information from ACPI.
> Find associated stream id and smmu node info from the
> RMR node and populate a linked list with RMR memory
> descriptors.
> 
> Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
> ---
>   drivers/acpi/arm64/iort.c | 104 +++++++++++++++++++++++++++++++++++++-
>   1 file changed, 103 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index 3912a1f6058e..fea1ffaedf3b 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -40,6 +40,19 @@ struct iort_fwnode {
>   static LIST_HEAD(iort_fwnode_list);
>   static DEFINE_SPINLOCK(iort_fwnode_lock);
>   
> +/*
> + * One entry for IORT RMR.
> + */
> +struct iort_rmr_entry {
> +	struct list_head list;
> +	u32 sid;
> +	struct acpi_iort_node *smmu;
> +	struct acpi_iort_rmr_desc *rmr_desc;
> +	u32 flags;
> +};
> +
> +static LIST_HEAD(iort_rmr_list);         /* list of RMR regions from ACPI */
> +
>   /**
>    * iort_set_fwnode() - Create iort_fwnode and use it to register
>    *		       iommu data in the iort_fwnode_list
> @@ -393,7 +406,8 @@ static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node,
>   		if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT ||
>   		    node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX ||
>   		    node->type == ACPI_IORT_NODE_SMMU_V3 ||
> -		    node->type == ACPI_IORT_NODE_PMCG) {
> +		    node->type == ACPI_IORT_NODE_PMCG ||
> +		    node->type == ACPI_IORT_NODE_RMR) {
>   			*id_out = map->output_base;
>   			return parent;
>   		}
> @@ -1660,6 +1674,91 @@ static void __init iort_enable_acs(struct acpi_iort_node *iort_node)
>   #else
>   static inline void iort_enable_acs(struct acpi_iort_node *iort_node) { }
>   #endif
> +static int iort_rmr_desc_valid(struct acpi_iort_rmr_desc *desc, u32 count)
> +{
> +	int i, j;
> +
> +	for (i = 0; i < count; i++) {
> +		u64 end, start = desc[i].base_address, length = desc[i].length;
> +
> +		if (!IS_ALIGNED(start, SZ_64K) || !IS_ALIGNED(length, SZ_64K))
> +			return -EINVAL;

We should certainly FW_BUG for this, but maybe it's OK to continue, 
since all we should need to do is round our iommu_resv_regions to at 
least PAGE_SIZE. That seems possibly better than ignoring them and 
having things potentially blow up later (especially if an end user 
exercises the system more thoroughly than the firmware developer tested 
it, which in at least one case I've seen may be "at all"...)

> +		end = start + length - 1;
> +
> +		/* Check for address overlap */
> +		for (j = i + 1; j < count; j++) {
> +			u64 e_start = desc[j].base_address;
> +			u64 e_end = e_start + desc[j].length - 1;
> +
> +			if (start <= e_end && end >= e_start)
> +				return -EINVAL;

Similarly it's not *too* hard to trim overlaps; I guess it's really a 
question of whether we want to bother :/

> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +static int __init iort_parse_rmr(struct acpi_iort_node *iort_node)
> +{
> +	struct acpi_iort_node *smmu;
> +	struct iort_rmr_entry *e;
> +	struct acpi_iort_rmr *rmr;
> +	struct acpi_iort_rmr_desc *rmr_desc;
> +	u32 map_count = iort_node->mapping_count;
> +	u32  sid;

Nit: extra space.

> +	int i, ret = 0;
> +
> +	if (iort_node->type != ACPI_IORT_NODE_RMR)
> +		return 0;
> +
> +	if (!iort_node->mapping_offset || map_count != 1) {

Beware that there was some discussion about allowing multiple SIDs to 
share an RMR descriptor, since there are potential use-cases which would 
otherwise lead to excessive duplication (e.g. an MSI doorbell carveout 
in a VM which would effectively apply to all possible PCI RIDs). I think 
the conclusion we reached was that disallowing that was fairly 
arbitrary, and could possibly be relaxed in future. It looks like the 
design of things here could grow to fit that fairly easily though, so I 
don't think it's a major concern.

Robin.

> +		pr_err(FW_BUG "Invalid ID mapping, skipping RMR node %p\n",
> +		       iort_node);
> +		return -EINVAL;
> +	}
> +
> +	/* Retrieve associated smmu and stream id */
> +	smmu = iort_node_get_id(iort_node, &sid, 0);
> +	if (!smmu) {
> +		pr_err(FW_BUG "Invalid SMMU reference, skipping RMR node %p\n",
> +		       iort_node);
> +		return -EINVAL;
> +	}
> +
> +	/* Retrieve RMR data */
> +	rmr = (struct acpi_iort_rmr *)iort_node->node_data;
> +	if (!rmr->rmr_offset || !rmr->rmr_count) {
> +		pr_err(FW_BUG "Invalid RMR descriptor array, skipping RMR node %p\n",
> +		       iort_node);
> +		return -EINVAL;
> +	}
> +
> +	rmr_desc = ACPI_ADD_PTR(struct acpi_iort_rmr_desc, iort_node,
> +				rmr->rmr_offset);
> +
> +	ret = iort_rmr_desc_valid(rmr_desc, rmr->rmr_count);
> +	if (ret) {
> +		pr_err(FW_BUG "Invalid RMR descriptor[%d] for node %p, skipping...\n",
> +		       i, iort_node);
> +		return ret;
> +	}
> +
> +	for (i = 0; i < rmr->rmr_count; i++, rmr_desc++) {
> +		e = kmalloc(sizeof(*e), GFP_KERNEL);
> +		if (!e)
> +			return -ENOMEM;
> +
> +		e->sid = sid;
> +		e->smmu = smmu;
> +		e->rmr_desc = rmr_desc;
> +		e->flags = rmr->flags;
> +
> +		list_add_tail(&e->list, &iort_rmr_list);
> +	}
> +
> +	return 0;
> +}
>   
>   static void __init iort_init_platform_devices(void)
>   {
> @@ -1689,6 +1788,9 @@ static void __init iort_init_platform_devices(void)
>   
>   		iort_enable_acs(iort_node);
>   
> +		if (iort_table->revision == 3)
> +			iort_parse_rmr(iort_node);
> +
>   		ops = iort_get_dev_cfg(iort_node);
>   		if (ops) {
>   			fwnode = acpi_alloc_fwnode_static();
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2021-06-14 11:18 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-24 11:02 [PATCH v5 0/8] ACPI/IORT: Support for IORT RMR node Shameer Kolothum
2021-05-24 11:02 ` [PATCH v5 1/8] ACPI/IORT: Add support for RMR node parsing Shameer Kolothum
2021-06-14 11:14   ` Robin Murphy [this message]
2021-06-14 12:37     ` Shameerali Kolothum Thodi
2021-05-24 11:02 ` [PATCH v5 2/8] iommu/dma: Introduce generic helper to retrieve RMR info Shameer Kolothum
2021-05-24 15:35   ` kernel test robot
2021-05-24 11:02 ` [PATCH v5 3/8] ACPI/IORT: Add a helper to retrieve RMR memory regions Shameer Kolothum
2021-05-26  7:53   ` Laurentiu Tudor
2021-05-26 16:36     ` Shameerali Kolothum Thodi
2021-05-26 17:11       ` Laurentiu Tudor
2021-06-03 12:27         ` Jon Nettleton
2021-06-03 12:32           ` Laurentiu Tudor
2021-05-27  4:25       ` Jon Nettleton
2021-06-14 10:35       ` Robin Murphy
2021-06-14 11:23   ` Robin Murphy
2021-06-14 12:49     ` Shameerali Kolothum Thodi
2021-06-29 17:34       ` Jon Nettleton
2021-07-04  7:38         ` Jon Nettleton
2021-07-05  9:10           ` Shameerali Kolothum Thodi
2021-05-24 11:02 ` [PATCH v5 4/8] iommu/arm-smmu-v3: Introduce strtab init helper Shameer Kolothum
2021-05-24 11:02 ` [PATCH v5 5/8] iommu/arm-smmu-v3: Add bypass flag to arm_smmu_write_strtab_ent() Shameer Kolothum
2021-06-14 10:23   ` Robin Murphy
2021-06-14 12:51     ` Shameerali Kolothum Thodi
2021-05-24 11:02 ` [PATCH v5 6/8] iommu/arm-smmu-v3: Get associated RMR info and install Shameer Kolothum
2021-06-14 10:15   ` Robin Murphy
2021-05-24 11:02 ` [PATCH v5 7/8] iommu/arm-smmu: Get associated RMR info and install bypass SMR Shameer Kolothum
2021-06-03  8:52   ` Jon Nettleton
2021-06-03 11:27     ` Steven Price
2021-06-03 11:51       ` Jon Nettleton
2021-06-13  7:40         ` Jon Nettleton
2021-06-14  9:23           ` Robin Murphy
2021-06-14 10:06   ` Robin Murphy
2021-06-14 16:51     ` Shameerali Kolothum Thodi
2021-06-15  8:02       ` Jon Nettleton
2021-06-29  7:03     ` Jon Nettleton
2021-06-29 13:22       ` Robin Murphy
2021-06-29 16:25         ` Jon Nettleton
2021-06-30  8:50           ` Shameerali Kolothum Thodi
2021-05-24 11:02 ` [PATCH v5 8/8] iommu/dma: Reserve any RMR regions associated with a dev Shameer Kolothum
2021-05-24 15:18 ` [PATCH v5 0/8] ACPI/IORT: Support for IORT RMR node Steven Price

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=15c7fac0-11a8-0cdb-aac3-b5d8feb8f066@arm.com \
    --to=robin.murphy@arm.com \
    --cc=Sami.Mujawar@arm.com \
    --cc=eric.auger@redhat.com \
    --cc=guohanjun@huawei.com \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jon@solid-run.com \
    --cc=joro@8bytes.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linuxarm@huawei.com \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=shameerali.kolothum.thodi@huawei.com \
    --cc=steven.price@arm.com \
    --cc=wanghuiqiang@huawei.com \
    --cc=yangyicong@huawei.com \
    /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).