* [PATCH 1/3] cxl/pci: Ignore unknown register block types
2021-07-16 23:15 [PATCH 0/3] Rework register enumeration for later reuse Ben Widawsky
@ 2021-07-16 23:15 ` Ben Widawsky
2021-08-02 15:49 ` Jonathan Cameron
2021-07-16 23:15 ` [PATCH 2/3] cxl/pci: Simplify register setup Ben Widawsky
2021-07-16 23:15 ` [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe Ben Widawsky
2 siblings, 1 reply; 10+ messages in thread
From: Ben Widawsky @ 2021-07-16 23:15 UTC (permalink / raw)
To: linux-cxl, Ira Weiny
Cc: Ben Widawsky, Alison Schofield, Dan Williams, Jonathan Cameron,
Vishal Verma
In an effort to explicit avoid supporting vendor specific register
blocks (which can happily be mapped from userspace), entirely skip
probing unknown types. The secondary benefit of this will be revealed
in the future with code simplification.
Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
---
drivers/cxl/pci.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index d7da18ebba81..dd0ac89fbdf4 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1106,14 +1106,6 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
u64 offset;
u8 bar;
- map = kzalloc(sizeof(*map), GFP_KERNEL);
- if (!map) {
- ret = -ENOMEM;
- goto free_maps;
- }
-
- list_add(&map->list, ®ister_maps);
-
pci_read_config_dword(pdev, regloc, ®_lo);
pci_read_config_dword(pdev, regloc + 4, ®_hi);
@@ -1123,6 +1115,18 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
dev_dbg(dev, "Found register block in bar %u @ 0x%llx of type %u\n",
bar, offset, reg_type);
+ /* Ignore unknown register block types */
+ if (reg_type > CXL_REGLOC_RBI_MEMDEV)
+ continue;
+
+ map = kzalloc(sizeof(*map), GFP_KERNEL);
+ if (!map) {
+ ret = -ENOMEM;
+ goto free_maps;
+ }
+
+ list_add(&map->list, ®ister_maps);
+
base = cxl_mem_map_regblock(cxlm, bar, offset);
if (!base) {
ret = -ENOMEM;
--
2.32.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/3] cxl/pci: Ignore unknown register block types
2021-07-16 23:15 ` [PATCH 1/3] cxl/pci: Ignore unknown register block types Ben Widawsky
@ 2021-08-02 15:49 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2021-08-02 15:49 UTC (permalink / raw)
To: Ben Widawsky
Cc: linux-cxl, Ira Weiny, Alison Schofield, Dan Williams, Vishal Verma
On Fri, 16 Jul 2021 16:15:46 -0700
Ben Widawsky <ben.widawsky@intel.com> wrote:
> In an effort to explicit avoid supporting vendor specific register
> blocks (which can happily be mapped from userspace), entirely skip
> probing unknown types. The secondary benefit of this will be revealed
> in the future with code simplification.
>
> Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
Seems sensible even on it's own as we don't do anything with unknown
blocks anyway.
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
> drivers/cxl/pci.c | 20 ++++++++++++--------
> 1 file changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index d7da18ebba81..dd0ac89fbdf4 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1106,14 +1106,6 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> u64 offset;
> u8 bar;
>
> - map = kzalloc(sizeof(*map), GFP_KERNEL);
> - if (!map) {
> - ret = -ENOMEM;
> - goto free_maps;
> - }
> -
> - list_add(&map->list, ®ister_maps);
> -
> pci_read_config_dword(pdev, regloc, ®_lo);
> pci_read_config_dword(pdev, regloc + 4, ®_hi);
>
> @@ -1123,6 +1115,18 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> dev_dbg(dev, "Found register block in bar %u @ 0x%llx of type %u\n",
> bar, offset, reg_type);
>
> + /* Ignore unknown register block types */
> + if (reg_type > CXL_REGLOC_RBI_MEMDEV)
> + continue;
> +
> + map = kzalloc(sizeof(*map), GFP_KERNEL);
> + if (!map) {
> + ret = -ENOMEM;
> + goto free_maps;
> + }
> +
> + list_add(&map->list, ®ister_maps);
> +
> base = cxl_mem_map_regblock(cxlm, bar, offset);
> if (!base) {
> ret = -ENOMEM;
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/3] cxl/pci: Simplify register setup
2021-07-16 23:15 [PATCH 0/3] Rework register enumeration for later reuse Ben Widawsky
2021-07-16 23:15 ` [PATCH 1/3] cxl/pci: Ignore unknown register block types Ben Widawsky
@ 2021-07-16 23:15 ` Ben Widawsky
2021-08-02 15:50 ` Jonathan Cameron
2021-07-16 23:15 ` [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe Ben Widawsky
2 siblings, 1 reply; 10+ messages in thread
From: Ben Widawsky @ 2021-07-16 23:15 UTC (permalink / raw)
To: linux-cxl, Ira Weiny
Cc: Ben Widawsky, Alison Schofield, Dan Williams, Jonathan Cameron,
Vishal Verma
It is desirable to retain the mappings from the calling function. By
simplifying this code, it will be much more straightforward to do that.
Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
---
drivers/cxl/cxl.h | 1 -
drivers/cxl/pci.c | 38 ++++++++++++--------------------------
drivers/cxl/pci.h | 1 +
3 files changed, 13 insertions(+), 27 deletions(-)
diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
index b6bda39a59e3..53927f9fa77e 100644
--- a/drivers/cxl/cxl.h
+++ b/drivers/cxl/cxl.h
@@ -140,7 +140,6 @@ struct cxl_device_reg_map {
};
struct cxl_register_map {
- struct list_head list;
u64 block_offset;
u8 reg_type;
u8 barno;
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index dd0ac89fbdf4..8be18daa1420 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1079,9 +1079,8 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
struct device *dev = &pdev->dev;
u32 regloc_size, regblocks;
void __iomem *base;
- int regloc, i;
- struct cxl_register_map *map, *n;
- LIST_HEAD(register_maps);
+ int regloc, i, n_maps;
+ struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES];
int ret = 0;
regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
@@ -1100,7 +1099,7 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET;
regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8;
- for (i = 0; i < regblocks; i++, regloc += 8) {
+ for (i = 0, n_maps = 0; i < regblocks; i++, regloc += 8) {
u32 reg_lo, reg_hi;
u8 reg_type;
u64 offset;
@@ -1119,20 +1118,11 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
if (reg_type > CXL_REGLOC_RBI_MEMDEV)
continue;
- map = kzalloc(sizeof(*map), GFP_KERNEL);
- if (!map) {
- ret = -ENOMEM;
- goto free_maps;
- }
-
- list_add(&map->list, ®ister_maps);
-
base = cxl_mem_map_regblock(cxlm, bar, offset);
- if (!base) {
- ret = -ENOMEM;
- goto free_maps;
- }
+ if (!base)
+ return -ENOMEM;
+ map = &maps[n_maps];
map->barno = bar;
map->block_offset = offset;
map->reg_type = reg_type;
@@ -1143,21 +1133,17 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
cxl_mem_unmap_regblock(cxlm, base);
if (ret)
- goto free_maps;
+ return ret;
+
+ n_maps++;
}
pci_release_mem_regions(pdev);
- list_for_each_entry(map, ®ister_maps, list) {
- ret = cxl_map_regs(cxlm, map);
+ for (i = 0; i < n_maps; i++) {
+ ret = cxl_map_regs(cxlm, &maps[i]);
if (ret)
- goto free_maps;
- }
-
-free_maps:
- list_for_each_entry_safe(map, n, ®ister_maps, list) {
- list_del(&map->list);
- kfree(map);
+ break;
}
return ret;
diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h
index dad7a831f65f..8c1a58813816 100644
--- a/drivers/cxl/pci.h
+++ b/drivers/cxl/pci.h
@@ -25,6 +25,7 @@
#define CXL_REGLOC_RBI_COMPONENT 1
#define CXL_REGLOC_RBI_VIRT 2
#define CXL_REGLOC_RBI_MEMDEV 3
+#define CXL_REGLOC_RBI_TYPES CXL_REGLOC_RBI_MEMDEV + 1
#define CXL_REGLOC_ADDR_MASK GENMASK(31, 16)
--
2.32.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/3] cxl/pci: Simplify register setup
2021-07-16 23:15 ` [PATCH 2/3] cxl/pci: Simplify register setup Ben Widawsky
@ 2021-08-02 15:50 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2021-08-02 15:50 UTC (permalink / raw)
To: Ben Widawsky
Cc: linux-cxl, Ira Weiny, Alison Schofield, Dan Williams, Vishal Verma
On Fri, 16 Jul 2021 16:15:47 -0700
Ben Widawsky <ben.widawsky@intel.com> wrote:
> It is desirable to retain the mappings from the calling function. By
> simplifying this code, it will be much more straightforward to do that.
>
> Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
Nice. Moving such a small structure onto the stack makes sense
as the diff stats show.
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
> drivers/cxl/cxl.h | 1 -
> drivers/cxl/pci.c | 38 ++++++++++++--------------------------
> drivers/cxl/pci.h | 1 +
> 3 files changed, 13 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h
> index b6bda39a59e3..53927f9fa77e 100644
> --- a/drivers/cxl/cxl.h
> +++ b/drivers/cxl/cxl.h
> @@ -140,7 +140,6 @@ struct cxl_device_reg_map {
> };
>
> struct cxl_register_map {
> - struct list_head list;
> u64 block_offset;
> u8 reg_type;
> u8 barno;
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index dd0ac89fbdf4..8be18daa1420 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1079,9 +1079,8 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> struct device *dev = &pdev->dev;
> u32 regloc_size, regblocks;
> void __iomem *base;
> - int regloc, i;
> - struct cxl_register_map *map, *n;
> - LIST_HEAD(register_maps);
> + int regloc, i, n_maps;
> + struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES];
> int ret = 0;
>
> regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
> @@ -1100,7 +1099,7 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> regloc += PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET;
> regblocks = (regloc_size - PCI_DVSEC_ID_CXL_REGLOC_BLOCK1_OFFSET) / 8;
>
> - for (i = 0; i < regblocks; i++, regloc += 8) {
> + for (i = 0, n_maps = 0; i < regblocks; i++, regloc += 8) {
> u32 reg_lo, reg_hi;
> u8 reg_type;
> u64 offset;
> @@ -1119,20 +1118,11 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> if (reg_type > CXL_REGLOC_RBI_MEMDEV)
> continue;
>
> - map = kzalloc(sizeof(*map), GFP_KERNEL);
> - if (!map) {
> - ret = -ENOMEM;
> - goto free_maps;
> - }
> -
> - list_add(&map->list, ®ister_maps);
> -
> base = cxl_mem_map_regblock(cxlm, bar, offset);
> - if (!base) {
> - ret = -ENOMEM;
> - goto free_maps;
> - }
> + if (!base)
> + return -ENOMEM;
>
> + map = &maps[n_maps];
> map->barno = bar;
> map->block_offset = offset;
> map->reg_type = reg_type;
> @@ -1143,21 +1133,17 @@ static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> cxl_mem_unmap_regblock(cxlm, base);
>
> if (ret)
> - goto free_maps;
> + return ret;
> +
> + n_maps++;
> }
>
> pci_release_mem_regions(pdev);
>
> - list_for_each_entry(map, ®ister_maps, list) {
> - ret = cxl_map_regs(cxlm, map);
> + for (i = 0; i < n_maps; i++) {
> + ret = cxl_map_regs(cxlm, &maps[i]);
> if (ret)
> - goto free_maps;
> - }
> -
> -free_maps:
> - list_for_each_entry_safe(map, n, ®ister_maps, list) {
> - list_del(&map->list);
> - kfree(map);
> + break;
> }
>
> return ret;
> diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h
> index dad7a831f65f..8c1a58813816 100644
> --- a/drivers/cxl/pci.h
> +++ b/drivers/cxl/pci.h
> @@ -25,6 +25,7 @@
> #define CXL_REGLOC_RBI_COMPONENT 1
> #define CXL_REGLOC_RBI_VIRT 2
> #define CXL_REGLOC_RBI_MEMDEV 3
> +#define CXL_REGLOC_RBI_TYPES CXL_REGLOC_RBI_MEMDEV + 1
>
> #define CXL_REGLOC_ADDR_MASK GENMASK(31, 16)
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe
2021-07-16 23:15 [PATCH 0/3] Rework register enumeration for later reuse Ben Widawsky
2021-07-16 23:15 ` [PATCH 1/3] cxl/pci: Ignore unknown register block types Ben Widawsky
2021-07-16 23:15 ` [PATCH 2/3] cxl/pci: Simplify register setup Ben Widawsky
@ 2021-07-16 23:15 ` Ben Widawsky
2021-08-02 15:56 ` Jonathan Cameron
2 siblings, 1 reply; 10+ messages in thread
From: Ben Widawsky @ 2021-07-16 23:15 UTC (permalink / raw)
To: linux-cxl, Ira Weiny
Cc: Ben Widawsky, Alison Schofield, Dan Williams, Jonathan Cameron,
Vishal Verma
In order for a memdev to participate in cxl_core's port APIs, the
physical address of the memdev's component registers is needed. This is
accomplished by allocating the array of maps in probe so they can be
used after the memdev is created.
Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
---
drivers/cxl/pci.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index 8be18daa1420..f924a8c5a831 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1066,21 +1066,22 @@ static void cxl_decode_register_block(u32 reg_lo, u32 reg_hi,
/**
* cxl_mem_setup_regs() - Setup necessary MMIO.
* @cxlm: The CXL memory device to communicate with.
+ * @maps: Array of maps populated by this function.
*
- * Return: 0 if all necessary registers mapped.
+ * Return: 0 if all necessary registers mapped. The results are stored in @maps.
*
* A memory device is required by spec to implement a certain set of MMIO
* regions. The purpose of this function is to enumerate and map those
* registers.
*/
-static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
+static int cxl_mem_setup_regs(struct cxl_mem *cxlm, struct cxl_register_map maps[])
{
struct pci_dev *pdev = cxlm->pdev;
struct device *dev = &pdev->dev;
u32 regloc_size, regblocks;
void __iomem *base;
int regloc, i, n_maps;
- struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES];
+ struct cxl_register_map *map;
int ret = 0;
regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
@@ -1364,6 +1365,7 @@ static void cxl_memdev_shutdown(struct cxl_memdev *cxlmd)
static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
+ struct cxl_register_map maps[CXL_REGLOC_RBI_TYPES];
struct cxl_memdev *cxlmd;
struct cxl_mem *cxlm;
int rc;
@@ -1376,7 +1378,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (IS_ERR(cxlm))
return PTR_ERR(cxlm);
- rc = cxl_mem_setup_regs(cxlm);
+ rc = cxl_mem_setup_regs(cxlm, maps);
if (rc)
return rc;
--
2.32.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe
2021-07-16 23:15 ` [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe Ben Widawsky
@ 2021-08-02 15:56 ` Jonathan Cameron
2021-08-02 16:10 ` Dan Williams
0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Cameron @ 2021-08-02 15:56 UTC (permalink / raw)
To: Ben Widawsky
Cc: linux-cxl, Ira Weiny, Alison Schofield, Dan Williams, Vishal Verma
On Fri, 16 Jul 2021 16:15:48 -0700
Ben Widawsky <ben.widawsky@intel.com> wrote:
> In order for a memdev to participate in cxl_core's port APIs, the
> physical address of the memdev's component registers is needed. This is
> accomplished by allocating the array of maps in probe so they can be
> used after the memdev is created.
>
> Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
Hmm. I don't entirely like the the passing of an array of
unknown size into cxl_mem_setup_regs. It is perhaps paranoid
but I'd separately pass in the size and error out should we
overflow with a suitable message to highlight the bug.
So far this code is also not justified by anything using the
array now it's been moved up a layer. Looks that doesn't happen
until patch 22 of your large WIP series. I think this patch needs
to be in the same series as that one as it doesn't stand on
it's own.
Jonathan
> ---
> drivers/cxl/pci.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index 8be18daa1420..f924a8c5a831 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1066,21 +1066,22 @@ static void cxl_decode_register_block(u32 reg_lo, u32 reg_hi,
> /**
> * cxl_mem_setup_regs() - Setup necessary MMIO.
> * @cxlm: The CXL memory device to communicate with.
> + * @maps: Array of maps populated by this function.
> *
> - * Return: 0 if all necessary registers mapped.
> + * Return: 0 if all necessary registers mapped. The results are stored in @maps.
> *
> * A memory device is required by spec to implement a certain set of MMIO
> * regions. The purpose of this function is to enumerate and map those
> * registers.
> */
> -static int cxl_mem_setup_regs(struct cxl_mem *cxlm)
> +static int cxl_mem_setup_regs(struct cxl_mem *cxlm, struct cxl_register_map maps[])
> {
> struct pci_dev *pdev = cxlm->pdev;
> struct device *dev = &pdev->dev;
> u32 regloc_size, regblocks;
> void __iomem *base;
> int regloc, i, n_maps;
> - struct cxl_register_map *map, maps[CXL_REGLOC_RBI_TYPES];
> + struct cxl_register_map *map;
> int ret = 0;
>
> regloc = cxl_mem_dvsec(pdev, PCI_DVSEC_ID_CXL_REGLOC_DVSEC_ID);
> @@ -1364,6 +1365,7 @@ static void cxl_memdev_shutdown(struct cxl_memdev *cxlmd)
>
> static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> {
> + struct cxl_register_map maps[CXL_REGLOC_RBI_TYPES];
> struct cxl_memdev *cxlmd;
> struct cxl_mem *cxlm;
> int rc;
> @@ -1376,7 +1378,7 @@ static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> if (IS_ERR(cxlm))
> return PTR_ERR(cxlm);
>
> - rc = cxl_mem_setup_regs(cxlm);
> + rc = cxl_mem_setup_regs(cxlm, maps);
> if (rc)
> return rc;
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe
2021-08-02 15:56 ` Jonathan Cameron
@ 2021-08-02 16:10 ` Dan Williams
2021-08-02 17:09 ` Dan Williams
0 siblings, 1 reply; 10+ messages in thread
From: Dan Williams @ 2021-08-02 16:10 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Ben Widawsky, linux-cxl, Ira Weiny, Alison Schofield, Vishal Verma
On Mon, Aug 2, 2021 at 8:57 AM Jonathan Cameron
<Jonathan.Cameron@huawei.com> wrote:
>
> On Fri, 16 Jul 2021 16:15:48 -0700
> Ben Widawsky <ben.widawsky@intel.com> wrote:
>
> > In order for a memdev to participate in cxl_core's port APIs, the
> > physical address of the memdev's component registers is needed. This is
> > accomplished by allocating the array of maps in probe so they can be
> > used after the memdev is created.
> >
> > Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
>
> Hmm. I don't entirely like the the passing of an array of
> unknown size into cxl_mem_setup_regs. It is perhaps paranoid
> but I'd separately pass in the size and error out should we
> overflow with a suitable message to highlight the bug.
Agree.
>
> So far this code is also not justified by anything using the
> array now it's been moved up a layer. Looks that doesn't happen
> until patch 22 of your large WIP series. I think this patch needs
> to be in the same series as that one as it doesn't stand on
> it's own.
Agree, I'll reorder this change to closer to where it is used.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe
2021-08-02 16:10 ` Dan Williams
@ 2021-08-02 17:09 ` Dan Williams
2021-08-03 7:58 ` Jonathan Cameron
0 siblings, 1 reply; 10+ messages in thread
From: Dan Williams @ 2021-08-02 17:09 UTC (permalink / raw)
To: Jonathan Cameron
Cc: Ben Widawsky, linux-cxl, Ira Weiny, Alison Schofield, Vishal Verma
On Mon, Aug 2, 2021 at 9:10 AM Dan Williams <dan.j.williams@intel.com> wrote:
>
> On Mon, Aug 2, 2021 at 8:57 AM Jonathan Cameron
> <Jonathan.Cameron@huawei.com> wrote:
> >
> > On Fri, 16 Jul 2021 16:15:48 -0700
> > Ben Widawsky <ben.widawsky@intel.com> wrote:
> >
> > > In order for a memdev to participate in cxl_core's port APIs, the
> > > physical address of the memdev's component registers is needed. This is
> > > accomplished by allocating the array of maps in probe so they can be
> > > used after the memdev is created.
> > >
> > > Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
> >
> > Hmm. I don't entirely like the the passing of an array of
> > unknown size into cxl_mem_setup_regs. It is perhaps paranoid
> > but I'd separately pass in the size and error out should we
> > overflow with a suitable message to highlight the bug.
>
> Agree.
Here's the incremental diff I came up with:
diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
index c370ab2e48bc..ff72286142e7 100644
--- a/drivers/cxl/pci.c
+++ b/drivers/cxl/pci.c
@@ -1086,7 +1086,8 @@ static void cxl_decode_register_block(u32
reg_lo, u32 reg_hi,
* regions. The purpose of this function is to enumerate and map those
* registers.
*/
-static int cxl_mem_setup_regs(struct cxl_mem *cxlm, struct
cxl_register_map maps[])
+static int cxl_mem_setup_regs(struct cxl_mem *cxlm,
+ struct cxl_register_maps *maps)
{
struct pci_dev *pdev = cxlm->pdev;
struct device *dev = &pdev->dev;
@@ -1135,7 +1136,9 @@ static int cxl_mem_setup_regs(struct cxl_mem
*cxlm, struct cxl_register_map maps
if (!base)
return -ENOMEM;
- map = &maps[n_maps];
+ if (n_maps > ARRAY_SIZE(maps->map))
+ return -ENXIO;
+ map = &maps->map[n_maps++];
map->barno = bar;
map->block_offset = offset;
map->reg_type = reg_type;
@@ -1147,14 +1150,12 @@ static int cxl_mem_setup_regs(struct cxl_mem
*cxlm, struct cxl_register_map maps
if (ret)
return ret;
-
- n_maps++;
}
pci_release_mem_regions(pdev);
for (i = 0; i < n_maps; i++) {
- ret = cxl_map_regs(cxlm, &maps[i]);
+ ret = cxl_map_regs(cxlm, &maps->map[i]);
if (ret)
break;
}
@@ -1370,7 +1371,7 @@ static int cxl_mem_identify(struct cxl_mem *cxlm)
static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- struct cxl_register_map maps[CXL_REGLOC_RBI_TYPES];
+ struct cxl_register_maps maps;
struct cxl_memdev *cxlmd;
struct cxl_mem *cxlm;
int rc;
@@ -1383,7 +1384,7 @@ static int cxl_mem_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
if (IS_ERR(cxlm))
return PTR_ERR(cxlm);
- rc = cxl_mem_setup_regs(cxlm, maps);
+ rc = cxl_mem_setup_regs(cxlm, &maps);
if (rc)
return rc;
diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h
index 8c1a58813816..5b7828003b76 100644
--- a/drivers/cxl/pci.h
+++ b/drivers/cxl/pci.h
@@ -2,6 +2,7 @@
/* Copyright(c) 2020 Intel Corporation. All rights reserved. */
#ifndef __CXL_PCI_H__
#define __CXL_PCI_H__
+#include "cxlmem.h"
#define CXL_MEMORY_PROGIF 0x10
@@ -29,4 +30,8 @@
#define CXL_REGLOC_ADDR_MASK GENMASK(31, 16)
+struct cxl_register_maps {
+ struct cxl_register_map map[CXL_REGLOC_RBI_TYPES];
+};
+
#endif /* __CXL_PCI_H__ */
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 3/3] cxl/pci: Retain map information in cxl_mem_probe
2021-08-02 17:09 ` Dan Williams
@ 2021-08-03 7:58 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2021-08-03 7:58 UTC (permalink / raw)
To: Dan Williams
Cc: Ben Widawsky, linux-cxl, Ira Weiny, Alison Schofield, Vishal Verma
On Mon, 2 Aug 2021 10:09:45 -0700
Dan Williams <dan.j.williams@intel.com> wrote:
> On Mon, Aug 2, 2021 at 9:10 AM Dan Williams <dan.j.williams@intel.com> wrote:
> >
> > On Mon, Aug 2, 2021 at 8:57 AM Jonathan Cameron
> > <Jonathan.Cameron@huawei.com> wrote:
> > >
> > > On Fri, 16 Jul 2021 16:15:48 -0700
> > > Ben Widawsky <ben.widawsky@intel.com> wrote:
> > >
> > > > In order for a memdev to participate in cxl_core's port APIs, the
> > > > physical address of the memdev's component registers is needed. This is
> > > > accomplished by allocating the array of maps in probe so they can be
> > > > used after the memdev is created.
> > > >
> > > > Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
> > >
> > > Hmm. I don't entirely like the the passing of an array of
> > > unknown size into cxl_mem_setup_regs. It is perhaps paranoid
> > > but I'd separately pass in the size and error out should we
> > > overflow with a suitable message to highlight the bug.
> >
> > Agree.
>
> Here's the incremental diff I came up with:
>
> diff --git a/drivers/cxl/pci.c b/drivers/cxl/pci.c
> index c370ab2e48bc..ff72286142e7 100644
> --- a/drivers/cxl/pci.c
> +++ b/drivers/cxl/pci.c
> @@ -1086,7 +1086,8 @@ static void cxl_decode_register_block(u32
> reg_lo, u32 reg_hi,
> * regions. The purpose of this function is to enumerate and map those
> * registers.
> */
> -static int cxl_mem_setup_regs(struct cxl_mem *cxlm, struct
> cxl_register_map maps[])
> +static int cxl_mem_setup_regs(struct cxl_mem *cxlm,
> + struct cxl_register_maps *maps)
> {
> struct pci_dev *pdev = cxlm->pdev;
> struct device *dev = &pdev->dev;
> @@ -1135,7 +1136,9 @@ static int cxl_mem_setup_regs(struct cxl_mem
> *cxlm, struct cxl_register_map maps
> if (!base)
> return -ENOMEM;
>
> - map = &maps[n_maps];
> + if (n_maps > ARRAY_SIZE(maps->map))
> + return -ENXIO;
> + map = &maps->map[n_maps++];
> map->barno = bar;
> map->block_offset = offset;
> map->reg_type = reg_type;
> @@ -1147,14 +1150,12 @@ static int cxl_mem_setup_regs(struct cxl_mem
> *cxlm, struct cxl_register_map maps
>
> if (ret)
> return ret;
> -
> - n_maps++;
I found original form of this block with the separate n_maps++ a little
bit more readable. But otherwise this approach looks good to me.
Jonathan
> }
>
> pci_release_mem_regions(pdev);
>
> for (i = 0; i < n_maps; i++) {
> - ret = cxl_map_regs(cxlm, &maps[i]);
> + ret = cxl_map_regs(cxlm, &maps->map[i]);
> if (ret)
> break;
> }
> @@ -1370,7 +1371,7 @@ static int cxl_mem_identify(struct cxl_mem *cxlm)
>
> static int cxl_mem_probe(struct pci_dev *pdev, const struct pci_device_id *id)
> {
> - struct cxl_register_map maps[CXL_REGLOC_RBI_TYPES];
> + struct cxl_register_maps maps;
> struct cxl_memdev *cxlmd;
> struct cxl_mem *cxlm;
> int rc;
> @@ -1383,7 +1384,7 @@ static int cxl_mem_probe(struct pci_dev *pdev,
> const struct pci_device_id *id)
> if (IS_ERR(cxlm))
> return PTR_ERR(cxlm);
>
> - rc = cxl_mem_setup_regs(cxlm, maps);
> + rc = cxl_mem_setup_regs(cxlm, &maps);
> if (rc)
> return rc;
>
> diff --git a/drivers/cxl/pci.h b/drivers/cxl/pci.h
> index 8c1a58813816..5b7828003b76 100644
> --- a/drivers/cxl/pci.h
> +++ b/drivers/cxl/pci.h
> @@ -2,6 +2,7 @@
> /* Copyright(c) 2020 Intel Corporation. All rights reserved. */
> #ifndef __CXL_PCI_H__
> #define __CXL_PCI_H__
> +#include "cxlmem.h"
>
> #define CXL_MEMORY_PROGIF 0x10
>
> @@ -29,4 +30,8 @@
>
> #define CXL_REGLOC_ADDR_MASK GENMASK(31, 16)
>
> +struct cxl_register_maps {
> + struct cxl_register_map map[CXL_REGLOC_RBI_TYPES];
> +};
> +
> #endif /* __CXL_PCI_H__ */
^ permalink raw reply [flat|nested] 10+ messages in thread