Patchwork [v2,1/2] PCI/ATS: Add pci_ats_page_aligned() interface

login
register
mail settings
Submitter sathyanarayanan.kuppuswamy@linux.intel.com
Date Feb. 11, 2019, 9:44 p.m.
Message ID <fbe54ba84d990a7637012b3e17fd58328d5804ad.1549920354.git.sathyanarayanan.kuppuswamy@linux.intel.com>
Download mbox | patch
Permalink /patch/723331/
State New
Headers show

Comments

From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

Return the Page Aligned Request bit in the ATS Capability Register.

As per PCIe spec r4.0, sec 10.5.1.2, If Page Aligned Request bit is
set, then it indicates the Untranslated Addresses generated by the
device are alwayis always aligned to a 4096 byte boundary.

This interface will be used by drivers like IOMMU, if it is required
to check whether the Untranslated Address generated by the device will
be aligned before enabling the ATS service.

Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
Cc: Keith Busch <keith.busch@intel.com>
Suggested-by: Ashok Raj <ashok.raj@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
---
 drivers/pci/ats.c             | 27 +++++++++++++++++++++++++++
 include/linux/pci.h           |  2 ++
 include/uapi/linux/pci_regs.h |  1 +
 3 files changed, 30 insertions(+)
Bjorn Helgaas - Feb. 13, 2019, 7:45 p.m.
On Mon, Feb 11, 2019 at 01:44:34PM -0800, sathyanarayanan.kuppuswamy@linux.intel.com wrote:
> From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> 
> Return the Page Aligned Request bit in the ATS Capability Register.
> 
> As per PCIe spec r4.0, sec 10.5.1.2, If Page Aligned Request bit is
> set, then it indicates the Untranslated Addresses generated by the
> device are alwayis always aligned to a 4096 byte boundary.

s/, If/, if the/
s/then it/it/
s/alwayis//

> This interface will be used by drivers like IOMMU, if it is required
> to check whether the Untranslated Address generated by the device will
> be aligned before enabling the ATS service.

Maybe something like this?

  An IOMMU that can only translate page-aligned addresses can only be used
  with devices that always produce aligned Untranslated Addresses.  This
  interface will be used by drivers for such IOMMUs to determine whether
  devices can use the ATS service.

> Cc: Ashok Raj <ashok.raj@intel.com>
> Cc: Jacob Pan <jacob.jun.pan@linux.intel.com>
> Cc: Keith Busch <keith.busch@intel.com>
> Suggested-by: Ashok Raj <ashok.raj@intel.com>
> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>

With typos addressed (more below),

Acked-by: Bjorn Helgaas <bhelgaas@google.com>

> ---
>  drivers/pci/ats.c             | 27 +++++++++++++++++++++++++++
>  include/linux/pci.h           |  2 ++
>  include/uapi/linux/pci_regs.h |  1 +
>  3 files changed, 30 insertions(+)
> 
> diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
> index 5b78f3b1b918..b3c7f1496081 100644
> --- a/drivers/pci/ats.c
> +++ b/drivers/pci/ats.c
> @@ -142,6 +142,33 @@ int pci_ats_queue_depth(struct pci_dev *dev)
>  }
>  EXPORT_SYMBOL_GPL(pci_ats_queue_depth);
>  
> +/**
> + * pci_ats_page_aligned - Return Page Aligned Request bit status.
> + * @pdev: the PCI device
> + *
> + * Returns 1, if Untranslated Addresses generated by the device are
> + * always aligned or 0 otherwise.
> + *
> + * Per PCIe spec r4.0, sec 10.5.1.2, If Page Aligned Request bit is
> + * set, it indicates the Untranslated Addresses generated by the
> + * device are always aligned to a 4096 byte boundary.

s/, If/, if the/

> + */
> +int pci_ats_page_aligned(struct pci_dev *pdev)
> +{
> +	u16 cap;
> +
> +	if (!pdev->ats_cap)
> +		return 0;
> +
> +	pci_read_config_word(pdev, pdev->ats_cap + PCI_ATS_CAP, &cap);
> +
> +	if (cap & PCI_ATS_CAP_PAGE_ALIGNED)
> +		return 1;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(pci_ats_page_aligned);
> +
>  #ifdef CONFIG_PCI_PRI
>  /**
>   * pci_enable_pri - Enable PRI capability
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 65f1d8c2f082..9724a8c0496b 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -1524,11 +1524,13 @@ void pci_ats_init(struct pci_dev *dev);
>  int pci_enable_ats(struct pci_dev *dev, int ps);
>  void pci_disable_ats(struct pci_dev *dev);
>  int pci_ats_queue_depth(struct pci_dev *dev);
> +int pci_ats_page_aligned(struct pci_dev *dev);
>  #else
>  static inline void pci_ats_init(struct pci_dev *d) { }
>  static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
>  static inline void pci_disable_ats(struct pci_dev *d) { }
>  static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
> +static inline int pci_ats_page_aligned(struct pci_dev *dev) { return 0; }
>  #endif
>  
>  #ifdef CONFIG_PCIE_PTM
> diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
> index e1e9888c85e6..7973bb02ed4b 100644
> --- a/include/uapi/linux/pci_regs.h
> +++ b/include/uapi/linux/pci_regs.h
> @@ -866,6 +866,7 @@
>  #define PCI_ATS_CAP		0x04	/* ATS Capability Register */
>  #define  PCI_ATS_CAP_QDEP(x)	((x) & 0x1f)	/* Invalidate Queue Depth */
>  #define  PCI_ATS_MAX_QDEP	32	/* Max Invalidate Queue Depth */
> +#define  PCI_ATS_CAP_PAGE_ALIGNED	0x0020 /* Page Aligned Request */
>  #define PCI_ATS_CTRL		0x06	/* ATS Control Register */
>  #define  PCI_ATS_CTRL_ENABLE	0x8000	/* ATS Enable */
>  #define  PCI_ATS_CTRL_STU(x)	((x) & 0x1f)	/* Smallest Translation Unit */
> -- 
> 2.20.1
>

Patch

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index 5b78f3b1b918..b3c7f1496081 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -142,6 +142,33 @@  int pci_ats_queue_depth(struct pci_dev *dev)
 }
 EXPORT_SYMBOL_GPL(pci_ats_queue_depth);
 
