Re: [PATCH 1/2] powerpc/powernv: ocxl move SPA definition

2019-10-14 Thread christophe lombard

On 14/10/2019 12:17, Frederic Barrat wrote:


diff --git a/arch/powerpc/platforms/powernv/ocxl.c 
b/arch/powerpc/platforms/powernv/ocxl.c

index 8c65aacda9c8..4d26cba12b63 100644
--- a/arch/powerpc/platforms/powernv/ocxl.c
+++ b/arch/powerpc/platforms/powernv/ocxl.c
@@ -12,11 +12,54 @@
  #define PNV_OCXL_PASID_BITS    15
  #define PNV_OCXL_PASID_MAX    ((1 << PNV_OCXL_PASID_BITS) - 1)

-#define AFU_PRESENT (1 << 31)
-#define AFU_INDEX_MASK 0x3F00
-#define AFU_INDEX_SHIFT 24
-#define ACTAG_MASK 0xFFF
+#define AFU_PRESENT    (1 << 31)
+#define AFU_INDEX_MASK    0x3F00
+#define AFU_INDEX_SHIFT    24
+#define ACTAG_MASK 0xFFF
+
+#define SPA_PASID_BITS    15
+#define SPA_PASID_MAX    ((1 << SPA_PASID_BITS) - 1)
+#define SPA_PE_MASK    SPA_PASID_MAX
+#define SPA_SPA_SIZE_LOG    22 /* Each SPA is 4 Mb */
+#define SPA_PE_VALID    0x8000
+
+#define SPA_CFG_SF    (1ull << (63-0))
+#define SPA_CFG_TA    (1ull << (63-1))
+#define SPA_CFG_HV    (1ull << (63-3))
+#define SPA_CFG_UV    (1ull << (63-4))
+#define SPA_CFG_XLAT_hpt    (0ull << (63-6)) /* Hashed page table 
(HPT) mode */

+#define SPA_CFG_XLAT_roh    (2ull << (63-6)) /* Radix on HPT mode */
+#define SPA_CFG_XLAT_ror    (3ull << (63-6)) /* Radix on Radix mode */
+#define SPA_CFG_PR    (1ull << (63-49))
+#define SPA_CFG_TC    (1ull << (63-54))
+#define SPA_CFG_DR    (1ull << (63-59))
+
+struct ocxl_process_element {
+    __be64 config_state;
+    __be32 reserved1[11];
+    __be32 lpid;
+    __be32 tid;
+    __be32 pid;
+    __be32 reserved2[10];
+    __be64 amr;
+    __be32 reserved3[3];
+    __be32 software_state;
+};
+
+struct spa {
+    struct ocxl_process_element *spa_mem;
+    int spa_order;
+};

+struct platform_data {
+    struct spa *spa;
+    u64 phb_opal_id;
+    u32 bdfn;
+    void __iomem *dsisr;
+    void __iomem *dar;
+    void __iomem *tfc;
+    void __iomem *pe_handle;
+};

  struct actag_range {
  u16 start;
@@ -369,7 +412,7 @@ int pnv_ocxl_set_tl_conf(struct pci_dev *dev, long 
cap,

  }
  EXPORT_SYMBOL_GPL(pnv_ocxl_set_tl_conf);

-int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, int *hwirq)
+static int get_xsl_irq(struct pci_dev *dev, int *hwirq)
  {
  int rc;

@@ -381,19 +424,17 @@ int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, 
int *hwirq)

  }
  return 0;
  }
-EXPORT_SYMBOL_GPL(pnv_ocxl_get_xsl_irq);

-void pnv_ocxl_unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
-    void __iomem *tfc, void __iomem *pe_handle)
+static void unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
+   void __iomem *tfc, void __iomem *pe_handle)
  {
  iounmap(dsisr);
  iounmap(dar);
  iounmap(tfc);
  iounmap(pe_handle);
  }
-EXPORT_SYMBOL_GPL(pnv_ocxl_unmap_xsl_regs);

-int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
+static int map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
  void __iomem **dar, void __iomem **tfc,
  void __iomem **pe_handle)
  {
@@ -429,61 +470,144 @@ int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, 
void __iomem **dsisr,

  }
  return rc;
  }
-EXPORT_SYMBOL_GPL(pnv_ocxl_map_xsl_regs);

