RE: [PATCH v4 07/25] ocxl: Add functions to map/unmap LPC memory
From: Alastair D'Silva <hidden>
Date: 2020-04-03 03:50:55
Also in:
linux-mm, lkml, nvdimm
-----Original Message----- From: Dan Williams <redacted> Sent: Wednesday, 1 April 2020 7:49 PM To: Alastair D'Silva <redacted> Cc: Aneesh Kumar K . V <redacted>; Oliver O'Halloran [off-list ref]; Benjamin Herrenschmidt [off-list ref]; Paul Mackerras [off-list ref]; Michael Ellerman [off-list ref]; Frederic Barrat [off-list ref]; Andrew Donnellan [off-list ref]; Arnd Bergmann [off-list ref]; Greg Kroah-Hartman [off-list ref]; Vishal Verma [off-list ref]; Dave Jiang [off-list ref]; Ira Weiny [off-list ref]; Andrew Morton [off-list ref]; Mauro Carvalho Chehab [off-list ref]; David S. Miller [off-list ref]; Rob Herring [off-list ref]; Anton Blanchard [off-list ref]; Krzysztof Kozlowski [off-list ref]; Mahesh Salgaonkar [off-list ref]; Madhavan Srinivasan [off-list ref]; Cédric Le Goater [off-list ref]; Anju T Sudhakar [off-list ref]; Hari Bathini [off-list ref]; Thomas Gleixner [off-list ref]; Greg Kurz [off-list ref]; Nicholas Piggin [off-list ref]; Masahiro Yamada [off-list ref]; Alexey Kardashevskiy [off-list ref]; Linux Kernel Mailing List [off-list ref]; linuxppc-dev [off-list ref]; linux-nvdimm <linux- nvdimm@lists.01.org>; Linux MM [off-list ref] Subject: Re: [PATCH v4 07/25] ocxl: Add functions to map/unmap LPC memory On Sun, Mar 29, 2020 at 10:23 PM Alastair D'Silva [off-list ref] wrote:quoted
Add functions to map/unmap LPC memory"map memory" is an overloaded term. I'm guessing this patch has nothing to do with mapping memory in the MMU. Is it updating hardware resource decoders to start claiming address space that was allocated previously?
It's similar to MMIO - these calls end up setting up a BAR which places the LPC memory into a physical memory range addressable by the kernel.
quoted
Signed-off-by: Alastair D'Silva <redacted> Acked-by: Frederic Barrat <redacted> --- drivers/misc/ocxl/core.c | 51 +++++++++++++++++++++++++++++++ drivers/misc/ocxl/ocxl_internal.h | 3 ++ include/misc/ocxl.h | 21 +++++++++++++ 3 files changed, 75 insertions(+)diff --git a/drivers/misc/ocxl/core.c b/drivers/misc/ocxl/core.c index2531c6cf19a0..75ff14e3882a 100644--- a/drivers/misc/ocxl/core.c +++ b/drivers/misc/ocxl/core.c@@ -210,6 +210,56 @@ static void unmap_mmio_areas(struct ocxl_afu*afu)quoted
release_fn_bar(afu->fn, afu->config.global_mmio_bar); } +int ocxl_afu_map_lpc_mem(struct ocxl_afu *afu) { + struct pci_dev *dev = to_pci_dev(afu->fn->dev.parent); + + if ((afu->config.lpc_mem_size + afu- config.special_purpose_mem_size) == 0) + return 0; + + afu->lpc_base_addr = ocxl_link_lpc_map(afu->fn->link, dev); + if (afu->lpc_base_addr == 0) + return -EINVAL; + + if (afu->config.lpc_mem_size > 0) { + afu->lpc_res.start = afu->lpc_base_addr + afu- config.lpc_mem_offset; + afu->lpc_res.end = afu->lpc_res.start + afu->config.lpc_mem_size- 1;quoted
+ } + + if (afu->config.special_purpose_mem_size > 0) { + afu->special_purpose_res.start = afu->lpc_base_addr + + afu->config.special_purpose_mem_offset; + afu->special_purpose_res.end = afu->special_purpose_res.start + + afu->config.special_purpose_mem_size - 1; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ocxl_afu_map_lpc_mem); + +struct resource *ocxl_afu_lpc_mem(struct ocxl_afu *afu) { + return &afu->lpc_res; +} +EXPORT_SYMBOL_GPL(ocxl_afu_lpc_mem); + +static void unmap_lpc_mem(struct ocxl_afu *afu) { + struct pci_dev *dev = to_pci_dev(afu->fn->dev.parent); + + if (afu->lpc_res.start || afu->special_purpose_res.start) { + void *link = afu->fn->link; + + // only release the link when the the last consumer calls release + ocxl_link_lpc_release(link, dev); + + afu->lpc_res.start = 0; + afu->lpc_res.end = 0; + afu->special_purpose_res.start = 0; + afu->special_purpose_res.end = 0; + } +} + static int configure_afu(struct ocxl_afu *afu, u8 afu_idx, struct pci_dev *dev) { int rc;@@ -251,6 +301,7 @@ static int configure_afu(struct ocxl_afu *afu, u8afu_idx, struct pci_dev *dev) static void deconfigure_afu(struct ocxl_afu *afu) { + unmap_lpc_mem(afu); unmap_mmio_areas(afu); reclaim_afu_pasid(afu); reclaim_afu_actag(afu);diff --git a/drivers/misc/ocxl/ocxl_internal.hb/drivers/misc/ocxl/ocxl_internal.h index 2d7575225bd7..7b975a89db7b 100644--- a/drivers/misc/ocxl/ocxl_internal.h +++ b/drivers/misc/ocxl/ocxl_internal.h@@ -52,6 +52,9 @@ struct ocxl_afu { void __iomem *global_mmio_ptr; u64 pp_mmio_start; void *private; + u64 lpc_base_addr; /* Covers both LPC & special purpose memory */ + struct resource lpc_res; + struct resource special_purpose_res; }; enum ocxl_context_status {diff --git a/include/misc/ocxl.h b/include/misc/ocxl.h index357ef1aadbc0..d8b0b4d46bfb 100644--- a/include/misc/ocxl.h +++ b/include/misc/ocxl.h@@ -203,6 +203,27 @@ int ocxl_irq_set_handler(struct ocxl_context*ctx, int irq_id, // AFU Metadata +/** + * ocxl_afu_map_lpc_mem() - Map the LPC system & special purpose +memory for an AFU + * Do not call this during device discovery, as there may me multiples/me/be/quoted
+ * devices on a link, and the memory is mapped for the whole link, +not + * just one device. It should only be called after all devices have + * registered their memory on the link. + * + * @afu: The AFU that has the LPC memory to map + * + * Returns 0 on success, negative on failure */ int +ocxl_afu_map_lpc_mem(struct ocxl_afu *afu); + +/** + * ocxl_afu_lpc_mem() - Get the physical address range of LPC memory +for an AFU + * @afu: The AFU associated with the LPC memory + * + * Returns a pointer to the resource struct for the physical address +range */ struct resource *ocxl_afu_lpc_mem(struct ocxl_afu *afu); + /** * ocxl_afu_config() - Get a pointer to the config for an AFU * @afu: a pointer to the AFU to get the config for -- 2.24.1
-- Alastair D'Silva mob: 0423 762 819 skype: alastair_dsilva msn: alastair@d-silva.org blog: http://alastair.d-silva.org Twitter: @EvilDeece