+/**
+ * pci_ats_page_aligned - Return Page Aligned Request bit status.
+ * @pdev: the PCI device
+ *
+ * Returns 1, if Untranslated Addresses generated by the device are
+ * always aligned or 0 otherwise.
+ *
+ * Per PCIe spec r4.0, sec 10.5.1.2, If Page Aligned Request bit is
+ * set, it indicates the Untranslated Addresses generated by the
+ * device are always aligned to a 4096 byte boundary.
+ */
+int pci_ats_page_aligned(struct pci_dev *pdev)
+{
+	u16 cap;
+
+	if (!pdev->ats_cap)
+		return 0;
+
+	pci_read_config_word(pdev, pdev->ats_cap + PCI_ATS_CAP, &cap);
+
+	if (cap & PCI_ATS_CAP_PAGE_ALIGNED)
+		return 1;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_ats_page_aligned);
+
 #ifdef CONFIG_PCI_PRI
 /**
  * pci_enable_pri - Enable PRI capability
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 65f1d8c2f082..9724a8c0496b 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1524,11 +1524,13 @@  void pci_ats_init(struct pci_dev *dev);
 int pci_enable_ats(struct pci_dev *dev, int ps);
 void pci_disable_ats(struct pci_dev *dev);
 int pci_ats_queue_depth(struct pci_dev *dev);
+int pci_ats_page_aligned(struct pci_dev *dev);
 #else
 static inline void pci_ats_init(struct pci_dev *d) { }
 static inline int pci_enable_ats(struct pci_dev *d, int ps) { return -ENODEV; }
 static inline void pci_disable_ats(struct pci_dev *d) { }
 static inline int pci_ats_queue_depth(struct pci_dev *d) { return -ENODEV; }
+static inline int pci_ats_page_aligned(struct pci_dev *dev) { return 0; }
 #endif
 
 #ifdef CONFIG_PCIE_PTM
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index e1e9888c85e6..7973bb02ed4b 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -866,6 +866,7 @@ 
 #define PCI_ATS_CAP		0x04	/* ATS Capability Register */
 #define  PCI_ATS_CAP_QDEP(x)	((x) & 0x1f)	/* Invalidate Queue Depth */
 #define  PCI_ATS_MAX_QDEP	32	/* Max Invalidate Queue Depth */
+#define  PCI_ATS_CAP_PAGE_ALIGNED	0x0020 /* Page Aligned Request */
 #define PCI_ATS_CTRL		0x06	/* ATS Control Register */
 #define  PCI_ATS_CTRL_ENABLE	0x8000	/* ATS Enable */
 #define  PCI_ATS_CTRL_STU(x)	((x) & 0x1f)	/* Smallest Translation Unit */