-struct spa_data {
-    u64 phb_opal_id;
-    u32 bdfn;
-};
+static int alloc_spa(struct pci_dev *dev, struct platform_data *data)
+{
+    struct spa *spa;
+
+    spa = kzalloc(sizeof(struct spa), GFP_KERNEL);
+    if (!spa)
+    return -ENOMEM;
+
+    spa->spa_order = SPA_SPA_SIZE_LOG - PAGE_SHIFT;
+    spa->spa_mem = (struct ocxl_process_element *)
+    __get_free_pages(GFP_KERNEL | __GFP_ZERO, spa->spa_order);
+    if (!spa->spa_mem) {
+    dev_err(>dev, "Can't allocate Shared Process Area\n");
+    kfree(spa);
+    return -ENOMEM;
+    }
+
+    data->spa = spa;
+    dev_dbg(>dev, "Allocated SPA for %x:%x:%x at %p\n",
+   pci_domain_nr(dev->bus), dev->bus->number,
+   PCI_SLOT(dev->devfn), spa->spa_mem);



If using dev_dbg() then we get the domain, bus and device/fn for free as 
part of the message prefix. Which leaves the SPA address, which may be 
hidden with recent kernel changes since it's a pointer to a kernel 
address (I haven't checked). I guess the message could be reworked. The 
point was really to show that we're allocating a spa structure for the 
link and help debugging any ref count issue.




I think we can even delete this message as it is not very interesting to
be present.




+
+    return 0;
+}
+
+static void free_spa(struct platform_data *data)
+{
+    struct spa *spa = data->spa;
+
+    if (spa && spa->spa_mem) {
+    free_pages((unsigned long) spa->spa_mem, spa->spa_order);
+    kfree(spa);
+    data->spa = NULL;
+    }
+}

-int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask,
-    void **platform_data)
+int pnv_ocxl_platform_setup(struct pci_dev *dev, int PE_mask,
+    int *hwirq, void **platform_data)
  {
  struct pci_controller *hose = 

Re: [PATCH 1/2] powerpc/powernv: ocxl move SPA definition

2019-10-14 Thread Frederic Barrat




diff --git a/arch/powerpc/platforms/powernv/ocxl.c 
b/arch/powerpc/platforms/powernv/ocxl.c
index 8c65aacda9c8..4d26cba12b63 100644
--- a/arch/powerpc/platforms/powernv/ocxl.c
+++ b/arch/powerpc/platforms/powernv/ocxl.c
@@ -12,11 +12,54 @@
  #define PNV_OCXL_PASID_BITS   15
  #define PNV_OCXL_PASID_MAX((1 << PNV_OCXL_PASID_BITS) - 1)

-#define AFU_PRESENT (1 << 31)
-#define AFU_INDEX_MASK 0x3F00
-#define AFU_INDEX_SHIFT 24
-#define ACTAG_MASK 0xFFF
+#define AFU_PRESENT(1 << 31)
+#define AFU_INDEX_MASK 0x3F00
+#define AFU_INDEX_SHIFT24
+#define ACTAG_MASK 0xFFF
+
+#define SPA_PASID_BITS 15
+#define SPA_PASID_MAX  ((1 << SPA_PASID_BITS) - 1)
+#define SPA_PE_MASKSPA_PASID_MAX
+#define SPA_SPA_SIZE_LOG   22 /* Each SPA is 4 Mb */
+#define SPA_PE_VALID   0x8000
+
+#define SPA_CFG_SF (1ull << (63-0))
+#define SPA_CFG_TA (1ull << (63-1))
+#define SPA_CFG_HV (1ull << (63-3))
+#define SPA_CFG_UV (1ull << (63-4))
+#define SPA_CFG_XLAT_hpt   (0ull << (63-6)) /* Hashed page table (HPT) 
mode */
+#define SPA_CFG_XLAT_roh   (2ull << (63-6)) /* Radix on HPT mode */
+#define SPA_CFG_XLAT_ror   (3ull << (63-6)) /* Radix on Radix mode */
+#define SPA_CFG_PR (1ull << (63-49))
+#define SPA_CFG_TC (1ull << (63-54))
+#define SPA_CFG_DR (1ull << (63-59))
+
+struct ocxl_process_element {
+   __be64 config_state;
+   __be32 reserved1[11];
+   __be32 lpid;
+   __be32 tid;
+   __be32 pid;
+   __be32 reserved2[10];
+   __be64 amr;
+   __be32 reserved3[3];
+   __be32 software_state;
+};
+
+struct spa {
+   struct ocxl_process_element *spa_mem;
+   int spa_order;
+};

+struct platform_data {
+   struct spa *spa;
+   u64 phb_opal_id;
+   u32 bdfn;
+   void __iomem *dsisr;
+   void __iomem *dar;
+   void __iomem *tfc;
+   void __iomem *pe_handle;
+};

  struct actag_range {
u16 start;
@@ -369,7 +412,7 @@ int pnv_ocxl_set_tl_conf(struct pci_dev *dev, long cap,
  }
  EXPORT_SYMBOL_GPL(pnv_ocxl_set_tl_conf);

-int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, int *hwirq)
+static int get_xsl_irq(struct pci_dev *dev, int *hwirq)
  {
int rc;

@@ -381,19 +424,17 @@ int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, int *hwirq)
}
return 0;
  }
-EXPORT_SYMBOL_GPL(pnv_ocxl_get_xsl_irq);

-void pnv_ocxl_unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
-   void __iomem *tfc, void __iomem *pe_handle)
+static void unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
+  void __iomem *tfc, void __iomem *pe_handle)
  {
iounmap(dsisr);
iounmap(dar);
iounmap(tfc);
iounmap(pe_handle);
  }
-EXPORT_SYMBOL_GPL(pnv_ocxl_unmap_xsl_regs);

-int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
+static int map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
void __iomem **dar, void __iomem **tfc,
void __iomem **pe_handle)
  {
@@ -429,61 +470,144 @@ int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void 
__iomem **dsisr,
}
return rc;
  }
-EXPORT_SYMBOL_GPL(pnv_ocxl_map_xsl_regs);

-struct spa_data {
-   u64 phb_opal_id;
-   u32 bdfn;
-};
+static int alloc_spa(struct pci_dev *dev, struct platform_data *data)
+{
+   struct spa *spa;
+
+   spa = kzalloc(sizeof(struct spa), GFP_KERNEL);
+   if (!spa)
+   return -ENOMEM;
+
+   spa->spa_order = SPA_SPA_SIZE_LOG - PAGE_SHIFT;
+   spa->spa_mem = (struct ocxl_process_element *)
+   __get_free_pages(GFP_KERNEL | __GFP_ZERO, spa->spa_order);
+   if (!spa->spa_mem) {
+   dev_err(>dev, "Can't allocate Shared Process Area\n");
+   kfree(spa);
+   return -ENOMEM;
+   }
+
+   data->spa = spa;
+   dev_dbg(>dev, "Allocated SPA for %x:%x:%x at %p\n",
+  pci_domain_nr(dev->bus), dev->bus->number,
+  PCI_SLOT(dev->devfn), spa->spa_mem);



If using dev_dbg() then we get the domain, bus and device/fn for free as 
part of the message prefix. Which leaves the SPA address, which may be 
hidden with recent kernel changes since it's a pointer to a kernel 
address (I haven't checked). I guess the message could be reworked. The 
point was really to show that we're allocating a spa structure for the 
link and help debugging any ref count issue.




+
+   return 0;
+}
+
+static void free_spa(struct platform_data *data)
+{
+   struct spa *spa = data->spa;
+
+   if (spa && spa->spa_mem) {
+   free_pages((unsigned long) spa->spa_mem, spa->spa_order);
+   kfree(spa);
+   data->spa = NULL;
+   }
+}

-int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask,
-   void **platform_data)

[PATCH 1/2] powerpc/powernv: ocxl move SPA definition

2019-10-09 Thread christophe lombard
The Scheduled Process Area, located in system momory, contains a list of
Scheduled Processes (Structure of Process Element) to be serviced by the AFUs.
The process elements contain the address context and other state information
for the processes scheduled to run on the AFUs.
Update, rename and create new few platform-specific calls which can be used by
drivers.

No functional change.

Signed-off-by: Christophe Lombard 
---
 arch/powerpc/include/asm/pnv-ocxl.h   |  25 +-
 arch/powerpc/platforms/powernv/ocxl.c | 275 ++--
 drivers/misc/ocxl/afu_irq.c   |   1 -
 drivers/misc/ocxl/link.c  | 347 +++---
 drivers/misc/ocxl/ocxl_internal.h |  12 -
 drivers/misc/ocxl/trace.h |  34 ++-
 6 files changed, 368 insertions(+), 326 deletions(-)

diff --git a/arch/powerpc/include/asm/pnv-ocxl.h 
b/arch/powerpc/include/asm/pnv-ocxl.h
index 7de82647e761..8e516e339e6c 100644
--- a/arch/powerpc/include/asm/pnv-ocxl.h
+++ b/arch/powerpc/include/asm/pnv-ocxl.h
@@ -18,19 +18,22 @@ extern int pnv_ocxl_get_tl_cap(struct pci_dev *dev, long 
*cap,
 extern int pnv_ocxl_set_tl_conf(struct pci_dev *dev, long cap,
uint64_t rate_buf_phys, int rate_buf_size);
 
-extern int pnv_ocxl_get_xsl_irq(struct pci_dev *dev, int *hwirq);
-extern void pnv_ocxl_unmap_xsl_regs(void __iomem *dsisr, void __iomem *dar,
-   void __iomem *tfc, void __iomem *pe_handle);
-extern int pnv_ocxl_map_xsl_regs(struct pci_dev *dev, void __iomem **dsisr,
-   void __iomem **dar, void __iomem **tfc,
-   void __iomem **pe_handle);
-
-extern int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask,
-   void **platform_data);
-extern void pnv_ocxl_spa_release(void *platform_data);
-extern int pnv_ocxl_spa_remove_pe_from_cache(void *platform_data, int 
pe_handle);
+extern int pnv_ocxl_platform_setup(struct pci_dev *dev,
+  int PE_mask, int *hwirq,
+  void **platform_data);
+extern void pnv_ocxl_platform_release(void *platform_data);
+extern void pnv_ocxl_read_xsl_regs(void *platform_data, u64 *dsisr, u64 *dar,
+  u64 *pe, int *pid);
+extern void pnv_ocxl_write_xsl_tfc(void *platform_data, u64 tfc);
+extern int pnv_ocxl_remove_pe_from_cache(void *platform_data, int pe_handle);
 
 extern int pnv_ocxl_alloc_xive_irq(u32 *irq, u64 *trigger_addr);
 extern void pnv_ocxl_free_xive_irq(u32 irq);
+extern int pnv_ocxl_set_pe(void *platform_data, int lpid, int pasid,
+  u32 pidr, u32 tidr, u64 amr, int *pe_handle);
+extern int pnv_ocxl_update_pe(void *platform_data, int pasid, __u16 tid,
+ int *pe_handle);
+extern int pnv_ocxl_remove_pe(void *platform_data, int pasid, u32 *pid,
+ u32 *tid, int *pe_handle);
 
 #endif /* _ASM_PNV_OCXL_H */
diff --git a/arch/powerpc/platforms/powernv/ocxl.c 
b/arch/powerpc/platforms/powernv/ocxl.c
index 8c65aacda9c8..4d26cba12b63 100644
--- a/arch/powerpc/platforms/powernv/ocxl.c
+++ b/arch/powerpc/platforms/powernv/ocxl.c
@@ -12,11 +12,54 @@
 #define PNV_OCXL_PASID_BITS15
 #define PNV_OCXL_PASID_MAX ((1 << PNV_OCXL_PASID_BITS) - 1)
 
-#define AFU_PRESENT (1 << 31)
-#define AFU_INDEX_MASK 0x3F00
-#define AFU_INDEX_SHIFT 24
-#define ACTAG_MASK 0xFFF
+#define AFU_PRESENT(1 << 31)
+#define AFU_INDEX_MASK 0x3F00
+#define AFU_INDEX_SHIFT24
+#define ACTAG_MASK 0xFFF
+
+#define SPA_PASID_BITS 15
+#define SPA_PASID_MAX  ((1 << SPA_PASID_BITS) - 1)
+#define SPA_PE_MASKSPA_PASID_MAX
+#define SPA_SPA_SIZE_LOG   22 /* Each SPA is 4 Mb */
+#define SPA_PE_VALID   0x8000
+
+#define SPA_CFG_SF (1ull << (63-0))
+#define SPA_CFG_TA (1ull << (63-1))
+#define SPA_CFG_HV (1ull << (63-3))
+#define SPA_CFG_UV (1ull << (63-4))
+#define SPA_CFG_XLAT_hpt   (0ull << (63-6)) /* Hashed page table (HPT) 
mode */
+#define SPA_CFG_XLAT_roh   (2ull << (63-6)) /* Radix on HPT mode */
+#define SPA_CFG_XLAT_ror   (3ull << (63-6)) /* Radix on Radix mode */
+#define SPA_CFG_PR (1ull << (63-49))
+#define SPA_CFG_TC (1ull << (63-54))
+#define SPA_CFG_DR (1ull << (63-59))
+
+struct ocxl_process_element {
+   __be64 config_state;
+   __be32 reserved1[11];
+   __be32 lpid;
+   __be32 tid;
+   __be32 pid;
+   __be32 reserved2[10];
+   __be64 amr;
+   __be32 reserved3[3];
+   __be32 software_state;
+};
+
+struct spa {
+   struct ocxl_process_element *spa_mem;
+   int spa_order;
+};
 
+struct platform_data {
+   struct spa *spa;
+   u64 phb_opal_id;
+   u32 bdfn;
+   void __iomem *dsisr;
+   void __iomem *dar;
+   void __iomem *tfc;
+   void __iomem *pe_handle;