Re: [PATCH] iommu/amd: print out "tag" in INVALID_PPR_REQUEST

2019-05-07 Thread Gary R Hook
On 5/5/19 11:11 PM, Qian Cai wrote:
> [CAUTION: External Email]
> 
> The commit e7f63ffc1bf1 ("iommu/amd: Update logging information for new
> event type") introduced a variable "tag" but had never used it which
> generates a warning below,
> 
> drivers/iommu/amd_iommu.c: In function 'iommu_print_event':
> drivers/iommu/amd_iommu.c:567:33: warning: variable 'tag' set but not
> used [-Wunused-but-set-variable]
>int type, devid, pasid, flags, tag;
>   ^~~
> so just use it during the logging.
> 
> Signed-off-by: Qian Cai 
> ---
>   drivers/iommu/amd_iommu.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index f7cdd2ab7f11..52f41369c5b3 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -631,9 +631,9 @@ static void iommu_print_event(struct amd_iommu *iommu, 
> void *__evt)
>  pasid = ((event[0] >> 16) & 0x)
>  | ((event[1] << 6) & 0xF);
>  tag = event[1] & 0x03FF;
> -   dev_err(dev, "Event logged [INVALID_PPR_REQUEST 
> device=%02x:%02x.%x pasid=0x%05x address=0x%llx flags=0x%04x]\n",
> +   dev_err(dev, "Event logged [INVALID_PPR_REQUEST 
> device=%02x:%02x.%x pasid=0x%05x tag=0x%04x address=0x%llx flags=0x%04x]\n",
>  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
> -   pasid, address, flags);
> +   pasid, tag, address, flags);
>  break;
>  default:
>  dev_err(dev, "Event logged [UNKNOWN event[0]=0x%08x 
> event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n",

I did manage to overlook that variable when I posted the original patch. 
But it looks to me like 41e59a41fc5d1 (iommu tree) already fixed this... 
I'm not sure why it never got pushed to the main tree.

grh

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2] iommu/amd: Reserve exclusion range in iova-domain

2019-03-29 Thread Gary R Hook
On 3/29/19 10:10 AM, Joerg Roedel wrote:
> From: Joerg Roedel 
> 
> If a device has an exclusion range specified in the IVRS
> table, this region needs to be reserved in the iova-domain
> of that device. This hasn't happened until now and can cause
> data corruption on data transfered with these devices.
> 
> Treat exclusion ranges as reserved regions in the iommu-core
> to fix the problem.

Reviewed-by: Gary R Hook 

> 
> Fixes: be2a022c0dd0 ('x86, AMD IOMMU: add functions to parse IOMMU memory 
> mapping requirements for devices')
> Signed-off-by: Joerg Roedel 
> ---
>   drivers/iommu/amd_iommu.c   | 9 ++---
>   drivers/iommu/amd_iommu_init.c  | 7 ---
>   drivers/iommu/amd_iommu_types.h | 2 ++
>   3 files changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index 21cb088d6687..f7cdd2ab7f11 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -3169,21 +3169,24 @@ static void amd_iommu_get_resv_regions(struct device 
> *dev,
>   return;
>   
>   list_for_each_entry(entry, _iommu_unity_map, list) {
> + int type, prot = 0;
>   size_t length;
> - int prot = 0;
>   
>   if (devid < entry->devid_start || devid > entry->devid_end)
>   continue;
>   
> + type   = IOMMU_RESV_DIRECT;
>   length = entry->address_end - entry->address_start;
>   if (entry->prot & IOMMU_PROT_IR)
>   prot |= IOMMU_READ;
>   if (entry->prot & IOMMU_PROT_IW)
>   prot |= IOMMU_WRITE;
> + if (entry->prot & IOMMU_UNITY_MAP_FLAG_EXCL_RANGE)
> + /* Exclusion range */
> + type = IOMMU_RESV_RESERVED;
>   
>   region = iommu_alloc_resv_region(entry->address_start,
> -  length, prot,
> -  IOMMU_RESV_DIRECT);
> +  length, prot, type);
>   if (!region) {
>   dev_err(dev, "Out of memory allocating dm-regions\n");
>   return;
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index f773792d77fd..1b1378619fc9 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -2013,6 +2013,9 @@ static int __init init_unity_map_range(struct 
> ivmd_header *m)
>   if (e == NULL)
>   return -ENOMEM;
>   
> + if (m->flags & IVMD_FLAG_EXCL_RANGE)
> + init_exclusion_range(m);
> +
>   switch (m->type) {
>   default:
>   kfree(e);
> @@ -2059,9 +2062,7 @@ static int __init init_memory_definitions(struct 
> acpi_table_header *table)
>   
>   while (p < end) {
>   m = (struct ivmd_header *)p;
> - if (m->flags & IVMD_FLAG_EXCL_RANGE)
> - init_exclusion_range(m);
> - else if (m->flags & IVMD_FLAG_UNITY_MAP)
> + if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
>   init_unity_map_range(m);
>   
>   p += m->length;
> diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
> index eae0741f72dc..87965e4d9647 100644
> --- a/drivers/iommu/amd_iommu_types.h
> +++ b/drivers/iommu/amd_iommu_types.h
> @@ -374,6 +374,8 @@
>   #define IOMMU_PROT_IR 0x01
>   #define IOMMU_PROT_IW 0x02
>   
> +#define IOMMU_UNITY_MAP_FLAG_EXCL_RANGE  (1 << 2)
> +
>   /* IOMMU capabilities */
>   #define IOMMU_CAP_IOTLB   24
>   #define IOMMU_CAP_NPCACHE 26
> 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: Reserve exclusion range in iova-domain

2019-03-29 Thread Gary R Hook
On 3/29/19 9:51 AM, Joerg Roedel wrote:
> Hi Gary,
> 
> On Thu, Mar 28, 2019 at 02:52:19PM +0000, Gary R Hook wrote:
>> On 3/28/19 5:44 AM, Joerg Roedel wrote:
>>> +   if (entry->prot & (1 << 2))
>>
>> Could we add #define IOMMU_WRITE_EXCL (1 << 2) to amd_iommu_types.h?
> 
> Yes, I replace that magic number with a descriptive name.

Super; thanks.

>> The problem I see here is that if, for some untold reason, there is more
>> than one exclusion range emitted, where only the last one wins in the
>> hardware, we'd still end up with more than one range reserved in the
>> IOVA tree. Clearly, this is extremely unlikely, but wouldn't we want to
>> protect against that sort of misuse/mistake?
>>
>> I could be missing something.
> 
> No, you are not, this could still be a problem. Until now it isn't,
> because this week was the first time I have every seen an AMD IOMMU
> system making use of exclusion ranges, and it doesn't have this problem.
> 
> But this problem has been in the code even before this patch and needs
> to be addressed separatly. I think it is the best option to cancel IOMMU
> initialization when the IVRS table defines conflicting exclusion ranges
> for a single IOMMU instance.

Really? Interesting. May I ask who, as I've not seen it yet, either?

This change accomplishes the goal of setting exclusion + reserving the 
IOVA range, and is verified with testing? Cool. One wonders if they've 
considered a unity range?

Agree that addressing the uniqueness issue separately is fine. I'd 
probably prefer "first one wins" until IOVA tree clean-up could be 
implemented for "last one wins" but I'm seeing that there are at 
least two spots in the code that need attention. I may go experiment 
with this.

All told, this is really about handling a corner case, as the likelihood 
of a BIOS trying to set up >1 exclusion ranges seems improbable, if not 
impossible.


grh
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: Reserve exclusion range in iova-domain

2019-03-28 Thread Gary R Hook
On 3/28/19 5:44 AM, Joerg Roedel wrote:
> From: Joerg Roedel 
> 
> If a device has an exclusion range specified in the IVRS
> table, this region needs to be reserved in the iova-domain
> of that device. This hasn't happened until now and can cause
> data corruption on data transfered with these devices.
> 
> Treat exclusion ranges as reserved regions in the iommu-core
> to fix the problem.
> 
> Fixes: be2a022c0dd0 ('x86, AMD IOMMU: add functions to parse IOMMU memory 
> mapping requirements for devices')
> Signed-off-by: Joerg Roedel 
> ---
>   drivers/iommu/amd_iommu.c  | 9 ++---
>   drivers/iommu/amd_iommu_init.c | 7 ---
>   2 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
> index 21cb088d6687..2a8d2806d5b9 100644
> --- a/drivers/iommu/amd_iommu.c
> +++ b/drivers/iommu/amd_iommu.c
> @@ -3169,21 +3169,24 @@ static void amd_iommu_get_resv_regions(struct device 
> *dev,
>   return;
>   
>   list_for_each_entry(entry, _iommu_unity_map, list) {
> + int type, prot = 0;
>   size_t length;
> - int prot = 0;
>   
>   if (devid < entry->devid_start || devid > entry->devid_end)
>   continue;
>   
> + type   = IOMMU_RESV_DIRECT;
>   length = entry->address_end - entry->address_start;
>   if (entry->prot & IOMMU_PROT_IR)
>   prot |= IOMMU_READ;
>   if (entry->prot & IOMMU_PROT_IW)
>   prot |= IOMMU_WRITE;
> + if (entry->prot & (1 << 2))

Could we add
#define IOMMU_WRITE_EXCL (1 << 2)
to amd_iommu_types.h?

The bit is documented in the AMD IOMMU spec, so this seems safe...

> + /* Exclusion range */
> + type = IOMMU_RESV_RESERVED;
>   
>   region = iommu_alloc_resv_region(entry->address_start,
> -  length, prot,
> -  IOMMU_RESV_DIRECT);
> +  length, prot, type);
>   if (!region) {
>   dev_err(dev, "Out of memory allocating dm-regions\n");
>   return;
> diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
> index f773792d77fd..1b1378619fc9 100644
> --- a/drivers/iommu/amd_iommu_init.c
> +++ b/drivers/iommu/amd_iommu_init.c
> @@ -2013,6 +2013,9 @@ static int __init init_unity_map_range(struct 
> ivmd_header *m)
>   if (e == NULL)
>   return -ENOMEM;
>   
> + if (m->flags & IVMD_FLAG_EXCL_RANGE)
> + init_exclusion_range(m);
> +
>   switch (m->type) {
>   default:
>   kfree(e);
> @@ -2059,9 +2062,7 @@ static int __init init_memory_definitions(struct 
> acpi_table_header *table)
>   
>   while (p < end) {
>   m = (struct ivmd_header *)p;
> - if (m->flags & IVMD_FLAG_EXCL_RANGE)
> - init_exclusion_range(m);
> - else if (m->flags & IVMD_FLAG_UNITY_MAP)
> + if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
>   init_unity_map_range(m);
>   
>   p += m->length;
> 

The problem I see here is that if, for some untold reason, there is more 
than one exclusion range emitted, where only the last one wins in the 
hardware, we'd still end up with more than one range reserved in the 
IOVA tree. Clearly, this is extremely unlikely, but wouldn't we want to 
protect against that sort of misuse/mistake?

I could be missing something.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu: Fix IOMMU debugfs fallout

2019-02-21 Thread Gary R Hook
On 2/20/19 7:05 AM, Geert Uytterhoeven wrote:
> A change made in the final version of IOMMU debugfs support replaced the
> public function iommu_debugfs_new_driver_dir() by the public dentry
> iommu_debugfs_dir in , but forgot to update both the
> implementation in iommu-debugfs.c, and the patch description.
> 
> Fix this by exporting iommu_debugfs_dir, and removing the reference to
> and implementation of iommu_debugfs_new_driver_dir().
> 
> Fixes: bad614b24293ae46 ("iommu: Enable debugfs exposure of IOMMU driver 
> internals")
> Signed-off-by: Geert Uytterhoeven 

Acked-by: Gary R Hook 

> ---
>   drivers/iommu/iommu-debugfs.c | 23 ---
>   1 file changed, 4 insertions(+), 19 deletions(-)
> 
> diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
> index 3b1bf88fd1b0494a..f0354894209648fd 100644
> --- a/drivers/iommu/iommu-debugfs.c
> +++ b/drivers/iommu/iommu-debugfs.c
> @@ -12,6 +12,7 @@
>   #include 
>   
>   struct dentry *iommu_debugfs_dir;
> +EXPORT_SYMBOL_GPL(iommu_debugfs_dir);
>   
>   /**
>* iommu_debugfs_setup - create the top-level iommu directory in debugfs
> @@ -23,9 +24,9 @@ struct dentry *iommu_debugfs_dir;
>* Emit a strong warning at boot time to indicate that this feature is
>* enabled.
>*
> - * This function is called from iommu_init; drivers may then call
> - * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
> - * directory to be used to expose internal data.
> + * This function is called from iommu_init; drivers may then use
> + * iommu_debugfs_dir to instantiate a vendor-specific directory to be used
> + * to expose internal data.
>*/
>   void iommu_debugfs_setup(void)
>   {
> @@ -48,19 +49,3 @@ void iommu_debugfs_setup(void)
>   
> pr_warn("*\n");
>   }
>   }
> -
> -/**
> - * iommu_debugfs_new_driver_dir - create a vendor directory under 
> debugfs/iommu
> - * @vendor: name of the vendor-specific subdirectory to create
> - *
> - * This function is called by an IOMMU driver to create the top-level debugfs
> - * directory for that driver.
> - *
> - * Return: upon success, a pointer to the dentry for the new directory.
> - * NULL in case of failure.
> - */
> -struct dentry *iommu_debugfs_new_driver_dir(const char *vendor)
> -{
> - return debugfs_create_dir(vendor, iommu_debugfs_dir);
> -}
> -EXPORT_SYMBOL_GPL(iommu_debugfs_new_driver_dir);
> 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: fix missing tag from dev_err message

2018-07-03 Thread Gary R Hook

On 07/03/2018 05:07 AM, Joe Perches wrote:

On Tue, 2018-07-03 at 07:40 +0100, Colin King wrote:

Currently tag is being assigned but not used, it is missing from
the dev_err message, so add it in.

Cleans up clang warning:
warning: variable 'tag' set but not used [-Wunused-but-set-variable]

[]

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c

[]

@@ -616,9 +616,9 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
pasid = ((event[0] >> 16) & 0x)
| ((event[1] << 6) & 0xF);
tag = event[1] & 0x03FF;
-   dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x 
address=0x%016llx flags=0x%04x]\n",
+   dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x 
address=0x%016llx flags=0x%04x tag=0x%03x]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-   pasid, address, flags);
+   pasid, address, flags, tag);


Seems to have a superfluous ] that should be removed.


Yeah, I pretty much messed up all of the log messages in that function. 
My apologies. I'll create a patch for that problem; it shouldn't be 
fixed here.


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: fix missing tag from dev_err message

2018-07-03 Thread Gary R Hook

On 07/03/2018 01:40 AM, Colin King wrote:

From: Colin Ian King 

Currently tag is being assigned but not used, it is missing from
the dev_err message, so add it in.

Cleans up clang warning:
warning: variable 'tag' set but not used [-Wunused-but-set-variable]

Fixes: e7f63ffc1bf1 ("iommu/amd: Update logging information for new event type")
Signed-off-by: Colin Ian King 

---
This is a re-working of an earlier incorrect fix that I posted
yesterday ("iommu/amd: remove redundant variable tag")


Acked-by: Gary R Hook 



---
  drivers/iommu/amd_iommu.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 596b95c50051..6adab2690793 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -616,9 +616,9 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
pasid = ((event[0] >> 16) & 0x)
| ((event[1] << 6) & 0xF);
tag = event[1] & 0x03FF;
-   dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x 
address=0x%016llx flags=0x%04x]\n",
+   dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x 
address=0x%016llx flags=0x%04x tag=0x%03x]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-   pasid, address, flags);
+   pasid, address, flags, tag);
break;
default:
dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x 
event[2]=0x%08x event[3]=0x%08x\n",



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd: remove redundant variable tag

2018-07-02 Thread Gary R Hook

On 07/02/2018 11:37 AM, Colin King wrote:

From: Colin Ian King 

Variable tag is being assigned but is never used hence it is
redundant and can be removed.

Cleans up clang warning:
warning: variable 'tag' set but not used [-Wunused-but-set-variable]

Signed-off-by: Colin Ian King 
---
  drivers/iommu/amd_iommu.c | 3 +--
  1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 596b95c50051..c6aed1b088e9 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -547,7 +547,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 
domain_id,
  static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
  {
struct device *dev = iommu->iommu.dev;
-   int type, devid, pasid, flags, tag;
+   int type, devid, pasid, flags;
volatile u32 *event = __evt;
int count = 0;
u64 address;
@@ -615,7 +615,6 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
case EVENT_TYPE_INV_PPR_REQ:
pasid = ((event[0] >> 16) & 0x)
| ((event[1] << 6) & 0xF);
-   tag = event[1] & 0x03FF;
dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x pasid=0x%05x 
address=0x%016llx flags=0x%04x]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
pasid, address, flags);



If it's all the same to you, the intent was to print the tag as well. 
Could we add that to the message, rather than removing the variable, please?



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v9 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-06-12 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the AMD
IOMMU.  Add an AMD-specific Kconfig boolean that depends upon
general enablement of DebugFS in the IOMMU.

Signed-off-by: Gary R Hook 
---
 drivers/iommu/Kconfig |   12 
 drivers/iommu/Makefile|1 +
 drivers/iommu/amd_iommu_debugfs.c |   33 +
 drivers/iommu/amd_iommu_init.c|6 --
 drivers/iommu/amd_iommu_proto.h   |6 ++
 drivers/iommu/amd_iommu_types.h   |5 +
 6 files changed, 61 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f9af25ac409f..5a9cef113763 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -146,6 +146,18 @@ config AMD_IOMMU_V2
  hardware. Select this option if you want to use devices that support
  the PCI PRI and PASID interface.
 
+config AMD_IOMMU_DEBUGFS
+   bool "Enable AMD IOMMU internals in DebugFS"
+   depends on AMD_IOMMU && IOMMU_DEBUGFS
+   ---help---
+ !!!WARNING!!!  !!!WARNING!!!  !!!WARNING!!!  !!!WARNING!!!
+
+ DO NOT ENABLE THIS OPTION UNLESS YOU REALLY, -REALLY- KNOW WHAT YOU 
ARE DOING!!!
+ Exposes AMD IOMMU device internals in DebugFS.
+
+ This option is -NOT- intended for production environments, and should
+ not generally be enabled.
+
 # Intel IOMMU support
 config DMAR_TABLE
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..47fd6ea9de2d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..c6a5c737ef09
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs)
+   amd_iommu_debugfs = debugfs_create_dir("amd",
+  iommu_debugfs_dir);
+   mutex_unlock(_iommu_debugfs_lock);
+
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name, amd_iommu_debugfs);
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..a8cd0296fb16 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_AMD_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 986cbe0cc189..cfac9d842b0f 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -594,6 +594,11 @@ struct amd_iommu {
 
u32 flags;
volat

[PATCH v9 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-06-12 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook 
---
 drivers/iommu/Kconfig |   10 ++
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   66 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |7 
 5 files changed, 86 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c76157e57f6b..f9af25ac409f 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..3b1bf88fd1b0
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU debugfs core infrastructure
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+
+struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE**\n");
+   pr_warn("** 
**\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS 
KERNEL  **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** This means that this kernel is built to expose 
internal **\n");
+   pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+   pr_warn("** your system.
**\n");
+   pr_warn("** 
**\n");
+   pr_warn("** If you see this message and you are not debugging 
the   **\n");
+   pr_warn("** kernel, report this immediately to your vendor! 
**\n");
+   pr_warn("** 
**\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE**\n");
+   
pr_warn("*\n");
+   }
+}
+
+/**
+ * iommu_debugfs_new_driver_dir - create a vendor directory under debugfs/iommu
+ * @vendor: name of the vendor-speci

[PATCH v9 0/2] Base enablement of IOMMU debugfs support

2018-06-12 Thread Gary R Hook
These patches create a top-level function, called at IOMMU
initialization, to create a debugfs directory for the IOMMU.
Under this directory drivers may create and populate
vendor-specific directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow 
debugfs code to be built.

The Makefile structure is intended to allow the use of a single switch for 
turning on DebugFS.

Changes since v8:
 - Change Kconfig to use both an IOMMU boolean and a vendor-specific
   boolean; ensure big warning messages
 - Make the function that creates a vendor directory more concise

Changes since v7:
 - Change the Kconfig approach to use a hidden boolean for a
   specific device
 - Change some #ifdefs to reference the new boolean

Changes since v6:
 - Rely on default Kconfig value for a bool
 - comment/doc fixes
 - use const where appropriate
 - fix inline declaration

Changes since v5:
 - Added parameters names in declarations/definitions
 - Reformatted an inline definition

Changes since v4:
 - Guard vendor-specific debugfs files in the Makefile
 - Call top-level routine from iommu_init()
 - Add function for instantiating a driver-specific directory
 - Change AMD driver code to use this new format

Changes since v3:
 - Remove superfluous calls to debugfs_initialized()
 - Emit a warning exactly one time
 - Change the Kconfig name to IOMMU_DEBUGFS
 - Change the way debugfs modules are made

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of IOMMU driver internals
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   22 
 drivers/iommu/Makefile|2 +
 drivers/iommu/amd_iommu_debugfs.c |   33 +++
 drivers/iommu/amd_iommu_init.c|6 ++-
 drivers/iommu/amd_iommu_proto.h   |6 +++
 drivers/iommu/amd_iommu_types.h   |5 +++
 drivers/iommu/iommu-debugfs.c |   66 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |7 
 9 files changed, 147 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v8 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-06-12 Thread Gary R Hook

On 06/04/2018 08:23 PM, Randy Dunlap wrote:

On 05/29/2018 11:39 AM, Greg KH wrote:

On Tue, May 29, 2018 at 01:23:23PM -0500, Gary R Hook wrote:

Implement a skeleton framework for debugfs support in the
AMD IOMMU. Add a hidden boolean to Kconfig that is defined
for the AMD IOMMU when general IOMMY DebugFS support is
enabled.

Signed-off-by: Gary R Hook 
---
  drivers/iommu/Kconfig |4 
  drivers/iommu/Makefile|1 +
  drivers/iommu/amd_iommu_debugfs.c |   39 +
  drivers/iommu/amd_iommu_init.c|6 --
  drivers/iommu/amd_iommu_proto.h   |6 ++
  drivers/iommu/amd_iommu_types.h   |5 +
  6 files changed, 59 insertions(+), 2 deletions(-)
  create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f9af25ac409f..ec223f6f4ad4 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -137,6 +137,10 @@ config AMD_IOMMU
  your BIOS for an option to enable it or if you have an IVRS ACPI
  table.
  
+config AMD_IOMMU_DEBUGFS

+   def_bool y


Why default y?  Can you not boot a box without this?  If not, it should
not be Y.


+   depends on AMD_IOMMU && IOMMU_DEBUGFS
+
  config AMD_IOMMU_V2
tristate "AMD IOMMU Version 2 driver"
depends on AMD_IOMMU


Gary,

By far, most driver-debugfs additions are optional and include a user Kconfig 
prompt
so that user's can choose whether to enable it or not.

I suggest that the way forward is to fix Greg's debugfs_() api comments
and to add a prompt string to AMD_IOMMU_DEBUGFS.


Roger. I think we have that all worked out. Will send another version soon.

Thanks.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v8 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-06-12 Thread Gary R Hook

On 06/05/2018 12:08 PM, Greg KH wrote:

On Tue, Jun 05, 2018 at 12:01:41PM -0500, Gary R Hook wrote:

+/**
+ * iommu_debugfs_new_driver_dir - create a vendor directory under debugfs/iommu
+ * @vendor: name of the vendor-specific subdirectory to create
+ *
+ * This function is called by an IOMMU driver to create the top-level debugfs
+ * directory for that driver.
+ *
+ * Return: upon success, a pointer to the dentry for the new directory.
+ * NULL in case of failure.
+ */
+struct dentry *iommu_debugfs_new_driver_dir(const char *vendor)
+{
+   struct dentry *d_new;
+
+   d_new = debugfs_create_dir(vendor, iommu_debugfs_dir);
+
+   return d_new;
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_new_driver_dir);


Why are you wrapping a debugfs call?  Why not just export
iommu_debugfs_dir instead?


It was a choice, as I stated in my other post. It is not a requirement.
If you resolutely reject this approach, that's fine. I'll change it, no
worries.


Either is fine, but if it stays, it should stay a single line function
:)

thanks,

greg k-h



Then I shall leave it as a black-box function. Single line, of course.

Thank you.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v8 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-06-12 Thread Gary R Hook

On 06/05/2018 12:06 PM, Greg KH wrote:

On Tue, Jun 05, 2018 at 11:58:13AM -0500, Gary R Hook wrote:

On 05/29/2018 01:39 PM, Greg KH wrote:

On Tue, May 29, 2018 at 01:23:23PM -0500, Gary R Hook wrote:

Implement a skeleton framework for debugfs support in the
AMD IOMMU. Add a hidden boolean to Kconfig that is defined
for the AMD IOMMU when general IOMMY DebugFS support is
enabled.

Signed-off-by: Gary R Hook 
---
   drivers/iommu/Kconfig |4 
   drivers/iommu/Makefile|1 +
   drivers/iommu/amd_iommu_debugfs.c |   39 
+
   drivers/iommu/amd_iommu_init.c|6 --
   drivers/iommu/amd_iommu_proto.h   |6 ++
   drivers/iommu/amd_iommu_types.h   |5 +
   6 files changed, 59 insertions(+), 2 deletions(-)
   create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f9af25ac409f..ec223f6f4ad4 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -137,6 +137,10 @@ config AMD_IOMMU
  your BIOS for an option to enable it or if you have an IVRS ACPI
  table.
+config AMD_IOMMU_DEBUGFS
+   def_bool y


Why default y?  Can you not boot a box without this?  If not, it should
not be Y.


Again, apologies for not seeing this sooner.

Yes, the system can boot without this. The idea of a hidden option was
surfaced by Robin, and after my first approach was shot down, I tried this.

Logic: If the over-arching IOMMU debugfs option is enabled, then
AMD_IOMMU_DEBUGFS gets defined, and AMD IOMMU code gets included.

This issue was discussed a few weeks ago. No single approach appears to
satisfy everyone. I like this because it depends upon one switch: Do you
want DebugFS support enabled in the IOMMU driver, period? Vendor-specific
code can then choose to implement support or not, and a builder doesn't have
to worry about enabling/disabling multiple Kconfig options.

At least, that was my line of reasoning.

I'm not married to any approach, and I don't find clever use of Kconfig
options too terribly challenging. And I'm not defending, I'm just
explaining.


The issue is, no one sets Kconfig options except a very tiny subset of
kernel developers.  Distros allways enable everything, as they have to
do that.

If you are creating something here that is so dangerous that you spam
the kernel log with big warning messages, you should not be making it
easy to enable, let alone be enabled by default :)


Okay, I get that. Totally understand.


Just make it an option, have it rely on the kernel debugging option, and
say "DO NOT ENABLE THIS UNLESS YOU REALLY REALLY REALLY KNOW WHAT YOU
ARE DOING!"


Nah, Randy voted for separate options per device, on top of the IOMMU 
option. So I'll go with that. With loud messages, of course.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v8 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-06-05 Thread Gary R Hook

On 05/29/2018 01:41 PM, Greg KH wrote:

On Tue, May 29, 2018 at 01:23:14PM -0500, Gary R Hook wrote:

Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook 
---
  drivers/iommu/Kconfig |   10 ++
  drivers/iommu/Makefile|1 +
  drivers/iommu/iommu-debugfs.c |   72 +
  drivers/iommu/iommu.c |2 +
  include/linux/iommu.h |   11 ++
  5 files changed, 96 insertions(+)
  create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c76157e57f6b..f9af25ac409f 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
  
  endmenu
  
+config IOMMU_DEBUGFS

+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.


You didn't put a big enough warning here, like I asked last time :(


As I noted a few moments ago, I didn't see these until now. Very 
annoying, that.





+
  config IOMMU_IOVA
tristate
  
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile

index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
  obj-$(CONFIG_IOMMU_API) += iommu.o
  obj-$(CONFIG_IOMMU_API) += iommu-traces.o
  obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
  obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..bb1bf2d0ac51
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU debugfs core infrastructure
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir) {


Again, no, never test a return value from a debugfs call.  You do not
care, you should do the same exact thing if it is enabled or disabled or
somehow failing.  Just keep moving on.


Yes, noted.




+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE**\n");
+   pr_warn("**  
   **\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS 
KERNEL  **\n");
+   pr_warn("**  
   **\n");
+   pr_warn("** This means that this kernel is built to expose 
internal **\n");
+   pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+   pr_warn("** your system. 
   **\n");
+   pr_warn("**  
   **\n");
+   pr_warn("

Re: [PATCH v8 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-06-05 Thread Gary R Hook

On 05/29/2018 01:39 PM, Greg KH wrote:

On Tue, May 29, 2018 at 01:23:23PM -0500, Gary R Hook wrote:

Implement a skeleton framework for debugfs support in the
AMD IOMMU. Add a hidden boolean to Kconfig that is defined
for the AMD IOMMU when general IOMMY DebugFS support is
enabled.

Signed-off-by: Gary R Hook 
---
  drivers/iommu/Kconfig |4 
  drivers/iommu/Makefile|1 +
  drivers/iommu/amd_iommu_debugfs.c |   39 +
  drivers/iommu/amd_iommu_init.c|6 --
  drivers/iommu/amd_iommu_proto.h   |6 ++
  drivers/iommu/amd_iommu_types.h   |5 +
  6 files changed, 59 insertions(+), 2 deletions(-)
  create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f9af25ac409f..ec223f6f4ad4 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -137,6 +137,10 @@ config AMD_IOMMU
  your BIOS for an option to enable it or if you have an IVRS ACPI
  table.
  
+config AMD_IOMMU_DEBUGFS

+   def_bool y


Why default y?  Can you not boot a box without this?  If not, it should
not be Y.


Again, apologies for not seeing this sooner.

Yes, the system can boot without this. The idea of a hidden option was 
surfaced by Robin, and after my first approach was shot down, I tried this.


Logic: If the over-arching IOMMU debugfs option is enabled, then 
AMD_IOMMU_DEBUGFS gets defined, and AMD IOMMU code gets included.


This issue was discussed a few weeks ago. No single approach appears to 
satisfy everyone. I like this because it depends upon one switch: Do you 
want DebugFS support enabled in the IOMMU driver, period? 
Vendor-specific code can then choose to implement support or not, and a 
builder doesn't have to worry about enabling/disabling multiple Kconfig 
options.


At least, that was my line of reasoning.

I'm not married to any approach, and I don't find clever use of Kconfig 
options too terribly challenging. And I'm not defending, I'm just 
explaining.







+   depends on AMD_IOMMU && IOMMU_DEBUGFS
+
  config AMD_IOMMU_V2
tristate "AMD IOMMU Version 2 driver"
depends on AMD_IOMMU
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..47fd6ea9de2d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
  obj-$(CONFIG_OF_IOMMU)+= of_iommu.o
  obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
  obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
  obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
  obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
  obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..6dff98552969
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs)
+   amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd");
+   mutex_unlock(_iommu_debugfs_lock);
+
+   if (amd_iommu_debugfs) {


Do not test this.


Okay, noted. I'll stop worrying about this.




+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {


No, you don't care about the return value of any debugfs call.  Just
save the directory and move on.  If it's not correct, find, nothing is
wrong, just keep going.


Roger.

Thank you,
Gary
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v7 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-06-05 Thread Gary R Hook

On 05/24/2018 04:18 AM, Greg KH wrote:

On Mon, May 14, 2018 at 12:20:20PM -0500, Gary R Hook wrote:

Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook 
---
  drivers/iommu/Kconfig |   10 ++
  drivers/iommu/Makefile|1 +
  drivers/iommu/iommu-debugfs.c |   72 +
  drivers/iommu/iommu.c |2 +
  include/linux/iommu.h |   11 ++
  5 files changed, 96 insertions(+)
  create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..2eab6a849a0a 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
  
  endmenu
  
+config IOMMU_DEBUGFS

+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.


You need a big "DO NOT ENABLE THIS OPTION UNLESS YOU REALLY REALLY KNOW
WHAT YOU ARE DOING!!!" line here.  To match up with your crazy kernel
log warning.

Otherwise distros will turn this on, I guarantee it.


Apologies for not seeing this. Notes from Greg have been going to junk 
mail >:-(


I will add this text to the Kconfig item.




+
  config IOMMU_IOVA
tristate
  
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile

index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
  obj-$(CONFIG_IOMMU_API) += iommu.o
  obj-$(CONFIG_IOMMU_API) += iommu-traces.o
  obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
  obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..bb1bf2d0ac51
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU debugfs core infrastructure
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir) {


No need to care about the return value, just keep going.  Nothing you
should, or should not, do depending on the return value of a debugfs
call.


Sorry. Some habits are hard to break. It just seemed that if there's no 
iommu debugfs directory, nothing else needed to be done. But plowing 
ahead works for me. Thank you.





+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE**\n");
+   pr_warn("**  
   **\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS 
KERNEL  **\n");
+   pr_warn("**  
   **\n");
+   pr_warn("** This means that this kernel is built to expose 
internal **\n");
+   pr_warn(&qu

[PATCH v8 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-29 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU. Add a hidden boolean to Kconfig that is defined
for the AMD IOMMU when general IOMMY DebugFS support is
enabled.

Signed-off-by: Gary R Hook 
---
 drivers/iommu/Kconfig |4 
 drivers/iommu/Makefile|1 +
 drivers/iommu/amd_iommu_debugfs.c |   39 +
 drivers/iommu/amd_iommu_init.c|6 --
 drivers/iommu/amd_iommu_proto.h   |6 ++
 drivers/iommu/amd_iommu_types.h   |5 +
 6 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f9af25ac409f..ec223f6f4ad4 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -137,6 +137,10 @@ config AMD_IOMMU
  your BIOS for an option to enable it or if you have an IVRS ACPI
  table.
 
+config AMD_IOMMU_DEBUGFS
+   def_bool y
+   depends on AMD_IOMMU && IOMMU_DEBUGFS
+
 config AMD_IOMMU_V2
tristate "AMD IOMMU Version 2 driver"
depends on AMD_IOMMU
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..47fd6ea9de2d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..6dff98552969
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs)
+   amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd");
+   mutex_unlock(_iommu_debugfs_lock);
+
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..a8cd0296fb16 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_AMD_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 986cbe0cc189..cfac9d842b0f 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -594,6 +594,11 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+#ifdef CONFIG_AMD_IOMMU_DEBUGFS
+   /* DebugFS Info */
+   struct dentry *debugfs;
+#endif
 };
 
 

[PATCH v8 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-29 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook 
---
 drivers/iommu/Kconfig |   10 ++
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   72 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |   11 ++
 5 files changed, 96 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index c76157e57f6b..f9af25ac409f 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..bb1bf2d0ac51
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU debugfs core infrastructure
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook 
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir) {
+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   pr_warn("** 
**\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL  **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** This means that this kernel is built to 
expose internal **\n");
+   pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+   pr_warn("** your system.
**\n");
+   pr_warn("** 
**\n");
+   pr_warn("** If you see this message and you are not 
debugging the   **\n");
+   pr_warn("** kernel, report this immediately to your 
vendor! **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   
pr_warn("**

[PATCH v8 0/2] Base enablement of IOMMU debugfs support

2018-05-29 Thread Gary R Hook
These patches create a top-level function, called at IOMMU
initialization, to create a debugfs directory for the IOMMU. Under
this directory drivers may create and populate vendor-specific
directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally
allow/disallow debugfs code to be built.

The Makefile structure is intended to allow the use of a single
switch for turning on DebugFS.

Changes since v7:
 - Change the Kconfig approach to use a hidden boolean for a
   specific device
 - Change some #ifdefs to reference the new boolean

Changes since v6:
 - Rely on default Kconfig value for a bool
 - comment/doc fixes
 - use const where appropriate
 - fix inline declaration

Changes since v5:
 - Added parameters names in declarations/definitions
 - Reformatted an inline definition

Changes since v4:
 - Guard vendor-specific debugfs files in the Makefile
 - Call top-level routine from iommu_init()
 - Add function for instantiating a driver-specific directory
 - Change AMD driver code to use this new format

Changes since v3:
 - Remove superfluous calls to debugfs_initialized()
 - Emit a warning exactly one time
 - Change the Kconfig name to IOMMU_DEBUGFS
 - Change the way debugfs modules are made

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of IOMMU driver internals
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   14 +++
 drivers/iommu/Makefile|2 +
 drivers/iommu/amd_iommu_debugfs.c |   39 
 drivers/iommu/amd_iommu_init.c|6 ++-
 drivers/iommu/amd_iommu_proto.h   |6 +++
 drivers/iommu/amd_iommu_types.h   |5 +++
 drivers/iommu/iommu-debugfs.c |   72 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |   11 ++
 9 files changed, 155 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
Signature
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd - Optimize PPR log handling

2018-05-29 Thread Gary R Hook

On 05/29/2018 09:54 AM, Joerg Roedel wrote:

Hey Gary,

On Fri, May 18, 2018 at 04:51:56PM -0500, Gary R Hook wrote:

Improve the performance of the PPR log polling function (i.e. the
task of emptying the log) by minimizing MMIO operations and more
efficiently processing groups of log entries. Cache the head
pointer, as there's never a reason to read it. Ensure the head
pointer register is updated every so often, to inform the IOMMU
that space is available in the log.

Finally, since a single pass may leave logged events unread, use
an outer loop to repeat until head has caught up to tail.

Signed-off-by: Gary R Hook 


Do you have numbers for the performance improvement? How did you test
this patch?


No, no numbers. We're still working out how best to test this, and 
suggestions/strategies are welcome.


The change is modeled after the function iommu_poll_events(), which is 
much cleaner. The GA log handling should be changed, as well (there are 
superfluous writes in the loop), but I figured, "one thing at a time". 
This is admittedly a minor optimization, but discussions with Tom 
Lendacky have led us down this path.


Your feedback is appreciated.

Gary

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-24 Thread Gary R Hook

On 05/18/2018 04:02 PM, Gary R Hook wrote:

On 05/18/2018 11:49 AM, Randy Dunlap wrote:

I think the Kconfig option would have been the correct choice.


"Preferred", perhaps. Neither is incorrect. And really, the 
Makefile/Kconfig choice is somewhat separate from the organization issue.


So I've made the changes for this. Now I'm waiting on Joerg to make a 
decision on the code/file organization. I still prefer a separate file 
for the debug fs code.


Joerg:

*poke*

Any thoughts on this?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu/amd - Optimize PPR log handling

2018-05-18 Thread Gary R Hook
Improve the performance of the PPR log polling function (i.e. the
task of emptying the log) by minimizing MMIO operations and more
efficiently processing groups of log entries. Cache the head
pointer, as there's never a reason to read it. Ensure the head
pointer register is updated every so often, to inform the IOMMU
that space is available in the log.

Finally, since a single pass may leave logged events unread, use
an outer loop to repeat until head has caught up to tail.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c   |   69 +--
 drivers/iommu/amd_iommu_init.c  |1 +
 drivers/iommu/amd_iommu_types.h |1 +
 3 files changed, 39 insertions(+), 32 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 77c056ae082c..13a550fb7d47 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -660,51 +660,56 @@ static void iommu_handle_ppr_entry(struct amd_iommu 
*iommu, u64 *raw)
 
 static void iommu_poll_ppr_log(struct amd_iommu *iommu)
 {
-   u32 head, tail;
+   u32 tail;
 
if (iommu->ppr_log == NULL)
return;
 
-   head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
 
-   while (head != tail) {
-   volatile u64 *raw;
-   u64 entry[2];
-   int i;
+   while (iommu->ppr_log_head != tail) {
+   uint count = PPR_LOG_ENTRIES / 8;
+
+   while (iommu->ppr_log_head != tail && count--) {
+   volatile u64 *raw;
+   u64 entry[2];
+   int i;
+
+   raw = (u64 *)(iommu->ppr_log + iommu->ppr_log_head);
+
+   /*
+* Hardware bug: Interrupt may arrive before the
+* entry is written to memory. If this happens we
+* need to wait for the entry to arrive.
+*/
+   for (i = 0; i < LOOP_TIMEOUT; ++i) {
+   if (PPR_REQ_TYPE(raw[0]) != 0)
+   break;
+   udelay(1);
+   }
 
-   raw = (u64 *)(iommu->ppr_log + head);
+   /* Avoid memcpy function-call overhead */
+   entry[0] = raw[0];
+   entry[1] = raw[1];
 
-   /*
-* Hardware bug: Interrupt may arrive before the entry is
-* written to memory. If this happens we need to wait for the
-* entry to arrive.
-*/
-   for (i = 0; i < LOOP_TIMEOUT; ++i) {
-   if (PPR_REQ_TYPE(raw[0]) != 0)
-   break;
-   udelay(1);
-   }
+   /*
+* To detect the hardware bug we need to clear the
+* entry back to zero.
+*/
+   raw[0] = raw[1] = 0UL;
 
-   /* Avoid memcpy function-call overhead */
-   entry[0] = raw[0];
-   entry[1] = raw[1];
+   /* Handle PPR entry */
+   iommu_handle_ppr_entry(iommu, entry);
 
-   /*
-* To detect the hardware bug we need to clear the entry
-* back to zero.
-*/
-   raw[0] = raw[1] = 0UL;
+   iommu->ppr_log_head += PPR_ENTRY_SIZE;
+   iommu->ppr_log_head %= PPR_LOG_SIZE;
+   }
 
/* Update head pointer of hardware ring-buffer */
-   head = (head + PPR_ENTRY_SIZE) % PPR_LOG_SIZE;
-   writel(head, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
-
-   /* Handle PPR entry */
-   iommu_handle_ppr_entry(iommu, entry);
+   writel(iommu->ppr_log_head,
+  iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
 
-   /* Refresh ring-buffer information */
-   head = readl(iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
+   /* Get the current value of tail */
tail = readl(iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
}
 }
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..227a9887feb1 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -721,6 +721,7 @@ static void iommu_enable_ppr_log(struct amd_iommu *iommu)
/* set head and tail to zero manually */
writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
+   iommu->ppr_log_head = 0;
 
iommu_feature_enable(iommu, CONTROL_PPFLOG_EN);

Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-18 Thread Gary R Hook

On 05/18/2018 11:49 AM, Randy Dunlap wrote:

On 05/18/2018 08:20 AM, Gary R Hook wrote:

On 05/15/2018 08:46 AM, Joerg Roedel wrote:

On Mon, May 14, 2018 at 03:00:50PM -0500, Gary R Hook wrote:

This was brought up a few weeks ago in, I believe, version 3 of this patch.
That question was discussed (because that's what I did the first time out),
and _someone_ _else_ asked about why I didn't just do it the way I've done
it here.


You don't have this problem if you put the code in amd_iommu.c in an
IOMMU_DEBUGFS ifdef.


Of course. My preference, however, is a separate file to avoid size creep. 
That's why I've done it this way.

To whit: there have been threads discussing the advisability/acceptability of 
using #ifdefs for debug code. My take-away was to avoid them. Perhaps I 
misunderstood.

So: I don't understand your comment. Is this an observation, or is it an 
imperative statement? I'd like for a maintainer to clearly indicate what is 
acceptable, and I'll do it.




Hi,
I looked back at Robin Murphy's comments on April 17:


Well, you could do a makefile-level dependency i.e.:

ifeq ($(CONFIG_IOMMU_DEBUG), y)
obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o
obj-$(CONFIG_BLAH_IOMMU) += blah_iommu_debugfs.o
...
endif

Or alternatively have an intermediate silent Kconfig option:

config AMD_IOMMU_DEBUG
def_bool y
depends on AMD_IOMMU && IOMMU_DEBUG

The makefile option is arguably ugly, but does at least scale better ;)



I think the Kconfig option would have been the correct choice.


"Preferred", perhaps. Neither is incorrect. And really, the 
Makefile/Kconfig choice is somewhat separate from the organization issue.


So I've made the changes for this. Now I'm waiting on Joerg to make a 
decision on the code/file organization. I still prefer a separate file 
for the debug fs code.


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-18 Thread Gary R Hook

On 05/15/2018 08:46 AM, Joerg Roedel wrote:

On Mon, May 14, 2018 at 03:00:50PM -0500, Gary R Hook wrote:

This was brought up a few weeks ago in, I believe, version 3 of this patch.
That question was discussed (because that's what I did the first time out),
and _someone_ _else_ asked about why I didn't just do it the way I've done
it here.


You don't have this problem if you put the code in amd_iommu.c in an
IOMMU_DEBUGFS ifdef.


Of course. My preference, however, is a separate file to avoid size 
creep. That's why I've done it this way.


To whit: there have been threads discussing the 
advisability/acceptability of using #ifdefs for debug code. My take-away 
was to avoid them. Perhaps I misunderstood.


So: I don't understand your comment. Is this an observation, or is it an 
imperative statement? I'd like for a maintainer to clearly indicate what 
is acceptable, and I'll do it.


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-14 Thread Gary R Hook

On 05/14/2018 12:50 PM, Randy Dunlap wrote:

On 05/14/2018 10:20 AM, Gary R Hook wrote:

Implement a skeleton framework for debugfs support in the
AMD IOMMU.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/Makefile|5 +
  drivers/iommu/amd_iommu_debugfs.c |   39 +
  drivers/iommu/amd_iommu_init.c|6 --
  drivers/iommu/amd_iommu_proto.h   |6 ++
  drivers/iommu/amd_iommu_types.h   |3 +++
  5 files changed, 57 insertions(+), 2 deletions(-)
  create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..dd980f7dd8b6 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
  obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
  obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
  obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+
+# This ensures that only the required files are compiled
+ifeq ($(CONFIG_IOMMU_DEBUGFS), y)


Most Makefiles don't use a space before the 'y', but since you tested it,
I guess either way works.


Pretty sure whitespace isn't used as a delimiter in this construct. I 
could be mistaken. But yes, it's perfectly serviceable.



But why do this in the Makefile at all?  Why not just add another Kconfig
symbol and simplify the Makefile?


+obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o
+endif



This was brought up a few weeks ago in, I believe, version 3 of this 
patch. That question was discussed (because that's what I did the first 
time out), and _someone_ _else_ asked about why I didn't just do it the 
way I've done it here.


Everyone has a preference.

I chose to simplify the choices and avoid multiple symbols, instead 
opting for two switches: choose your device, and decide on Debug FS 
enablement for it. IMO Very simple.


I can't fathom a scenario where this wouldn't work. Is there one?
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v7 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-14 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Makefile|5 +
 drivers/iommu/amd_iommu_debugfs.c |   39 +
 drivers/iommu/amd_iommu_init.c|6 --
 drivers/iommu/amd_iommu_proto.h   |6 ++
 drivers/iommu/amd_iommu_types.h   |3 +++
 5 files changed, 57 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..dd980f7dd8b6 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+
+# This ensures that only the required files are compiled
+ifeq ($(CONFIG_IOMMU_DEBUGFS), y)
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o
+endif
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..6dff98552969
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs)
+   amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd");
+   mutex_unlock(_iommu_debugfs_lock);
+
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..39053f11dda3 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 1c9b080276c9..2ca0959ae9e6 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -593,6 +593,9 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+   /* DebugFS Info */
+   struct dentry *debugfs;
 };
 
 static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v7 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-14 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |   10 ++
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   72 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |   11 ++
 5 files changed, 96 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..2eab6a849a0a 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,16 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..bb1bf2d0ac51
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU debugfs core infrastructure
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir) {
+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   pr_warn("** 
**\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL  **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** This means that this kernel is built to 
expose internal **\n");
+   pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+   pr_warn("** your system.
**\n");
+   pr_warn("** 
**\n");
+   pr_warn("** If you see this message and you are not 
debugging the   **\n");
+   pr_warn("** kernel, report this immediately to your 
vendor! **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   
pr_war

[PATCH v7 0/2] Base enablement of IOMMU debugfs support

2018-05-14 Thread Gary R Hook
These patches create a top-level function, called at IOMMU
initialization, to create a debugfs directory for the IOMMU. Under
this directory drivers may create and populate-specific directories
for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally
allow/disallow debugfs code to be built.

The Makefile structure is intended to allow the use of a single
switch for turning on DebugFS.

Changes since v6:
 - Rely on default Kconfig value for a bool
 - comment/doc fixes
 - use const where appropriate
 - fix inline declaration

Changes since v5:
 - Added parameters names in declarations/definitions
 - Reformatted an inline definition

Changes since v4:
 - Guard vendor-specific debugfs files in the Makefile
 - Call top-level routine from iommu_init()
 - Add function for instantiating a driver-specific directory
 - Change AMD driver code to use this new format

Changes since v3:
 - Remove superfluous calls to debugfs_initialized()
 - Emit a warning exactly one time
 - Change the Kconfig name to IOMMU_DEBUGFS
 - Change the way debugfs modules are made

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of IOMMU driver internals
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   10 +
 drivers/iommu/Makefile|6 +++
 drivers/iommu/amd_iommu_debugfs.c |   39 
 drivers/iommu/amd_iommu_init.c|6 ++-
 drivers/iommu/amd_iommu_proto.h   |6 +++
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   72 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |   11 ++
 9 files changed, 153 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v6 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-11 Thread Gary R Hook

On 05/11/2018 10:22 AM, Robin Murphy wrote:

Hi Gary,

Just a few trivial nitpicks below, otherwise:

Reviewed-by: Robin Murphy <robin.mur...@arm.com>

On 11/05/18 15:34, Gary R Hook wrote:

Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/Kconfig |   11 ++
  drivers/iommu/Makefile    |    1 +
  drivers/iommu/iommu-debugfs.c |   70 
+

  drivers/iommu/iommu.c |    2 +
  include/linux/iommu.h |   10 ++
  5 files changed, 94 insertions(+)
  create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..ff511fa8ca7d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
  endmenu
+config IOMMU_DEBUGFS
+    bool "Export IOMMU internals in DebugFS"
+    depends on DEBUG_FS
+    default n


bool implicitly defaults to n anyway, so you don't really need to say it.


Roger.




+    help
+  Allows exposure of IOMMU device internals. This option enables
+  the use of debugfs by IOMMU drivers as required. Devices can,
+  at initialization time, cause the IOMMU code to create a top-level
+  debug/iommu directory, and then populate a subdirectory with
+  entries as required.
+
  config IOMMU_IOVA
  tristate
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
  obj-$(CONFIG_IOMMU_API) += iommu.o
  obj-$(CONFIG_IOMMU_API) += iommu-traces.o
  obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
  obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c 
b/drivers/iommu/iommu-debugfs.c

new file mode 100644
index ..9df3b44aef55
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU driver


"driver"? ;) I'd have thought something like "IOMMU debugfs core 
infrastructure", but arguably it's self-evident enough that it doesn't 
necessarily need describing at all.


Changed to your suggestion




+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data 
of an

+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+    if (!iommu_debugfs_dir) {
+    iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+    if (iommu_debugfs_dir) {
+    pr_warn("\n");
+
pr_warn("*\n"); 

+    pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE    **\n");
+
pr_warn("** 
**\n");
+    pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL  **\n");
+
pr_warn("** 
**\n");
+    pr_warn("** This means that this kernel is built to 
expose internal **\n");
+    pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+    pr_warn("** your 
system.    **\n");
+
pr_warn("** 
**\n");
+    pr_warn("** If you see this message and you are not 
debugging the   **\n");

[PATCH v6 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-11 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Makefile|5 +
 drivers/iommu/amd_iommu_debugfs.c |   39 +
 drivers/iommu/amd_iommu_init.c|6 --
 drivers/iommu/amd_iommu_proto.h   |6 ++
 drivers/iommu/amd_iommu_types.h   |3 +++
 5 files changed, 57 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..dd980f7dd8b6 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+
+# This ensures that only the required files are compiled
+ifeq ($(CONFIG_IOMMU_DEBUGFS), y)
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o
+endif
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..6dff98552969
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs)
+   amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd");
+   mutex_unlock(_iommu_debugfs_lock);
+
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..39053f11dda3 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 1c9b080276c9..2ca0959ae9e6 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -593,6 +593,9 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+   /* DebugFS Info */
+   struct dentry *debugfs;
 };
 
 static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v6 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-11 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |   11 ++
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   70 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |   10 ++
 5 files changed, 94 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..ff511fa8ca7d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..9df3b44aef55
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/**
+ * iommu_debugfs_setup - create the top-level iommu directory in debugfs
+ *
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, this function creates the
+ * /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init; drivers may then call
+ * iommu_debugfs_new_driver_dir() to instantiate a vendor-specific
+ * directory to be used to expose internal data.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir) {
+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   pr_warn("** 
**\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL  **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** This means that this kernel is built to 
expose internal **\n");
+   pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+   pr_warn("** your system.
**\n");
+   pr_warn("** 
**\n");
+   pr_warn("** If you see this message and you are not 
debugging the   **\n");
+   pr_warn("** kernel, report this immediately to your 
vendor! **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   
pr_war

[PATCH v6 0/2] Base enablement of IOMMU debugfs support

2018-05-11 Thread Gary R Hook
These patches create a top-level function, called at IOMMU initialization,
to create a debugfs directory for the IOMMU. Under this directory drivers
may create and populate-specific directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow
debugfs code to be built.

The Makefile structure is intended to allow the use of a single switch for
turning on DebugFS.

Changes since v5:
 - Added parameters names in declarations/definitions
 - Reformatted an inline definition

Changes since v4:
 - Guard vendor-specific debugfs files in the Makefile
 - Call top-level routine from iommu_init()
 - Add function for instantiating a driver-specific directory
 - Change AMD driver code to use this new format

Changes since v3:
 - Remove superfluous calls to debugfs_initialized()
 - Emit a warning exactly one time
 - Change the Kconfig name to IOMMU_DEBUGFS
 - Change the way debugfs modules are made

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of IOMMU driver internals
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   11 ++
 drivers/iommu/Makefile|6 +++
 drivers/iommu/amd_iommu_debugfs.c |   39 +
 drivers/iommu/amd_iommu_init.c|6 ++-
 drivers/iommu/amd_iommu_proto.h   |6 +++
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   70 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |   10 +
 9 files changed, 151 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
Signature
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-08 Thread Gary R Hook

On 05/08/2018 03:42 PM, Joe Perches wrote:

On Tue, 2018-05-08 at 15:07 -0500, Gary R Hook wrote:

On 05/08/2018 01:48 PM, Joe Perches wrote:

On Tue, 2018-05-08 at 12:08 -0500, Hook, Gary wrote:

On 5/7/2018 6:47 PM, kbuild test robot wrote:


All error/warnings (new ones prefixed by >>):

  In file included from include/linux/intel-iommu.h:32:0,
   from drivers/gpu/drm/i915/i915_drv.h:41,
   from drivers/gpu/drm/i915/i915_oa_bxt.c:31:
  include/linux/iommu.h: In function 'iommu_debugfs_new_driver_dir':

include/linux/iommu.h:706:8: error: parameter name omitted


   struct dentry *iommu_debugfs_new_driver_dir(char *) {};
  ^~
  In file included from include/linux/intel-iommu.h:32:0,
   from drivers/gpu/drm/i915/i915_drv.h:41,
   from drivers/gpu/drm/i915/i915_oa_bxt.c:31:

include/linux/iommu.h:706:8: warning: control reaches end of non-void function 
[-Wreturn-type]


   struct dentry *iommu_debugfs_new_driver_dir(char *) {};
  ^~

vim +706 include/linux/iommu.h

  700   
  701   #ifdef CONFIG_IOMMU_DEBUGFS
  702   void iommu_debugfs_setup(void);
  703   struct dentry *iommu_debugfs_new_driver_dir(char *);
  704   #else
  705   static inline void iommu_debugfs_setup(void) {}
> 706struct dentry *iommu_debugfs_new_driver_dir(char *) {};
  707   #endif
  708   


I have no problems with adding parameter names. But
scripts/checkpatch.pl doesn't seem to check for this, nor require it.
Should checkpatch be updated?


I'm pretty sure that's not feasible.


Ugh. This is a definition, not a declaration. My bad. Which is likely
why I decided to apologize up front.


And when the compiler tells you you've stuffed up some
syntactical bit, why should checkpatch duplicate the
output error message too?


Well, that's the point: neither the 4.8 nor 5.4 compiler complained
about this.


Perhaps because CONFIG_IOMMU_DEBUGFS was set in the .config
for all the compilation previously performed?


Well, you'd think maybe so, but I forced a recompilation of that one 
file (i915_oa_bxt.c) and no complaint with 5.4. Weird.


Ah, well. Onward to patch version 6.

Thanks again.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-08 Thread Gary R Hook

On 05/08/2018 01:48 PM, Joe Perches wrote:

On Tue, 2018-05-08 at 12:08 -0500, Hook, Gary wrote:

On 5/7/2018 6:47 PM, kbuild test robot wrote:


All error/warnings (new ones prefixed by >>):

 In file included from include/linux/intel-iommu.h:32:0,
  from drivers/gpu/drm/i915/i915_drv.h:41,
  from drivers/gpu/drm/i915/i915_oa_bxt.c:31:
 include/linux/iommu.h: In function 'iommu_debugfs_new_driver_dir':

include/linux/iommu.h:706:8: error: parameter name omitted


  struct dentry *iommu_debugfs_new_driver_dir(char *) {};
 ^~
 In file included from include/linux/intel-iommu.h:32:0,
  from drivers/gpu/drm/i915/i915_drv.h:41,
  from drivers/gpu/drm/i915/i915_oa_bxt.c:31:

include/linux/iommu.h:706:8: warning: control reaches end of non-void function 
[-Wreturn-type]


  struct dentry *iommu_debugfs_new_driver_dir(char *) {};
 ^~

vim +706 include/linux/iommu.h

 700
 701#ifdef CONFIG_IOMMU_DEBUGFS
 702void iommu_debugfs_setup(void);
 703struct dentry *iommu_debugfs_new_driver_dir(char *);
 704#else
 705static inline void iommu_debugfs_setup(void) {}
   > 706 struct dentry *iommu_debugfs_new_driver_dir(char *) {};
 707#endif
 708


I have no problems with adding parameter names. But
scripts/checkpatch.pl doesn't seem to check for this, nor require it.
Should checkpatch be updated?


I'm pretty sure that's not feasible.


Ugh. This is a definition, not a declaration. My bad. Which is likely 
why I decided to apologize up front.



And when the compiler tells you you've stuffed up some
syntactical bit, why should checkpatch duplicate the
output error message too?


Well, that's the point: neither the 4.8 nor 5.4 compiler complained 
about this. Not as an error, despite the fact that (now that I read what 
is actually here, as opposed to what I think is there) this is wrong. 
Had an error message been emitted, and the make stopped, I would have 
figure this out before embarrassing myself in front of the entire interwebs.



btw:  That's an unnecessary ; at the end of that non-void
function and it should probably be something like:


You are correct, sir. I've made a change on this.



static inline struct dentry *iommu_debugfs_new_driver_dir(char *dir)
{
return NULL;
}


Thanks for taking a few moments to comment. Much appreciated.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-05-07 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Makefile|5 +
 drivers/iommu/amd_iommu_debugfs.c |   41 +
 drivers/iommu/amd_iommu_init.c|6 -
 drivers/iommu/amd_iommu_proto.h   |6 +
 drivers/iommu/amd_iommu_types.h   |3 +++
 5 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..dd980f7dd8b6 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+
+# This ensures that only the required files are compiled
+ifeq ($(CONFIG_IOMMU_DEBUGFS), y)
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o
+endif
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..2b351b9f9130
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+
+pr_warn("GRH: %s:%d\n", __func__, __LINE__);
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs)
+   amd_iommu_debugfs = iommu_debugfs_new_driver_dir("amd");
+   mutex_unlock(_iommu_debugfs_lock);
+
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..39053f11dda3 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 1c9b080276c9..2ca0959ae9e6 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -593,6 +593,9 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+   /* DebugFS Info */
+   struct dentry *debugfs;
 };
 
 static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 0/2] Base enablement of IOMMU debugfs support

2018-05-07 Thread Gary R Hook
These patches create a top-level function, called at IOMMU initialization,
to create a debugfs directory for the IOMMU. Under this directory drivers
may create and populate-specific directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUGFS to globally allow/disallow
debugfs code to be built.

The Makefile structure is intended to allow the use of a single switch for
turning on DebugFS.

Changes since v4:
 - Guard vendor-specific debugfs files in the Makefile
 - Call top-level routine from iommu_init()
 - Add function for instantiating a driver-specific directory
 - Change AMD driver code to use this new format

Changes since v3:
 - Remove superfluous calls to debugfs_initialized()
 - Emit a warning exactly one time
 - Change the Kconfig name to IOMMU_DEBUGFS
 - Change the way debugfs modules are made

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of IOMMU driver internals
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   11 ++
 drivers/iommu/Makefile|6 +++
 drivers/iommu/amd_iommu_debugfs.c |   41 
 drivers/iommu/amd_iommu_init.c|6 ++-
 drivers/iommu/amd_iommu_proto.h   |6 +++
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   64 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |8 +
 9 files changed, 145 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v5 1/2] iommu - Enable debugfs exposure of IOMMU driver internals

2018-05-07 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of an
IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.

Emit a strong warning at boot time to indicate that this feature is
enabled.

This function is called from iommu_init, and creates the initial DebugFS
directory. Drivers may then call iommu_debugfs_new_driver_dir() to
instantiate a device-specific directory to expose internal data.
It will return a pointer to the new dentry structure created in
/sys/kernel/debug/iommu, or NULL in the event of a failure.

Since the IOMMU driver can not be removed from the running system, there
is no need for an "off" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |   11 +++
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   64 +
 drivers/iommu/iommu.c |2 +
 include/linux/iommu.h |8 +
 5 files changed, 86 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..ff511fa8ca7d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+   bool "Export IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..d82a10b2478b
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/*
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This function is called from iommu_init, and creates the initial DebugFS
+ * directory. Drivers may then call iommu_debugfs_new_driver_dir() to
+ * instantiate a device-specific directory to expose internal data.
+ * It will return a pointer to the new dentry structure created in
+ * /sys/kernel/debug/iommu, or NULL in the event of a failure.
+ *
+ * Since the IOMMU driver can not be removed from the running system, there
+ * is no need for an "off" function.
+ */
+void iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir) {
+   pr_warn("\n");
+   
pr_warn("*\n");
+   pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE 
NOTICE NOTICE**\n");
+   pr_warn("** 
**\n");
+   pr_warn("**  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL  **\n");
+   pr_warn("** 
**\n");
+   pr_warn("** This means that this kernel is built to 
expose internal **\n");
+   pr_warn("** IOMMU data structures, which may compromise 
security on **\n");
+   pr_warn("** your system.
**\n");
+   pr_warn("** 
**\n");
+   pr_warn("** If you see this message and you are not 
debugging the   **\n");
+   pr_warn("** kernel, report this immediately to your 
vendor! **\n");
+   pr_warn("**  

Re: [PATCH 3/3] iommu/amd: Do not flush when device is busy

2018-05-07 Thread Gary R Hook

On 05/07/2018 07:38 AM, Anna-Maria Gleixner wrote:

On Fri, 4 May 2018, Gary R Hook wrote:




The prior version of this comment appears 3 times in the file, and is
grammatically problematic every time. Can we simplify it to say

  * This function makes the device visible in the domain

Or some such? I.e. tidy up the two remaining comments?





Will fix it in a separate patch - but I only found 2 places where the
prior version of this comment appears.


My mistake. You are, of course, correct.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 3/3] iommu/amd: Do not flush when device is busy

2018-05-04 Thread Gary R Hook

On 05/04/2018 11:22 AM, Sebastian Andrzej Siewior wrote:

From: Anna-Maria Gleixner 

When device is already attached to a domain, there is no need to execute
the domain_flush_tlb_pde(). Therefore move the check if the domain is set
into attach_device().

Signed-off-by: Anna-Maria Gleixner 
Signed-off-by: Sebastian Andrzej Siewior 
---
  drivers/iommu/amd_iommu.c | 32 ++--
  1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index f66a5d0b7c62..a801678ae1b4 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1878,8 +1878,11 @@ static void clear_dte_entry(u16 devid)
amd_iommu_apply_erratum_63(devid);
  }
  
-static void do_attach(struct iommu_dev_data *dev_data,

- struct protection_domain *domain)
+/*
+ * This function does assigns the device visible for the hardware
+ */




The prior version of this comment appears 3 times in the file, and is 
grammatically problematic every time. Can we simplify it to say


 * This function makes the device visible in the domain

Or some such? I.e. tidy up the two remaining comments?




___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] iommu/amd - Update the PASID information printed to the system log

2018-05-03 Thread Gary R Hook

On 05/03/2018 08:57 AM, Joerg Roedel wrote:

On Tue, May 01, 2018 at 02:52:52PM -0500, Gary R Hook wrote:

@@ -567,7 +567,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
}
  
  	if (type == EVENT_TYPE_IO_FAULT) {

-   amd_iommu_report_page_fault(devid, domid, address, flags);
+   amd_iommu_report_page_fault(devid, pasid, address, flags);


According to the spec this could be a domid or a pasid, it would be good
to make that visible in the error message, depending on the value of the
GN flag in the event entry.

But that can be done in a separate patch, I applied these two, thanks.



Yes, I didn't quite get this right. Both values should be passed along. 
Or perhaps the entire event could be passed in and decoded by 
amd_iommu_report_page_fault()?

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/2] iommu/amd - Update logging information for new event type

2018-05-01 Thread Gary R Hook
A new events have been defined in the AMD IOMMU spec:

0x09 - "invalid PPR request"

Add support for logging this type of event.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
~
~
~
---
 drivers/iommu/amd_iommu.c   |   10 +-
 drivers/iommu/amd_iommu_types.h |1 +
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index a557565d4413..009c6d801fae 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -544,7 +544,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 
domain_id,
 static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
 {
struct device *dev = iommu->iommu.dev;
-   int type, devid, pasid, flags;
+   int type, devid, pasid, flags, tag;
volatile u32 *event = __evt;
int count = 0;
u64 address;
@@ -609,6 +609,14 @@ static void iommu_print_event(struct amd_iommu *iommu, 
void *__evt)
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
pasid, address, flags);
break;
+   case EVENT_TYPE_INV_PPR_REQ:
+   pasid = ((event[0] >> 16) & 0x)
+   | ((event[1] << 6) & 0xF);
+   tag = event[1] & 0x03FF;
+   dev_err(dev, "INVALID_PPR_REQUEST device=%02x:%02x.%x 
pasid=0x%05x address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   pasid, address, flags);
+   break;
default:
dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x 
event[2]=0x%08x event[3]=0x%08x\n",
event[0], event[1], event[2], event[3]);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 1c9b080276c9..986cbe0cc189 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -133,6 +133,7 @@
 #define EVENT_TYPE_CMD_HARD_ERR0x6
 #define EVENT_TYPE_IOTLB_INV_TO0x7
 #define EVENT_TYPE_INV_DEV_REQ 0x8
+#define EVENT_TYPE_INV_PPR_REQ 0x9
 #define EVENT_DEVID_MASK   0x
 #define EVENT_DEVID_SHIFT  0
 #define EVENT_DOMID_MASK   0x

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 1/2] iommu/amd - Update the PASID information printed to the system log

2018-05-01 Thread Gary R Hook
Provide detailed data for each event, as appropriate.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c |   31 +--
 1 file changed, 13 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 8c469b51185f..a557565d4413 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -544,7 +544,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 
domain_id,
 static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
 {
struct device *dev = iommu->iommu.dev;
-   int type, devid, domid, flags;
+   int type, devid, pasid, flags;
volatile u32 *event = __evt;
int count = 0;
u64 address;
@@ -552,7 +552,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
 retry:
type= (event[1] >> EVENT_TYPE_SHIFT)  & EVENT_TYPE_MASK;
devid   = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
-   domid   = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
+   pasid   = PPR_PASID(*(u64 *)[0]);
flags   = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
address = (u64)(((u64)event[3]) << 32) | event[2];
 
@@ -567,7 +567,7 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
}
 
if (type == EVENT_TYPE_IO_FAULT) {
-   amd_iommu_report_page_fault(devid, domid, address, flags);
+   amd_iommu_report_page_fault(devid, pasid, address, flags);
return;
} else {
dev_err(dev, "AMD-Vi: Event logged [");
@@ -575,10 +575,9 @@ static void iommu_print_event(struct amd_iommu *iommu, 
void *__evt)
 
switch (type) {
case EVENT_TYPE_ILL_DEV:
-   dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
-   "address=0x%016llx flags=0x%04x]\n",
+   dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x 
pasid=0x%05x address=0x%016llx flags=0x%04x]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-   address, flags);
+   pasid, address, flags);
dump_dte_entry(devid);
break;
case EVENT_TYPE_DEV_TAB_ERR:
@@ -588,34 +587,30 @@ static void iommu_print_event(struct amd_iommu *iommu, 
void *__evt)
address, flags);
break;
case EVENT_TYPE_PAGE_TAB_ERR:
-   dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
-   "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
+   dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x 
domain=0x%04x address=0x%016llx flags=0x%04x]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-   domid, address, flags);
+   pasid, address, flags);
break;
case EVENT_TYPE_ILL_CMD:
dev_err(dev, "ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", 
address);
dump_command(address);
break;
case EVENT_TYPE_CMD_HARD_ERR:
-   dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx "
-   "flags=0x%04x]\n", address, flags);
+   dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx 
flags=0x%04x]\n",
+   address, flags);
break;
case EVENT_TYPE_IOTLB_INV_TO:
-   dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
-   "address=0x%016llx]\n",
+   dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x 
address=0x%016llx]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
address);
break;
case EVENT_TYPE_INV_DEV_REQ:
-   dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
-   "address=0x%016llx flags=0x%04x]\n",
+   dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x 
pasid=0x%05x address=0x%016llx flags=0x%04x]\n",
PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-   address, flags);
+   pasid, address, flags);
break;
default:
-   dev_err(dev, KERN_ERR "UNKNOWN event[0]=0x%08x event[1]=0x%08x "
-   "event[2]=0x%08x event[3]=0x%08x\n",
+   dev_err(dev, "UNKNOWN event[0]=0x%08x event[1]=0x%08x 
event[2]=0x%08x event[3]=0x%08x\n",
event[0], event[1], event[2], event[3]);
}
 

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 0/2] Tweak AMD IOMMU logging

2018-05-01 Thread Gary R Hook
Update the AMD IOMMU log messages to be more precise, and
add a log message for a new event type.

---

Gary R Hook (2):
  iommu/amd - Update the PASID information printed to the system log
  iommu/amd - Update logging information for new event type


 drivers/iommu/amd_iommu.c   |   39 +--
 drivers/iommu/amd_iommu_types.h |1 +
 2 files changed, 22 insertions(+), 18 deletions(-)

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-04-30 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Makefile|5 
 drivers/iommu/amd_iommu_debugfs.c |   42 +
 drivers/iommu/amd_iommu_init.c|6 -
 drivers/iommu/amd_iommu_proto.h   |6 +
 drivers/iommu/amd_iommu_types.h   |3 +++
 5 files changed, 60 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 74cfbc392862..dd980f7dd8b6 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -30,3 +30,8 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o
 obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o
 obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
 obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o
+
+# This ensures that only the required files are compiled
+ifeq ($(CONFIG_IOMMU_DEBUGFS), y)
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu_debugfs.o
+endif
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..34bb65cbd798
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_top;
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs) {
+   d_top = iommu_debugfs_setup();
+   if (d_top)
+   amd_iommu_debugfs = debugfs_create_dir("amd", d_top);
+   }
+   mutex_unlock(_iommu_debugfs_lock);
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..39053f11dda3 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 1c9b080276c9..2ca0959ae9e6 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -593,6 +593,9 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+   /* DebugFS Info */
+   struct dentry *debugfs;
 };
 
 static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v4 1/2] iommu - Enable debugfs exposure of the IOMMU

2018-04-30 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of
an IOMMU driver. When called, create the /sys/kernel/debug/iommu
directory.  Emit a strong warning at boot time to indicate that this
feature is enabled.

This patch adds a top-level function that will create the (above)
directory, under which a driver may create a hw-specific directory for
its use. The function

iommu_debugfs_setup()

returns a pointer to the new dentry structure created for
/sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU
driver should call this function first, and then create a directory
beneath it. A driver implementation might look something like:

static struct dentry *my_debugfs;

struct dentry *d_top;
if (!my_debugfs) {
d_top = iommu_debugfs_setup();
if (d_top)
my_debugfs = debugfs_create_dir("vendor", d_top);
}

Since the IOMMU driver can not be removed from the running system, this
patch only provides an "on" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |   11 
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   55 +
 include/linux/iommu.h |4 +++
 4 files changed, 71 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..81a6c281e69f 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUGFS
+   bool "Enable IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..74cfbc392862 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUGFS) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..409691ca0ff9
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,55 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/*
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This top-level function that will create the (above) directory, under a
+ * driver may create a hw-specific directory for its use. The function
+ *
+ * iommu_debugfs_setup()
+ *
+ * returns a pointer to the new dentry structure created for
+ * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU
+ * driver should call this function first, and then create a directory
+ * beneath it. A driver implementation might look something like:
+ *
+ * static struct dentry *my_debugfs;
+ *
+ *struct dentry *d_top;
+ *if (!my_debugfs) {
+ *d_top = iommu_debugfs_setup();
+ *if (d_top)
+ *my_debugfs = debugfs_create_dir("vendor", d_top);
+ *}
+ *
+ * Since the IOMMU driver can not be removed from the running system, there
+ * is no need for an "off" function.
+ */
+struct dentry *iommu_debugfs_setup(void)
+{
+   if (!iommu_debugfs_dir) {
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+   if (iommu_debugfs_dir)
+   pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN 
ENABLED IN THIS KERNEL\n");
+   }
+
+   return iommu_debugfs_dir;
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_setup);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 19938ee6eb31..e5657c70f90c 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -698,4 +698,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct 
fwnode_handle *fwnode)
 
 #endif /* CONFIG_IOMMU_API */
 
+#ifdef CONFIG_IOMMU_DEBUGFS
+struct dentry *iommu_debugfs_setup(void);
+#endif
+
 #endif /* __LINUX_IOMMU_H */

_

[PATCH v4 0/2] Base enablement of IOMMU debugfs support

2018-04-30 Thread Gary R Hook
These patches create a top-level function to create a debugfs directory
for the IOMMU, under which drivers may create and populate-specific
directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or
disallow debugfs code to be built.

Changes since v3:
 - Remove superfluous calls to debugfs_initialized()
 - Emit a warning exactly one time
 - Change the Kconfig name to IOMMU_DEBUGFS
 - Change the way debugfs modules are made

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework



---

Gary R Hook (2):
  iommu - Enable debugfs exposure of the IOMMU
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   11 +++
 drivers/iommu/Makefile|6 
 drivers/iommu/amd_iommu_debugfs.c |   42 
 drivers/iommu/amd_iommu_init.c|6 +++-
 drivers/iommu/amd_iommu_proto.h   |6 
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   55 +
 include/linux/iommu.h |4 +++
 8 files changed, 131 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-04-30 Thread Gary R Hook

On 04/17/2018 12:38 PM, Hook, Gary wrote:

On 4/13/2018 8:08 PM, Mehta, Sohil wrote:

On Fri, 2018-04-06 at 08:17 -0500, Gary R Hook wrote:

+
+
+    mutex_lock(_iommu_debugfs_lock);
+    if (!amd_iommu_debugfs) {
+    d_top = iommu_debugfs_setup();
+    if (d_top)
+    amd_iommu_debugfs =
debugfs_create_dir("amd", d_top);
+    }
+    mutex_unlock(_iommu_debugfs_lock);



You can do the above only once if you iterate over the IOMMUs here
  instead of doing it in amd_iommu_init.


I'm not sure it matters, given the finite number of IOMMUs in a system, 
and the fact that this work is done exactly once. However, removal of a 
lock is fine thing, so I'll move this around.


After thinking about this, and looking at the code, I've decided to 
leave this alone.


v4 is on its way.


___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

[PATCH v3 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-04-06 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Makefile|1 +
 drivers/iommu/amd_iommu_debugfs.c |   45 +
 drivers/iommu/amd_iommu_init.c|6 +++--
 drivers/iommu/amd_iommu_proto.h   |6 +
 drivers/iommu/amd_iommu_types.h   |3 ++
 5 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 5eb1121d54b9..0ca250f626d9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..282100a655b3
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_top;
+
+   if (!debugfs_initialized())
+   return;
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs) {
+   d_top = iommu_debugfs_setup();
+   if (d_top)
+   amd_iommu_debugfs = debugfs_create_dir("amd", d_top);
+   }
+   mutex_unlock(_iommu_debugfs_lock);
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 904c575d1677..031e6dbb8345 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2721,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2730,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..daf7f38531f9 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUG
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 1c9b080276c9..2ca0959ae9e6 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -593,6 +593,9 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+   /* DebugFS Info */
+   struct dentry *debugfs;
 };
 
 static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 0/2] Base enablement of IOMMU debugfs support

2018-04-06 Thread Gary R Hook
These patches create a top-level function to create a debugfs directory
for the IOMMU, under which drivers may create and populate-specific
directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or
disallow debugfs code to be built.

Changes since v2:
 - Move a declaration to outside an ifdef
 - Remove a spurious blank line

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of the IOMMU
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   11 +++
 drivers/iommu/Makefile|2 +
 drivers/iommu/amd_iommu_debugfs.c |   45 +
 drivers/iommu/amd_iommu_init.c|6 +++-
 drivers/iommu/amd_iommu_proto.h   |6 
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   58 +
 include/linux/iommu.h |4 +++
 8 files changed, 133 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
Effective helpfulness requires thoroughness
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 1/2] iommu - Enable debugfs exposure of the IOMMU

2018-04-06 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of
an IOMMU driver. When called, create the /sys/kernel/debug/iommu
directory.  Emit a strong warning at boot time to indicate that this
feature is enabled.

This patch adds a top-level function that will create the (above)
directory, under which a driver may create a hw-specific directory for
its use. The function

iommu_debugfs_setup()

returns a pointer to the new dentry structure created for
/sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU
driver should call this function first, and then create a directory
beneath it. A driver implementation might look something like:

static struct dentry *my_debugfs;

struct dentry *d_top;
if (!my_debugfs) {
d_top = iommu_debugfs_setup();
if (d_top)
my_debugfs = debugfs_create_dir("vendor", d_top);
}

Since the IOMMU driver can not be removed from the running system, this
patch only provides an "on" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |   11 
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   58 +
 include/linux/iommu.h |4 +++
 4 files changed, 74 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..c1e39dabfec2 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUG
+   bool "Enable IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..5eb1121d54b9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..add6f95120e4
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/*
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This top-level function that will create the (above) directory, under a
+ * driver may create a hw-specific directory for its use. The function
+ *
+ * iommu_debugfs_setup()
+ *
+ * returns a pointer to the new dentry structure created for
+ * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU
+ * driver should call this function first, and then create a directory
+ * beneath it. A driver implementation might look something like:
+ *
+ * static struct dentry *my_debugfs;
+ *
+ *struct dentry *d_top;
+ *if (!my_debugfs) {
+ *d_top = iommu_debugfs_setup();
+ *if (d_top)
+ *my_debugfs = debugfs_create_dir("vendor", d_top);
+ *}
+ *
+ * Since the IOMMU driver can not be removed from the running system, there
+ * is no need for an "off" function.
+ */
+struct dentry *iommu_debugfs_setup(void)
+{
+   if (!debugfs_initialized())
+   return NULL;
+
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+
+   if (iommu_debugfs_dir)
+   pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL\n");
+
+   return iommu_debugfs_dir;
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_setup);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 19938ee6eb31..ccf7c1d800b0 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -698,4 +698,8 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct 
fwnode_handle *fwnode)
 
 #endif /* CONFIG_IOMMU_API */
 
+#ifdef CONFIG_IOMMU_DEBUG
+struct dentry *iommu_debugfs_setup(void);
+#endif
+
 #endif /* __LI

[PATCH v2 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-04-04 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Makefile|1 +
 drivers/iommu/amd_iommu_debugfs.c |   45 +
 drivers/iommu/amd_iommu_init.c|7 --
 drivers/iommu/amd_iommu_proto.h   |8 ++-
 drivers/iommu/amd_iommu_types.h   |3 ++
 5 files changed, 61 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 5eb1121d54b9..0ca250f626d9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..282100a655b3
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *amd_iommu_debugfs;
+static DEFINE_MUTEX(amd_iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_top;
+
+   if (!debugfs_initialized())
+   return;
+
+   mutex_lock(_iommu_debugfs_lock);
+   if (!amd_iommu_debugfs) {
+   d_top = iommu_debugfs_setup();
+   if (d_top)
+   amd_iommu_debugfs = debugfs_create_dir("amd", d_top);
+   }
+   mutex_unlock(_iommu_debugfs_lock);
+   if (amd_iommu_debugfs) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs = debugfs_create_dir(name,
+   amd_iommu_debugfs);
+   if (!iommu->debugfs) {
+   debugfs_remove_recursive(amd_iommu_debugfs);
+   amd_iommu_debugfs = NULL;
+   }
+   }
+}
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6fe2d0346073..43856c7f4ea1 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -89,6 +89,7 @@
 #define ACPI_DEVFLAG_ATSDIS 0x1000
 
 #define LOOP_TIMEOUT   10
+
 /*
  * ACPI table definitions
  *
@@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..1cfaae28c2cd 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUG
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu);
+#else
+static inline void amd_iommu_debugfs_setup(struct amd_iommu *iommu) {}
+#endif
+
 /* Needed for interrupt remapping */
 extern int amd_iommu_prepare(void);
 extern int amd_iommu_enable(void);
@@ -58,7 +64,7 @@ extern int amd_iommu_domain_clear_gcr3(struct iommu_domain 
*dom, int pasid);
 extern struct iommu_domain *amd_iommu_get_v2_domain(struct pci_dev *pdev);
 
 #ifdef CONFIG_IRQ_REMAP
-extern int amd_iommu_create_irq_domain(struct amd_iommu *iommu);
+int amd_iommu_create_irq_domain(struct amd_iommu *iommu);
 #else
 static inline int amd_iommu_create_irq_domain(struct amd_iommu *iommu)
 {
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f6b24c7d8b70..43c52797810e 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -591,6 +591,9 @@ struct amd_iommu {
 
u32 flags;
volatile u64 __aligned(8) cmd_sem;
+
+   /* 

[PATCH v2 1/2] iommu - Enable debugfs exposure of the IOMMU

2018-04-04 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of
an IOMMU driver. When called, create the /sys/kernel/debug/iommu
directory.  Emit a strong warning at boot time to indicate that this
feature is enabled.

This patch adds a top-level function that will create the (above)
directory, under which a driver may create a hw-specific directory for
its use. The function

iommu_debugfs_setup()

returns a pointer to the new dentry structure created for
/sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU
driver should call this function first, and then create a directory
beneath it. A driver implementation might look something like:

static struct dentry *my_debugfs;

struct dentry *d_top;
if (!my_debugfs) {
d_top = iommu_debugfs_setup();
if (d_top)
my_debugfs = debugfs_create_dir("vendor", d_top);
}

Since the IOMMU driver can not be removed from the running system, this
patch only provides an "on" function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |   11 
 drivers/iommu/Makefile|1 +
 drivers/iommu/iommu-debugfs.c |   58 +
 include/linux/iommu.h |4 +++
 4 files changed, 74 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..c1e39dabfec2 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUG
+   bool "Enable IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..5eb1121d54b9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..add6f95120e4
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+/*
+ * Provide base enablement for using debugfs to expose internal data of an
+ * IOMMU driver. When called, create the /sys/kernel/debug/iommu directory.
+ *
+ * Emit a strong warning at boot time to indicate that this feature is
+ * enabled.
+ *
+ * This top-level function that will create the (above) directory, under a
+ * driver may create a hw-specific directory for its use. The function
+ *
+ * iommu_debugfs_setup()
+ *
+ * returns a pointer to the new dentry structure created for
+ * /sys/kernel/debug/iommu, or NULL in the event of a failure. An IOMMU
+ * driver should call this function first, and then create a directory
+ * beneath it. A driver implementation might look something like:
+ *
+ * static struct dentry *my_debugfs;
+ *
+ *struct dentry *d_top;
+ *if (!my_debugfs) {
+ *d_top = iommu_debugfs_setup();
+ *if (d_top)
+ *my_debugfs = debugfs_create_dir("vendor", d_top);
+ *}
+ *
+ * Since the IOMMU driver can not be removed from the running system, there
+ * is no need for an "off" function.
+ */
+struct dentry *iommu_debugfs_setup(void)
+{
+   if (!debugfs_initialized())
+   return NULL;
+
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+
+   if (iommu_debugfs_dir)
+   pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL\n");
+
+   return iommu_debugfs_dir;
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_setup);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 41b8c5757859..3dd2e73d31c4 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -412,6 +412,10 @@ void iommu_fwspec_free(struct device *dev);
 int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids);
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode);
 
+#if

[PATCH v2 0/2] Base enablement of IOMMU debugfs support

2018-04-04 Thread Gary R Hook
These patches create a top-level function to create a debugfs directory
for the IOMMU, under which drivers may create and populate-specific
directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or
disallow debugfs code to be built.

Changes since v1:
 - Remove debug cruft
 - Remove cruft produced by design change
 - Change the lock to a mutex
 - Coding style fixes
 - Add a comment to document the framework

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of the IOMMU
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |   11 +++
 drivers/iommu/Makefile|2 +
 drivers/iommu/amd_iommu_debugfs.c |   45 +
 drivers/iommu/amd_iommu_init.c|7 +++-
 drivers/iommu/amd_iommu_proto.h   |8 -
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   58 +
 include/linux/iommu.h |4 +++
 8 files changed, 135 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
Signature
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-03-30 Thread Gary R Hook

On 03/29/2018 11:16 PM, Tom Lendacky wrote:

On 3/29/2018 5:54 PM, Gary R Hook wrote:

Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/Kconfig |6 ++---
  drivers/iommu/Makefile|2 +-
  drivers/iommu/amd_iommu_debugfs.c |   47 +
  drivers/iommu/amd_iommu_init.c|9 ---
  drivers/iommu/amd_iommu_proto.h   |6 +
  drivers/iommu/amd_iommu_types.h   |3 ++
  include/linux/iommu.h |8 +++---
  7 files changed, 69 insertions(+), 12 deletions(-)
  create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d40248446214..8d50151d5bf4 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -65,9 +65,9 @@ config IOMMU_DEBUG
depends on DEBUG_FS
default n
help
- Base enablement for access to any IOMMU device. Allows individual
- drivers to populate debugfs for access to IOMMU registers and
- data structures.
+ Enable exposure of IOMMU device internals. Allow devices to
+ populate debugfs for access to IOMMU registers and data
+ structures.


This help text shouldn't change just because a driver is making use of
the interface that was created in the previous patch.


Roger. It should be changed in the base patch only.


  
  config IOMMU_IOVA

tristate
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 5e5c3339681d..0ca250f626d9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
  obj-$(CONFIG_OF_IOMMU)+= of_iommu.o
  obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
  obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
-obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o
+obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o
  obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
  obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
  obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..3547ad3339c1
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#ifdef CONFIG_IOMMU_DEBUG


Since the module won't be built unless this is defined, you don't
need this.


For some reason my build is trying to compile this file, even though I 
have the debug option disabled. Gotta track this down.





+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *iommu_debugfs_dir;
+static DEFINE_RWLOCK(iommu_debugfs_lock);


Use amd_iommu_...

Also, didn't you run into an issue with the CCP and debugfs creation
during probe using a RWLOCK?  Should probably make this a mutex.


Yes, and had to make a change. I will do so here.




+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_top;
+   unsigned long flags;
+
+   if (!debugfs_initialized())
+   return;
+
+   write_lock_irqsave(_debugfs_lock, flags);
+   if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup()))
+   iommu_debugfs_dir = debugfs_create_dir("amd", d_top);
+   write_unlock_irqrestore(_debugfs_lock, flags);
+   if (iommu_debugfs_dir) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs_instance = debugfs_create_dir(name,
+iommu_debugfs_dir);
+   if (!iommu->debugfs_instance)
+   debugfs_remove_recursive(iommu_debugfs_dir);


So this might cause an error.  You remove it, but don't set the variable
to NULL, so the next IOMMU that is probed could try to use it.  But why
are you deleting it anyway?


Right you are. My thought was to remove everything driver-specific in 
the event of a failure. Do we not like that?





+   }
+
+   return;
+}
+
+#endif
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 99d48c42a12f..43856c7f4ea1 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -89,6 +89,7 @@
  #define ACPI_DEVFLAG_ATSDIS 0x1000
  
  #define LOOP_TIMEOUT	10

+


Spurious newline.


D'oh!




  /*
   * ACPI table definitions
   *
@@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
   */
  static int __init amd_iommu_init(void)
  {
+   struct amd_iommu *iommu;
int ret;
  
  	ret = iommu_go_to_state(IOMMU_INITIAL

Re: [PATCH 1/2] iommu - Enable debugfs exposure of the IOMMU

2018-03-30 Thread Gary R Hook

On 03/29/2018 10:57 PM, Tom Lendacky wrote:

On 3/29/2018 5:54 PM, Gary R Hook wrote:

Provide base enablement for using debugfs to expose internal data of
an IOMMU driver. When enabled, create the /sys/kernel/debug/iommu


So this can't actually create anything yet since nothing invokes the
function.  Maybe describe how it should be used by other drivers (and
probably include that description as a commment for the function) to
create the directory.


Exactly. Given the approach I took, it takes another patch to take 
advantage of this. I can certainly elaborate on usage if we agree that 
this framework is acceptable.





directory.  Emit a strong warning at boot time to indicate that this
feature is enabled.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/Kconfig  |   11 +++
  drivers/iommu/Makefile |2 ++
  drivers/iommu/amd_iommu_init.c |2 ++
  drivers/iommu/iommu-debugfs.c  |   32 
  include/linux/iommu.h  |4 
  5 files changed, 51 insertions(+)
  create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..c1e39dabfec2 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
  
  endmenu
  
+config IOMMU_DEBUG

+   bool "Enable IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
  config IOMMU_IOVA
tristate
  
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile

index 1fb695854809..5e5c3339681d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
  obj-$(CONFIG_IOMMU_API) += iommu.o
  obj-$(CONFIG_IOMMU_API) += iommu-traces.o
  obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o
  obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
  obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
@@ -10,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
  obj-$(CONFIG_OF_IOMMU)+= of_iommu.o
  obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
  obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o


Where is this CONFIG defined?


That, my friend is left-over cruft. Please ignore. Apologies, and thanks.


  obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
  obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
  obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6fe2d0346073..99d48c42a12f 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2783,6 +2783,8 @@ int __init amd_iommu_detect(void)
iommu_detected = 1;
x86_init.iommu.iommu_init = amd_iommu_init;
  
+dump_stack();

+


This definitely shouldn't be here.


Dang it!




return 1;
  }
  
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c

new file mode 100644
index ..94c9acc63b65
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver


This isn't the AMD IOMMU driver.


Again: dang it!


+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+#defineMAX_NAME_LEN20


This isn't used anywhere.


Thanks.




+
+/* Return a zero on failure; 1 on successful setup */


Return NULL on failure, pointer to IOMMU debugfs dentry on success.


Roger.




+struct dentry *iommu_debugfs_setup(void)
+{
+   if (!debugfs_initialized())
+   return NULL;
+
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+
+   if (iommu_debugfs_dir)
+   pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN THIS 
KERNEL\n");
+
+   return iommu_debugfs_dir;
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_setup);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 41b8c5757859..cb2957dac43b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -696,6 +696,10 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct 
fwnode_handle *fwnode)
return NULL;
  }
  
+#ifdef	CONFIG_IOMMU_DEBUG


Should be a space between the #ifdef and the CONFIG_..., not a tab.


Roger that.



Thanks,
Tom


+struct dentry *iommu_debugfs_setup(void);
+#endif
+
  #endif /* CONFIG_IOMMU_API */
  
  #endif /* __LINUX_IOMMU_H */




___

[PATCH 1/2] iommu - Enable debugfs exposure of the IOMMU

2018-03-29 Thread Gary R Hook
Provide base enablement for using debugfs to expose internal data of
an IOMMU driver. When enabled, create the /sys/kernel/debug/iommu
directory.  Emit a strong warning at boot time to indicate that this
feature is enabled.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig  |   11 +++
 drivers/iommu/Makefile |2 ++
 drivers/iommu/amd_iommu_init.c |2 ++
 drivers/iommu/iommu-debugfs.c  |   32 
 include/linux/iommu.h  |4 
 5 files changed, 51 insertions(+)
 create mode 100644 drivers/iommu/iommu-debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..c1e39dabfec2 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -60,6 +60,17 @@ config IOMMU_IO_PGTABLE_ARMV7S_SELFTEST
 
 endmenu
 
+config IOMMU_DEBUG
+   bool "Enable IOMMU internals in DebugFS"
+   depends on DEBUG_FS
+   default n
+   help
+ Allows exposure of IOMMU device internals. This option enables
+ the use of debugfs by IOMMU drivers as required. Devices can,
+ at initialization time, cause the IOMMU code to create a top-level
+ debug/iommu directory, and then populate a subdirectory with
+ entries as required.
+
 config IOMMU_IOVA
tristate
 
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..5e5c3339681d 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,6 +2,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_DEBUG) += iommu-debugfs.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
@@ -10,6 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6fe2d0346073..99d48c42a12f 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2783,6 +2783,8 @@ int __init amd_iommu_detect(void)
iommu_detected = 1;
x86_init.iommu.iommu_init = amd_iommu_init;
 
+dump_stack();
+
return 1;
 }
 
diff --git a/drivers/iommu/iommu-debugfs.c b/drivers/iommu/iommu-debugfs.c
new file mode 100644
index ..94c9acc63b65
--- /dev/null
+++ b/drivers/iommu/iommu-debugfs.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#include 
+#include 
+#include 
+
+static struct dentry *iommu_debugfs_dir;
+
+#defineMAX_NAME_LEN20
+
+/* Return a zero on failure; 1 on successful setup */
+struct dentry *iommu_debugfs_setup(void)
+{
+   if (!debugfs_initialized())
+   return NULL;
+
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir("iommu", NULL);
+
+   if (iommu_debugfs_dir)
+   pr_warn("WARNING: IOMMU DEBUGFS SUPPORT HAS BEEN ENABLED IN 
THIS KERNEL\n");
+
+   return iommu_debugfs_dir;
+}
+EXPORT_SYMBOL_GPL(iommu_debugfs_setup);
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 41b8c5757859..cb2957dac43b 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -696,6 +696,10 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct 
fwnode_handle *fwnode)
return NULL;
 }
 
+#ifdef CONFIG_IOMMU_DEBUG
+struct dentry *iommu_debugfs_setup(void);
+#endif
+
 #endif /* CONFIG_IOMMU_API */
 
 #endif /* __LINUX_IOMMU_H */

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/2] iommu/amd: Add basic debugfs infrastructure for AMD IOMMU

2018-03-29 Thread Gary R Hook
Implement a skeleton framework for debugfs support in the
AMD IOMMU.


Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |6 ++---
 drivers/iommu/Makefile|2 +-
 drivers/iommu/amd_iommu_debugfs.c |   47 +
 drivers/iommu/amd_iommu_init.c|9 ---
 drivers/iommu/amd_iommu_proto.h   |6 +
 drivers/iommu/amd_iommu_types.h   |3 ++
 include/linux/iommu.h |8 +++---
 7 files changed, 69 insertions(+), 12 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d40248446214..8d50151d5bf4 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -65,9 +65,9 @@ config IOMMU_DEBUG
depends on DEBUG_FS
default n
help
- Base enablement for access to any IOMMU device. Allows individual
- drivers to populate debugfs for access to IOMMU registers and
- data structures.
+ Enable exposure of IOMMU device internals. Allow devices to
+ populate debugfs for access to IOMMU registers and data
+ structures.
 
 config IOMMU_IOVA
tristate
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 5e5c3339681d..0ca250f626d9 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -11,7 +11,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
-obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o
+obj-$(CONFIG_IOMMU_DEBUG) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..3547ad3339c1
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#ifdef CONFIG_IOMMU_DEBUG
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+static struct dentry *iommu_debugfs_dir;
+static DEFINE_RWLOCK(iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_top;
+   unsigned long flags;
+
+   if (!debugfs_initialized())
+   return;
+
+   write_lock_irqsave(_debugfs_lock, flags);
+   if (!iommu_debugfs_dir && (d_top = iommu_debugfs_setup()))
+   iommu_debugfs_dir = debugfs_create_dir("amd", d_top);
+   write_unlock_irqrestore(_debugfs_lock, flags);
+   if (iommu_debugfs_dir) {
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs_instance = debugfs_create_dir(name,
+iommu_debugfs_dir);
+   if (!iommu->debugfs_instance)
+   debugfs_remove_recursive(iommu_debugfs_dir);
+   }
+
+   return;
+}
+
+#endif
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 99d48c42a12f..43856c7f4ea1 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -89,6 +89,7 @@
 #define ACPI_DEVFLAG_ATSDIS 0x1000
 
 #define LOOP_TIMEOUT   10
+
 /*
  * ACPI table definitions
  *
@@ -2720,6 +2721,7 @@ int __init amd_iommu_enable_faulting(void)
  */
 static int __init amd_iommu_init(void)
 {
+   struct amd_iommu *iommu;
int ret;
 
ret = iommu_go_to_state(IOMMU_INITIALIZED);
@@ -2729,14 +2731,15 @@ static int __init amd_iommu_init(void)
disable_iommus();
free_iommu_resources();
} else {
-   struct amd_iommu *iommu;
-
uninit_device_table_dma();
for_each_iommu(iommu)
iommu_flush_all_caches(iommu);
}
}
 
+   for_each_iommu(iommu)
+   amd_iommu_debugfs_setup(iommu);
+
return ret;
 }
 
@@ -2783,8 +2786,6 @@ int __init amd_iommu_detect(void)
iommu_detected = 1;
x86_init.iommu.iommu_init = amd_iommu_init;
 
-dump_stack();
-
return 1;
 }
 
diff --git a/drivers/iommu/amd_iommu_proto.h b/drivers/iommu/amd_iommu_proto.h
index 640c286a0ab9..e19cebc5c740 100644
--- a/drivers/iommu/amd_iommu_proto.h
+++ b/drivers/iommu/amd_iommu_proto.h
@@ -33,6 +33,12 @@ extern void amd_iommu_uninit_devices(void);
 extern void amd_iommu_init_notifier(void);
 extern int amd_iommu_init_api(void);
 
+#ifdef CONFIG_IOMMU_DEBUG
+extern void am

[PATCH 0/2] Base enablement of IOMMU debugfs support

2018-03-29 Thread Gary R Hook
These patches create a top-level function to create a debugfs directory
for the IOMMU, under which drivers may create and populate-specific
directories for their device internals.

Patch 1: general IOMMU enablement
Patch 2: basic AMD enablement to demonstrate linkage with patch 1

Introduce a new Kconfig parameter IOMMU_DEBUG to globally allow or
disallow debugfs code to be built.

---

Gary R Hook (2):
  iommu - Enable debugfs exposure of the IOMMU
  iommu/amd: Add basic debugfs infrastructure for AMD IOMMU


 drivers/iommu/Kconfig |9 +++
 drivers/iommu/Makefile|2 ++
 drivers/iommu/amd_iommu_debugfs.c |   47 +
 drivers/iommu/amd_iommu_init.c|7 --
 drivers/iommu/amd_iommu_proto.h   |6 +
 drivers/iommu/amd_iommu_types.h   |3 ++
 drivers/iommu/iommu-debugfs.c |   32 +
 include/linux/iommu.h |4 +++
 8 files changed, 108 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c
 create mode 100644 drivers/iommu/iommu-debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v7 0/5] Add Intel IOMMU debugfs support

2018-03-29 Thread Gary R Hook

On 03/29/2018 03:48 AM, Joerg Roedel wrote:

[ Adding Gary from AMD to Cc ]

On Mon, Mar 19, 2018 at 09:37:14AM -0700, Jacob Pan wrote:

On Thu, 15 Mar 2018 14:18:54 +0100
Joerg Roedel  wrote:


On Thu, Feb 15, 2018 at 08:38:11AM -0800, Jacob Pan wrote:

Just wondering if your concern is on the implementation or the
debugfs idea in general. Perhaps have some common IOMMU debugfs?


My concern mainly is that we add interfaces which reveal
potentially security relevant information

I don;t think security is any worse than existing kernel page table in
debugfs. i.e. /sys/kernel/debug/page_tables
This is a debug feature.


Okay, so here is the way to go: Please introduce a basic debugfs
facility to the core iommu code. It should basically only create a
'iommu/' directory in debugfs where drivers can create their own
sub-directories. This must be enabled by a new kconfig option
(CONFIG_IOMMU_DEBUGFS) and the kernel should print a big fat warning at
boot when it is enabled. This hopefully prevents anyone from enabling it
for production kernels.


I'm halfway through this. Where would you like to place the invocation 
of the initialization function?


There's an iommu_init() in iommu.c, But it's a core_initcall, which 
doesn't seem like a good spot. Not knowing enough about bring-up here, 
Would adding another __init function be suitable?


Gary
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 0/5] Add debugfs info for the AMD IOMMU

2018-03-26 Thread Gary R Hook

On 03/15/2018 08:58 AM, Joerg Roedel wrote:

On Wed, Mar 14, 2018 at 06:04:44PM -0500, Gary R Hook wrote:

Gary R Hook (5):
   iommu/amd - Add debugfs support
   iommu/amd - Add a 'verbose' switch for IOMMU debugfs
   iommu/amd - Add a README variable for the IOMMU debugfs
   iommu/amd - Expose the active IOMMU device table entries
   iommu/amd - Add a debugfs entry to specify a IOMMU device table entry


Same problem here as with the Intel patches, I don't think it's a good
idea to reveal internal iommu data structures to user-space in this way.


I'm afraid I'm not following the line of thought here. AFAIK, if we 
restrict access of any debugfs info to root, then only root can see any 
of that information. If root is compromised, the whole system is 
compromised. Which seems to me to make all of debugfs suspect from a 
security perspective. Therefore, I'm likely not understanding the 
security concerns as they relate specifically to the IOMMU.


As for stability, you mention on the Intel IOMMU thread issues 
surrounding kABI, which I appreciate. But I'm exposing well-documented 
device structures in my patches, not kernel structures. There's nothing 
there that is going to change underneath me without my knowledge, if 
ever (I vote for never). And I'm likely ignorant about policy nuances 
surrounding the kernel ABI.



I've debugged iommu issues for around 10 years now and never had the
need for an interface that reveals those internals. How exactly are you
planning to use this information?


Well, I've already had to dig into the DTEs and page tables for a couple 
of reasons (both debug and development), and it made life easier (for 
me) to make the live data available this way. Then I thought that others 
might be interested as well. Admittedly, I could be wrong.


Finally, I'm no guru, and likely am unaware of other techniques in which 
I should develop skills. I'm always open to input.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 3/5] iommu/amd - Add a README variable for the IOMMU debugfs

2018-03-14 Thread Gary R Hook
Provide help text via a filesystem entry

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 170863e5e86b..d95428b1ef90 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -92,6 +92,31 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+static char readmetext[] =
+"count   Count of active devices\n"
+"verbose Provide additional descriptive text\n"
+"\n";
+
+static ssize_t amd_iommu_debugfs_readme_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   ssize_t ret;
+
+   ret = simple_read_from_buffer(ubuf, count, offp,
+ readmetext, strlen(readmetext));
+
+   return ret;
+}
+
+
+static const struct file_operations amd_iommu_debugfs_readme_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_readme_read,
+   .write = NULL,
+};
+
 void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
 {
char name[MAX_NAME_LEN + 1];
@@ -125,6 +150,12 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!d_dte)
goto err;
 
+   d_dte = debugfs_create_file("README", 0400,
+   iommu->debugfs_instance, iommu,
+   _iommu_debugfs_readme_ops);
+   if (!d_dte)
+   goto err;
+
return;
 
 err:

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 5/5] iommu/amd - Add a debugfs entry to specify a IOMMU device table entry

2018-03-14 Thread Gary R Hook
Initially (at boot) the device table values dumped are all of the
active devices.  Add a devid debugfs file to allow the user to select a
single device table entry to dump (active or not). Let any devid value
greater than the maximum allowable PCI ID (0x) restore the
behavior to that effective at boot.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |  121 -
 1 file changed, 106 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 1d941c5329be..47bf718f6178 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -42,6 +42,7 @@ static DEFINE_MUTEX(iommu_debugfs_lock);
 #defineMAX_NAME_LEN20
 
 static unsigned int amd_iommu_verbose = 0;
+static unsigned int amd_iommu_devid = ~0;
 
 static unsigned int amd_iommu_count_valid_dtes(int start, int end)
 {
@@ -92,14 +93,84 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+static ssize_t amd_iommu_debugfs_devid_read(struct file *filp,
+   char __user *ubuf,
+   size_t count, loff_t *offp)
+{
+   unsigned int obuflen = 64;
+   unsigned int oboff = 0;
+   ssize_t ret;
+   char *obuf;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   if (amd_iommu_verbose)
+   oboff += OSCNPRINTF("%02x:%02x:%x (%u / %04x)\n",
+   PCI_BUS_NUM(amd_iommu_devid),
+   PCI_SLOT(amd_iommu_devid),
+   PCI_FUNC(amd_iommu_devid),
+   amd_iommu_devid, amd_iommu_devid);
+   else
+   oboff += OSCNPRINTF("%u\n", amd_iommu_devid);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static ssize_t amd_iommu_debugfs_devid_write(struct file *filp,
+   const char __user *ubuf,
+   size_t count, loff_t *offp)
+{
+   unsigned int pci_id, pci_slot, pci_func;
+   unsigned int obuflen = 80;
+   ssize_t ret;
+   char *obuf;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   ret = simple_write_to_buffer(obuf, OBUFLEN, offp, ubuf, count);
+
+   if (strnchr(obuf, OBUFLEN, ':')) {
+   int n;
+   n = sscanf(obuf, "%x:%x.%x", _id, _slot, _func);
+   if (n == 3)
+   amd_iommu_devid = PCI_DEVID(pci_id, PCI_DEVFN(pci_slot, 
pci_func));
+   } else {
+   kstrtoint(obuf, 0, _iommu_devid);
+   }
+
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_devid_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_devid_read,
+   .write = amd_iommu_debugfs_devid_write,
+};
+
 #defineMAX_PCI_ID  0x
 
-#definePRINTDTE(i) OSCNPRINTF("%02x:%02x:%x - %016llx %016llx 
%016llx %016llx\n", \
-  PCI_BUS_NUM(i), PCI_SLOT(i), PCI_FUNC(i), \
-  amd_iommu_dev_table[i].data[0], \
-  amd_iommu_dev_table[i].data[1], \
-  amd_iommu_dev_table[i].data[2], \
-  amd_iommu_dev_table[i].data[3]);
+static inline int amd_iommu_debugfs_printdte(int i, char *obuf, unsigned int 
obuflen, unsigned int oboff)
+{
+   int rc;
+
+   rc = OSCNPRINTF("%02x:%02x:%x - %016llx %016llx %016llx %016llx\n",
+   PCI_BUS_NUM(i), PCI_SLOT(i), PCI_FUNC(i),
+   amd_iommu_dev_table[i].data[0],
+   amd_iommu_dev_table[i].data[1],
+   amd_iommu_dev_table[i].data[2],
+   amd_iommu_dev_table[i].data[3]);
+   return rc;
+}
 
 static ssize_t amd_iommu_debugfs_dte_read(struct file *filp,
  char __user *ubuf,
@@ -113,19 +184,28 @@ static ssize_t amd_iommu_debugfs_dte_read(struct file 
*filp,
char *obuf;
 
/* Count the number of valid entries in the device table */
-   istart = 0;
-   iend = MAX_PCI_ID;
-   n = amd_iommu_count_valid_dtes(istart, iend);
+   if (amd_iommu_devid > MAX_PCI_ID) {
+   istart = 0;
+   iend = MAX_PCI_ID;
+   n = amd_iommu_count_valid_dtes(istart, iend);
+   } else {
+   n = 1;
+   }
obuflen = n * 80;
 
obuf = kmalloc(OBUFLEN, GFP_KERNEL);
if (!obuf)
return -ENOMEM;
 
-   for (i = istart ; 

[PATCH v3 2/5] iommu/amd - Add a 'verbose' switch for IOMMU debugfs

2018-03-14 Thread Gary R Hook
Enable more descriptive debugfs output via a 'verbose' variable.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 4f0f05a89a41..170863e5e86b 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -41,6 +41,8 @@ static DEFINE_MUTEX(iommu_debugfs_lock);
 
 #defineMAX_NAME_LEN20
 
+static unsigned int amd_iommu_verbose = 0;
+
 static unsigned int amd_iommu_count_valid_dtes(int start, int end)
 {
unsigned int n = 0;
@@ -72,7 +74,10 @@ static ssize_t amd_iommu_debugfs_dtecount_read(struct file 
*filp,
return -ENOMEM;
 
n = amd_iommu_count_valid_dtes(0, 0x);
-   oboff += OSCNPRINTF("%d\n", n);
+   if (amd_iommu_verbose)
+   oboff += OSCNPRINTF("# DTEs:  %d\n", n);
+   else
+   oboff += OSCNPRINTF("%d\n", n);
 
ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
kfree(obuf);
@@ -90,6 +95,7 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
 void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
 {
char name[MAX_NAME_LEN + 1];
+   struct dentry *d_verbose;
struct dentry *d_dte;
 
if (!debugfs_initialized())
@@ -107,6 +113,12 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!iommu->debugfs_instance)
goto err;
 
+   d_verbose = debugfs_create_u32("verbose", 0600,
+  iommu->debugfs_instance,
+  _iommu_verbose);
+   if (!d_verbose)
+   goto err;
+
d_dte = debugfs_create_file("count", 0400,
iommu->debugfs_instance, iommu,
_iommu_debugfs_dtecount_ops);

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v3 1/5] iommu/amd - Add debugfs support

2018-03-14 Thread Gary R Hook
Expose the IOMMU MMIO registers and device table

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |7 ++
 drivers/iommu/Makefile|1 
 drivers/iommu/amd_iommu_debugfs.c |  122 +
 drivers/iommu/amd_iommu_init.c|6 +-
 drivers/iommu/amd_iommu_proto.h   |7 ++
 drivers/iommu/amd_iommu_types.h   |3 +
 6 files changed, 144 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..8b2a5b8707c6 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -135,6 +135,13 @@ config AMD_IOMMU_V2
  hardware. Select this option if you want to use devices that support
  the PCI PRI and PASID interface.
 
+config AMD_IOMMU_DEBUG
+   bool "Expose AMD IOMMU internals in DebugFS"
+   depends on AMD_IOMMU && DEBUG_FS
+   help
+ Provides debugfs access to IOMMU data such as registers and device
+ table entries.
+
 # Intel IOMMU support
 config DMAR_TABLE
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..64fba8b1ca4f 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..4f0f05a89a41
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include 
+#include 
+#include 
+
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+/* DebugFS helpers
+ *
+ * This is intended to shrink the scnprintf statements used to produce
+ * debugfs output. Each function that uses OSCNPRINTF will need to declare
+ * local variables:
+ *
+ * unsigned int obuflen = ;
+ * unsigned int oboff = 0;
+ * char *obuf;
+ *
+ * wherein obuflen is the expected buffer length needed for the output text.
+ * Every statement then reduces to
+ * oboff += OSCNPRINTF([, [, ...]]);
+ */
+#defineOBUFP   (obuf + oboff)
+#defineOBUFLEN obuflen
+#defineOBUFSPC (OBUFLEN - oboff)
+#defineOSCNPRINTF(fmt, ...) \
+   scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
+
+static struct dentry *iommu_debugfs_dir;
+static DEFINE_MUTEX(iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+static unsigned int amd_iommu_count_valid_dtes(int start, int end)
+{
+   unsigned int n = 0;
+   int i;
+
+   /* Scan the DTE table from entry 'start' through entry 'end' for
+* active entries
+*/
+   for (i = start ; i <= end ; i++) {
+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+   || amd_iommu_dev_table[i].data[1])
+   n++;
+   }
+   return n;
+}
+
+static ssize_t amd_iommu_debugfs_dtecount_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   unsigned int obuflen = 64;
+   unsigned int oboff = 0;
+   unsigned int n;
+   ssize_t ret;
+   char *obuf;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   n = amd_iommu_count_valid_dtes(0, 0x);
+   oboff += OSCNPRINTF("%d\n", n);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_dtecount_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_dtecount_read,
+   .write = NULL,
+};
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_dte;
+
+   if (!debugfs_initialized())
+   return;
+
+   mutex_lock(_debugfs_lock);
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+   mutex_unlock(_debugfs_lock);
+   if (!iommu_debugfs_dir)
+   goto err;
+
+   snprintf(name, MAX_NAME_LEN, "iommu%02x", iommu->index);
+   iommu->debugfs_instance = debugfs_create_dir(name, iommu_debugfs_dir);
+   if (!iommu->debugfs_insta

[PATCH v3 0/5] Add debugfs info for the AMD IOMMU

2018-03-14 Thread Gary R Hook
The following series creates a debugfs directory for AMD IOMMUs,
constructs a framework for additional entries, an online README,
and a method for dumping device table entries. Data is reported
in a default concise mode, but a verbose mode is enabled via a
filesystem entry.

This is the first of three patch series that will expose a number
of IOMMU registers.

Changes since v2:
- Change lock type to a mutex
- Convert a #define to an inline
- Alphabetize #include files
- Remove unnecessary checks for pointers
- Use kstrtoint() instead of sscanf()
- Added comments
- Minor style fixes

Changes since v1:
- Correctly use CONFIG_AMD_IOMMU_DEBUG in Makefile and header file

---

Gary R Hook (5):
  iommu/amd - Add debugfs support
  iommu/amd - Add a 'verbose' switch for IOMMU debugfs
  iommu/amd - Add a README variable for the IOMMU debugfs
  iommu/amd - Expose the active IOMMU device table entries
  iommu/amd - Add a debugfs entry to specify a IOMMU device table entry


 drivers/iommu/Kconfig |7 +
 drivers/iommu/Makefile|1 
 drivers/iommu/amd_iommu_debugfs.c |  316 +
 drivers/iommu/amd_iommu_init.c|6 -
 drivers/iommu/amd_iommu_proto.h   |7 +
 drivers/iommu/amd_iommu_types.h   |3 
 6 files changed, 338 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 1/5] iommu/amd - Add debugfs support

2018-03-14 Thread Gary R Hook

On 03/13/2018 03:23 PM, Andy Shevchenko wrote:

On Tue, Mar 13, 2018 at 8:54 PM, Gary R Hook <gary.h...@amd.com> wrote:

On 03/13/2018 12:16 PM, Andy Shevchenko wrote:

On Fri, Mar 9, 2018 at 2:50 AM, Gary R Hook <gary.h...@amd.com> wrote:



+#include 
+#include 
+#include 



Keep in order?



What order would that be? These few needed files are listed in the same
order as which they appear in amd_iommu.c. I'm gonna need a preference
spelled out, please (and a rationale, so I may better understand).


To increase readability and avoid potential header duplication (here
is can bus protocol implementation where the problem exists for real,
even in new code!)


With all due respect, I don't find that you clearly answered my 
question. I will hazard a guess that you mean to -alphabetize- them? 
Which I am happy to do, and will do so in the next version.


If that is not your meaning, I'll have to ask you to use small words, 
and not presume any understanding on my (or anyone's) part about 
preferences that are not documented in the style guide. I don't mean to 
be thick, but I have to ask for clarity.


Given that this is a preference, and that there are reasons for -not- 
doing so, I would also like to hear other comments on this suggestionn.




+   for (i = start ; i <= end ; i++)



Missed {}



Wasn't sure about the M.O. given that the body of this loop is a single if
statement. And I don't see anywhere in
https://www.kernel.org/doc/html/latest/process/coding-style.html
in section 3.1 where curly braces are called for in this situation. May I
ask for clarification on the style rule, please?


You can do nothing, though I'm guided by the end of section 3.0
(though it tells only about 'if' case).


Fixed this.




@@ -89,6 +89,7 @@
   #define ACPI_DEVFLAG_ATSDIS 0x1000

   #define LOOP_TIMEOUT   10
+
   /*
* ACPI table definitions
*



Doesn't belong to the patch.



I'm sorry, I don't understand. The added blank line doesn't belong to the
patch?


Correct.


Fixed this.

Thanks,
Gary
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 5/5] iommu/amd - Add a debugfs entry to specify a IOMMU device table entry

2018-03-14 Thread Gary R Hook

On 03/13/2018 03:56 PM, Andy Shevchenko wrote:

On Tue, Mar 13, 2018 at 8:54 PM, Gary R Hook <gary.h...@amd.com> wrote:

On 03/13/2018 12:20 PM, Andy Shevchenko wrote:



+   } else if (obuf[0] == '0' && obuf[1] == 'x') {
+   n = sscanf(obuf, "%x", _iommu_devid);
+   } else {
+   n = sscanf(obuf, "%d", _iommu_devid);
+   }



kstrtoint() ?



I see various mechanisms for this sort of thing, and simply chose one.
Am happy to use whatever is preferred.


sscanf() has an enormous overhead for cases like this.

simple

ret = kstrtoint();
if (ret)
  ... do error handling ...




Gotcha. Fixed.

Thanks,
Gary
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 5/5] iommu/amd - Add a debugfs entry to specify a IOMMU device table entry

2018-03-13 Thread Gary R Hook

On 03/13/2018 12:20 PM, Andy Shevchenko wrote:



+   oboff += OSCNPRINTF("%02x:%02x:%x (%u / %04x)\n",
+   PCI_BUS_NUM(amd_iommu_devid),
+   PCI_SLOT(amd_iommu_devid),
+   PCI_FUNC(amd_iommu_devid),


Perhaps at some point we will have an extension to %p to print PCI BDFs.


But until then  ;-)


+   if (strnchr(obuf, OBUFLEN, ':'))
+   {


Style


D'oh!


+   } else if (obuf[0] == '0' && obuf[1] == 'x') {
+   n = sscanf(obuf, "%x", _iommu_devid);
+   } else {
+   n = sscanf(obuf, "%d", _iommu_devid);
+   }


kstrtoint() ?


I see various mechanisms for this sort of thing, and simply chose one.
Am happy to use whatever is preferred.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v2 1/5] iommu/amd - Add debugfs support

2018-03-13 Thread Gary R Hook

On 03/13/2018 12:16 PM, Andy Shevchenko wrote:

On Fri, Mar 9, 2018 at 2:50 AM, Gary R Hook <gary.h...@amd.com> wrote:


+   default n


Redundant


Roger that.


+#include 
+#include 
+#include 


Keep in order?


What order would that be? These few needed files are listed in the same
order as which they appear in amd_iommu.c. I'm gonna need a preference
spelled out, please (and a rationale, so I may better understand).


+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"



+/* DebugFS helpers */
+#defineOBUFP   (obuf + oboff)
+#defineOBUFLEN obuflen
+#defineOBUFSPC (OBUFLEN - oboff)
+#defineOSCNPRINTF(fmt, ...) \
+   scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)


I don't see any advantages of this. Other way around, they will simple
makes things hard to read an understand in place.


I used this technique in the CCP driver code (where it was accepted), in 
an effort to do the opposite of what you claim: make the code more 
readable. Given the 80 column limit, a large number of arguments, and 
very long statements, IMO something needs to give. I don't find the use 
of #defines to be obfuscating.


I'm not trying to argue, but rather simply state the perspective / 
reasoning I used to create a source file I feel is manageable. I have 17 
more iommu patches built upon this strategy, and this seems to be 
advantageous for all of them.






+   for (i = start ; i <= end ; i++)


Missed {}


Wasn't sure about the M.O. given that the body of this loop is a single 
if statement. And I don't see anywhere in

https://www.kernel.org/doc/html/latest/process/coding-style.html
in section 3.1 where curly braces are called for in this situation. May 
I ask for clarification on the style rule, please?





+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+   || amd_iommu_dev_table[i].data[1])
+   n++;
+   return n;
+}



+
+static ssize_t amd_iommu_debugfs_dtecount_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   struct amd_iommu *iommu = filp->private_data;



+   unsigned int obuflen = 512;


Sounds like way too much.


I can tune these up.




+   if (!iommu)
+   return 0;


When this possible?


It was intended as a sanity check, but if this happens, much worse has 
already gone wrong. I'll remove.





+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   n = amd_iommu_count_valid_dtes(0, 0x);
+   oboff += OSCNPRINTF("%d\n", n);



+   return ret;
+}




@@ -89,6 +89,7 @@
  #define ACPI_DEVFLAG_ATSDIS 0x1000

  #define LOOP_TIMEOUT   10
+
  /*
   * ACPI table definitions
   *


Doesn't belong to the patch.


I'm sorry, I don't understand. The added blank line doesn't belong to 
the patch?





+#endif
+
+


Extra unneeded line.


Thanks,

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 5/5] iommu/amd - Add a debugfs entry to specify a IOMMU device table entry

2018-03-08 Thread Gary R Hook
Initially (at boot) the device table values dumped are all of the
active devices.  Add a devid debugfs file to allow the user to select a
single device table entry to dump (active or not). Let any devid value
greater than the maximum allowable PCI ID (0x) restore the
behavior to that effective at boot.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |  109 ++---
 1 file changed, 100 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index c4e071f7a5b9..aa6935340163 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -28,6 +28,7 @@ static DEFINE_RWLOCK(iommu_debugfs_lock);
 #defineMAX_NAME_LEN20
 
 static unsigned int amd_iommu_verbose = 0;
+static unsigned int amd_iommu_devid = ~0;
 
 static unsigned int amd_iommu_count_valid_dtes(int start, int end)
 {
@@ -81,6 +82,76 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+static ssize_t amd_iommu_debugfs_devid_read(struct file *filp,
+   char __user *ubuf,
+   size_t count, loff_t *offp)
+{
+   struct amd_iommu *iommu = filp->private_data;
+   unsigned int obuflen = 512;
+   unsigned int oboff = 0;
+   ssize_t ret;
+   char *obuf;
+
+   if (!iommu)
+   return 0;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   if (amd_iommu_verbose)
+   oboff += OSCNPRINTF("%02x:%02x:%x (%u / %04x)\n",
+   PCI_BUS_NUM(amd_iommu_devid),
+   PCI_SLOT(amd_iommu_devid),
+   PCI_FUNC(amd_iommu_devid),
+   amd_iommu_devid, amd_iommu_devid);
+   else
+   oboff += OSCNPRINTF("%u\n", amd_iommu_devid);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static ssize_t amd_iommu_debugfs_devid_write(struct file *filp,
+   const char __user *ubuf,
+   size_t count, loff_t *offp)
+{
+   unsigned int pci_id, pci_slot, pci_func;
+   unsigned int obuflen = 80;
+   ssize_t ret;
+   char *obuf;
+   int n;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   ret = simple_write_to_buffer(obuf, OBUFLEN, offp, ubuf, count);
+
+   if (strnchr(obuf, OBUFLEN, ':'))
+   {
+   n = sscanf(obuf, "%x:%x.%x", _id, _slot, _func);
+   if (n == 3)
+   amd_iommu_devid = PCI_DEVID(pci_id, PCI_DEVFN(pci_slot, 
pci_func));
+   } else if (obuf[0] == '0' && obuf[1] == 'x') {
+   n = sscanf(obuf, "%x", _iommu_devid);
+   } else {
+   n = sscanf(obuf, "%d", _iommu_devid);
+   }
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_devid_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_devid_read,
+   .write = amd_iommu_debugfs_devid_write,
+};
+
 #defineMAX_PCI_ID  0x
 
 #definePRINTDTE(i) OSCNPRINTF("%02x:%02x:%x - %016llx %016llx 
%016llx %016llx\n", \
@@ -106,19 +177,28 @@ static ssize_t amd_iommu_debugfs_dte_read(struct file 
*filp,
return 0;
 
/* Count the number of valid entries in the device table */
-   istart = 0;
-   iend = MAX_PCI_ID;
-   n = amd_iommu_count_valid_dtes(istart, iend);
+   if (amd_iommu_devid > MAX_PCI_ID) {
+   istart = 0;
+   iend = MAX_PCI_ID;
+   n = amd_iommu_count_valid_dtes(istart, iend);
+   } else {
+   n = 1;
+   }
obuflen = n * 80;
 
obuf = kmalloc(OBUFLEN, GFP_KERNEL);
if (!obuf)
return -ENOMEM;
 
-   for (i = istart ; i <= iend ; i++)
-   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
-|| amd_iommu_dev_table[i].data[1])
-   oboff += PRINTDTE(i);
+   if (amd_iommu_devid > MAX_PCI_ID) {
+   for (i = istart ; i <= iend ; i++)
+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+|| amd_iommu_dev_table[i].data[1])
+   oboff += PRINTDTE(i);
+   } else {
+   i = amd_iommu_devid;
+   oboff += PRINTDTE(i);
+   }
 
ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
kfree(obuf);
@@ -135,12 +215,17 @@ static const struct file_operations 
amd_iommu_debugfs_dte_ops = {
 
 stat

[PATCH v2 4/5] iommu/amd - Expose the active IOMMU device table entries

2018-03-08 Thread Gary R Hook
Add a debugfs entry to dump the active device table entries from
the IOMMU's table. Active is determined by non-default values
in the first and second long words of the DTE. Aside from IOMMU
devices, this output should list every device reported by lspci.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   64 +
 1 file changed, 64 insertions(+)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 79945ce1199d..c4e071f7a5b9 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -81,9 +81,66 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+#defineMAX_PCI_ID  0x
+
+#definePRINTDTE(i) OSCNPRINTF("%02x:%02x:%x - %016llx %016llx 
%016llx %016llx\n", \
+  PCI_BUS_NUM(i), PCI_SLOT(i), PCI_FUNC(i), \
+  amd_iommu_dev_table[i].data[0], \
+  amd_iommu_dev_table[i].data[1], \
+  amd_iommu_dev_table[i].data[2], \
+  amd_iommu_dev_table[i].data[3]);
+
+static ssize_t amd_iommu_debugfs_dte_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   struct amd_iommu *iommu = filp->private_data;
+   unsigned int obuflen;
+   unsigned int oboff = 0;
+   unsigned int istart, iend;
+   ssize_t ret;
+   u32 i, n;
+   char *obuf;
+
+   if (!iommu)
+   return 0;
+
+   /* Count the number of valid entries in the device table */
+   istart = 0;
+   iend = MAX_PCI_ID;
+   n = amd_iommu_count_valid_dtes(istart, iend);
+   obuflen = n * 80;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   for (i = istart ; i <= iend ; i++)
+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+|| amd_iommu_dev_table[i].data[1])
+   oboff += PRINTDTE(i);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_dte_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_dte_read,
+   .write = NULL,
+};
+
 static char readmetext[] =
+"devicetable Print active entries in the device table\n"
 "count   Count of active devices\n"
 "verbose Provide additional descriptive text\n"
+"\n"
+"Dumping the Device Table\n"
+"The device table is scanned for entries that appear to be active. The\n"
+"default range is from 0 to 0x, and only active entries will be reported\n"
 "\n";
 
 static ssize_t amd_iommu_debugfs_readme_read(struct file *filp,
@@ -134,6 +191,13 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!d_verbose)
goto err;
 
+   /* Device Table Entries */
+   d_dte = debugfs_create_file("devicetable", 0400,
+   iommu->debugfs_instance, iommu,
+   _iommu_debugfs_dte_ops);
+   if (!d_dte)
+   goto err;
+
d_dte = debugfs_create_file("count", 0400,
iommu->debugfs_instance, iommu,
_iommu_debugfs_dtecount_ops);

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 2/5] iommu/amd - Add a 'verbose' switch for IOMMU debugfs

2018-03-08 Thread Gary R Hook
Enable more descriptive debugfs output via a 'verbose' variable.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index b0395a47bc32..481f4d86f8f8 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -27,6 +27,8 @@ static DEFINE_RWLOCK(iommu_debugfs_lock);
 
 #defineMAX_NAME_LEN20
 
+static unsigned int amd_iommu_verbose = 0;
+
 static unsigned int amd_iommu_count_valid_dtes(int start, int end)
 {
unsigned int n = 0;
@@ -61,7 +63,10 @@ static ssize_t amd_iommu_debugfs_dtecount_read(struct file 
*filp,
return -ENOMEM;
 
n = amd_iommu_count_valid_dtes(0, 0x);
-   oboff += OSCNPRINTF("%d\n", n);
+   if (amd_iommu_verbose)
+   oboff += OSCNPRINTF("# DTEs:  %d\n", n);
+   else
+   oboff += OSCNPRINTF("%d\n", n);
 
ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
kfree(obuf);
@@ -79,6 +84,7 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
 void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
 {
char name[MAX_NAME_LEN + 1];
+   struct dentry *d_verbose;
struct dentry *d_dte;
unsigned long flags;
 
@@ -97,6 +103,12 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!iommu->debugfs_instance)
goto err;
 
+   d_verbose = debugfs_create_u32("verbose", 0600,
+  iommu->debugfs_instance,
+  _iommu_verbose);
+   if (!d_verbose)
+   goto err;
+
d_dte = debugfs_create_file("count", 0400,
iommu->debugfs_instance, iommu,
_iommu_debugfs_dtecount_ops);

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 3/5] iommu/amd - Add a README variable for the IOMMU debugfs

2018-03-08 Thread Gary R Hook
Provide help text via a filesystem entry

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 481f4d86f8f8..79945ce1199d 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -81,6 +81,31 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+static char readmetext[] =
+"count   Count of active devices\n"
+"verbose Provide additional descriptive text\n"
+"\n";
+
+static ssize_t amd_iommu_debugfs_readme_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   ssize_t ret;
+
+   ret = simple_read_from_buffer(ubuf, count, offp,
+ readmetext, strlen(readmetext));
+
+   return ret;
+}
+
+
+static const struct file_operations amd_iommu_debugfs_readme_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_readme_read,
+   .write = NULL,
+};
+
 void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
 {
char name[MAX_NAME_LEN + 1];
@@ -115,6 +140,12 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!d_dte)
goto err;
 
+   d_dte = debugfs_create_file("README", 0400,
+   iommu->debugfs_instance, iommu,
+   _iommu_debugfs_readme_ops);
+   if (!d_dte)
+   goto err;
+
return;
 
 err:

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2 1/5] iommu/amd - Add debugfs support

2018-03-08 Thread Gary R Hook
Expose the IOMMU MMIO registers and device table

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |8 +++
 drivers/iommu/Makefile|1 
 drivers/iommu/amd_iommu_debugfs.c |  112 +
 drivers/iommu/amd_iommu_init.c|7 ++
 drivers/iommu/amd_iommu_proto.h   |7 ++
 drivers/iommu/amd_iommu_types.h   |3 +
 6 files changed, 136 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..0fa85e73d5dd 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -135,6 +135,14 @@ config AMD_IOMMU_V2
  hardware. Select this option if you want to use devices that support
  the PCI PRI and PASID interface.
 
+config AMD_IOMMU_DEBUG
+   bool "Expose AMD IOMMU internals in DebugFS"
+   depends on AMD_IOMMU && DEBUG_FS
+   default n
+   help
+ Provides debugfs access to IOMMU data such as registers and device
+ table entries.
+
 # Intel IOMMU support
 config DMAR_TABLE
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..64fba8b1ca4f 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..b0395a47bc32
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+/* DebugFS helpers */
+#defineOBUFP   (obuf + oboff)
+#defineOBUFLEN obuflen
+#defineOBUFSPC (OBUFLEN - oboff)
+#defineOSCNPRINTF(fmt, ...) \
+   scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
+
+static struct dentry *iommu_debugfs_dir;
+static DEFINE_RWLOCK(iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+static unsigned int amd_iommu_count_valid_dtes(int start, int end)
+{
+   unsigned int n = 0;
+   int i;
+
+   /* Scan the DTE table from entry 'start' through entry 'end' for
+* active entries
+*/
+   for (i = start ; i <= end ; i++)
+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+   || amd_iommu_dev_table[i].data[1])
+   n++;
+   return n;
+}
+
+static ssize_t amd_iommu_debugfs_dtecount_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   struct amd_iommu *iommu = filp->private_data;
+   unsigned int obuflen = 512;
+   unsigned int oboff = 0;
+   unsigned int n;
+   ssize_t ret;
+   char *obuf;
+
+   if (!iommu)
+   return 0;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   n = amd_iommu_count_valid_dtes(0, 0x);
+   oboff += OSCNPRINTF("%d\n", n);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_dtecount_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_dtecount_read,
+   .write = NULL,
+};
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_dte;
+   unsigned long flags;
+
+   if (!debugfs_initialized())
+   return;
+
+   write_lock_irqsave(_debugfs_lock, flags);
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+   write_unlock_irqrestore(_debugfs_lock, flags);
+   if (!iommu_debugfs_dir)
+   goto err;
+
+   snprintf(name, MAX_NAME_LEN, "iommu%02x", iommu->index);
+   iommu->debugfs_instance = debugfs_create_dir(name, iommu_debugfs_dir);
+   if (!iommu->debugfs_instance)
+   goto err;
+
+   d_dte = debugfs_create_file("count", 0400,
+   iommu->debugfs_instance, iommu,
+   _iommu_debugfs_dtecount_ops);
+   if (!d_dte)
+   goto err;
+
+   

[PATCH v2 0/5] Add debugfs info for the AMD IOMMU

2018-03-08 Thread Gary R Hook
The following series creates a debugfs directory for AMD IOMMUs,
constructs a framework for additional entries, an online README,
and a method for dumping device table entries. Data is reported
in a default concise mode, but a verbose mode is enabled via a
filesystem entry.

This is the first of three patch series that will expose a number
of IOMMU registers.

Changes since v1:
- Correctly use CONFIG_AMD_IOMMU_DEBUG in Makefile and header file

---

Gary R Hook (5):
  iommu/amd - Add debugfs support
  iommu/amd - Add a 'verbose' switch for IOMMU debugfs
  iommu/amd - Add a README variable for the IOMMU debugfs
  iommu/amd - Expose the active IOMMU device table entries
  iommu/amd - Add a debugfs entry to specify a IOMMU device table entry


 drivers/iommu/Kconfig |8 +
 drivers/iommu/Makefile|1 
 drivers/iommu/amd_iommu_debugfs.c |  310 +
 drivers/iommu/amd_iommu_init.c|7 +
 drivers/iommu/amd_iommu_proto.h   |7 +
 drivers/iommu/amd_iommu_types.h   |3 
 6 files changed, 334 insertions(+), 2 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH v2] iommu/amd - Use dev_err to send events to the system log

2018-03-08 Thread Gary R Hook
Remove printk and use a more preferable error logging function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c |   55 +++--
 1 file changed, 28 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 7389cc15d97a..7f4e82aed6a0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -547,6 +547,7 @@ static void amd_iommu_report_page_fault(u16 devid, u16 
domain_id,
 
 static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
 {
+   struct device *dev = iommu->iommu.dev;
int type, devid, domid, flags;
volatile u32 *event = __evt;
int count = 0;
@@ -573,53 +574,53 @@ static void iommu_print_event(struct amd_iommu *iommu, 
void *__evt)
amd_iommu_report_page_fault(devid, domid, address, flags);
return;
} else {
-   printk(KERN_ERR "AMD-Vi: Event logged [");
+   dev_err(dev, "AMD-Vi: Event logged [");
}
 
switch (type) {
case EVENT_TYPE_ILL_DEV:
-   printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
-  "address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address, flags);
+   dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
+   "address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address, flags);
dump_dte_entry(devid);
break;
case EVENT_TYPE_DEV_TAB_ERR:
-   printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
-  "address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address, flags);
+   dev_err(dev, "DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+   "address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address, flags);
break;
case EVENT_TYPE_PAGE_TAB_ERR:
-   printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
-  "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  domid, address, flags);
+   dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+   "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   domid, address, flags);
break;
case EVENT_TYPE_ILL_CMD:
-   printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+   dev_err(dev, "ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", 
address);
dump_command(address);
break;
case EVENT_TYPE_CMD_HARD_ERR:
-   printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
-  "flags=0x%04x]\n", address, flags);
+   dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx "
+   "flags=0x%04x]\n", address, flags);
break;
case EVENT_TYPE_IOTLB_INV_TO:
-   printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
-  "address=0x%016llx]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address);
+   dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
+   "address=0x%016llx]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address);
break;
case EVENT_TYPE_INV_DEV_REQ:
-   printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
-  "address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address, flags);
+   dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
+   "address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address, flags);
break;
default:
-   printk(KERN_ERR "UNKNOWN type=0x%02x event[0]=0x%08x "
-  "event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n",
-  

[PATCH] iommu/amd - Use dev_err to send events to the system log

2018-01-30 Thread Gary R Hook
Remove printk and use a more preferable error logging function.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c |   56 +++--
 1 file changed, 29 insertions(+), 27 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index b58e0a745b7f..90a61f546bac 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -546,6 +546,8 @@ static void amd_iommu_report_page_fault(u16 devid, u16 
domain_id,
 
 static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
 {
+   struct pci_dev *pdev = iommu->dev;
+   struct device *dev = >dev;
int type, devid, domid, flags;
volatile u32 *event = __evt;
int count = 0;
@@ -572,53 +574,53 @@ static void iommu_print_event(struct amd_iommu *iommu, 
void *__evt)
amd_iommu_report_page_fault(devid, domid, address, flags);
return;
} else {
-   printk(KERN_ERR "AMD-Vi: Event logged [");
+   dev_err(dev, "AMD-Vi: Event logged [");
}
 
switch (type) {
case EVENT_TYPE_ILL_DEV:
-   printk("ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
-  "address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address, flags);
+   dev_err(dev, "ILLEGAL_DEV_TABLE_ENTRY device=%02x:%02x.%x "
+   "address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address, flags);
dump_dte_entry(devid);
break;
case EVENT_TYPE_DEV_TAB_ERR:
-   printk("DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
-  "address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address, flags);
+   dev_err(dev, "DEV_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+   "address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address, flags);
break;
case EVENT_TYPE_PAGE_TAB_ERR:
-   printk("PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
-  "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  domid, address, flags);
+   dev_err(dev, "PAGE_TAB_HARDWARE_ERROR device=%02x:%02x.%x "
+   "domain=0x%04x address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   domid, address, flags);
break;
case EVENT_TYPE_ILL_CMD:
-   printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
+   dev_err(dev, "ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", 
address);
dump_command(address);
break;
case EVENT_TYPE_CMD_HARD_ERR:
-   printk("COMMAND_HARDWARE_ERROR address=0x%016llx "
-  "flags=0x%04x]\n", address, flags);
+   dev_err(dev, "COMMAND_HARDWARE_ERROR address=0x%016llx "
+   "flags=0x%04x]\n", address, flags);
break;
case EVENT_TYPE_IOTLB_INV_TO:
-   printk("IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
-  "address=0x%016llx]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address);
+   dev_err(dev, "IOTLB_INV_TIMEOUT device=%02x:%02x.%x "
+   "address=0x%016llx]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address);
break;
case EVENT_TYPE_INV_DEV_REQ:
-   printk("INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
-  "address=0x%016llx flags=0x%04x]\n",
-  PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
-  address, flags);
+   dev_err(dev, "INVALID_DEVICE_REQUEST device=%02x:%02x.%x "
+   "address=0x%016llx flags=0x%04x]\n",
+   PCI_BUS_NUM(devid), PCI_SLOT(devid), PCI_FUNC(devid),
+   address, flags);
break;
default:
-   printk(KERN_ERR "UNKNOWN type=0x%02x event[0]=0x%08x "
-  "event[1]=0x%08x ev

Re: [PATCH 1/5] iommu/amd - Add debugfs support

2018-01-29 Thread Gary R Hook

On 01/26/2018 06:00 PM, Borislav Petkov wrote:

On Fri, Jan 26, 2018 at 05:52:15PM -0600, Gary R Hook wrote:

--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -135,6 +135,15 @@ config AMD_IOMMU_V2
  hardware. Select this option if you want to use devices that support
  the PCI PRI and PASID interface.
  
+config AMD_IOMMU_DEBUG

+   bool "Expose AMD IOMMU internals in DebugFS"
+   depends on AMD_IOMMU && DEBUG_FS
+   default n
+   help
+ With this option you can enable access to AMD IOMMU registers and
+ data structures through debugfs. Select this to see information
+ about the internal state of the device.
+
  # Intel IOMMU support
  config DMAR_TABLE
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..d9e9ed5f6cfc 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
  obj-$(CONFIG_IOMMU_IOVA) += iova.o
  obj-$(CONFIG_OF_IOMMU)+= of_iommu.o
  obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
-obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_debugfs.o


That looks like it needs to be:

obj-$(CONFIG_AMD_IOMMU_DEBUG) += amd_iommu_debugfs.o


Of course. Thanks, Boris. I'll get that in v2.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 5/5] iommu/amd - Add a debugfs entry to specify a IOMMU device table entry

2018-01-26 Thread Gary R Hook
Initially (at boot) the device table values dumped are all of the
active devices.  Add a devid debugfs file to allow the user to select a
single device table entry to dump (active or not). Let any devid value
greater than the maximum allowable PCI ID (0x) restore the
behavior to that effective at boot.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |  127 -
 1 file changed, 109 insertions(+), 18 deletions(-)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 87840ae9889d..efb666873daa 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -38,6 +38,7 @@ static DEFINE_RWLOCK(iommu_debugfs_lock);
 #defineMAX_NAME_LEN20
 
 static unsigned int amd_iommu_verbose;
+static unsigned int amd_iommu_devid = ~0;
 
 static unsigned int amd_iommu_count_valid_dtes(int start, int end)
 {
@@ -91,6 +92,72 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+static ssize_t amd_iommu_debugfs_devid_read(struct file *filp,
+   char __user *ubuf,
+   size_t count, loff_t *offp)
+{
+   struct amd_iommu *iommu = filp->private_data;
+   unsigned int obuflen = 512;
+   unsigned int oboff = 0;
+   ssize_t ret;
+   char *obuf;
+
+   if (!iommu)
+   return 0;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   if (amd_iommu_verbose)
+   oboff += OSCNPRINTF("%02x:%02x.%x 0x%04x %u\n",
+   PCI_BUS_NUM(amd_iommu_devid),
+   PCI_SLOT(amd_iommu_devid),
+   PCI_FUNC(amd_iommu_devid),
+   amd_iommu_devid, amd_iommu_devid);
+   else
+   oboff += OSCNPRINTF("%u\n", amd_iommu_devid);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static ssize_t amd_iommu_debugfs_devid_write(struct file *filp,
+   const char __user *ubuf,
+   size_t count, loff_t *offp)
+{
+   unsigned int pci_id, pci_slot, pci_func;
+   unsigned int obuflen = 80;
+   ssize_t ret;
+   char *obuf;
+   int n;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   ret = simple_write_to_buffer(obuf, OBUFLEN, offp, ubuf, count);
+
+   if (strnchr(obuf, OBUFLEN, ':')) {
+   n = sscanf(obuf, "%x:%x.%x", _id, _slot, _func);
+   if (n == 3)
+   amd_iommu_devid = PCI_DEVID(pci_id, PCI_DEVFN(pci_slot, 
pci_func));
+   } else
+   n = kstrtouint(obuf, 0, _iommu_devid);
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_devid_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_devid_read,
+   .write = amd_iommu_debugfs_devid_write,
+};
+
 struct bits {
uint bit;
uint len;
@@ -211,9 +278,13 @@ static ssize_t amd_iommu_debugfs_dte_read(struct file 
*filp,
return 0;
 
/* Count the number of valid entries in the device table */
-   istart = 0;
-   iend = MAX_PCI_ID;
-   n = amd_iommu_count_valid_dtes(istart, iend);
+   if (amd_iommu_devid > MAX_PCI_ID) {
+   istart = 0;
+   iend = MAX_PCI_ID;
+   n = amd_iommu_count_valid_dtes(istart, iend);
+   } else {
+   n = 1;
+   }
if (amd_iommu_verbose)
obuflen = n * 2048;
else
@@ -223,20 +294,29 @@ static ssize_t amd_iommu_debugfs_dte_read(struct file 
*filp,
if (!obuf)
return -ENOMEM;
 
-   for (i = istart ; i <= iend ; i++)
-   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
-|| amd_iommu_dev_table[i].data[1]) {
-   if (amd_iommu_verbose) {
-   oboff += OSCNPRINTF("Device %02x:%02x.%x\n",
-   PCI_BUS_NUM(i),
-   PCI_SLOT(i),
-   PCI_FUNC(i));
-   amd_iommu_print_dte_verbose(i, ,
-   , );
-   } else {
-   oboff += PRINTDTE(i);
+   if (amd_iommu_devid > MAX_PCI_ID) {
+   for (i = istart ; i <= iend ; i++)
+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+|| amd_iommu_dev_table[i].dat

[PATCH 4/5] iommu/amd - Expose the active IOMMU device table entries

2018-01-26 Thread Gary R Hook
Add a debugfs entry to dump the active device table entries from
the IOMMU's table. 'Active' is determined by non-default values
in the first and second long words of the DTE. Aside from IOMMU
devices, this output should list every device reported by lspci.

Use arrays to store DTE bit field definitions for debugfs printing
in verbose mode

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |  182 +
 1 file changed, 182 insertions(+)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 5066d3976912..87840ae9889d 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -22,6 +22,16 @@
 #defineOSCNPRINTF(fmt, ...) \
scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
 
+#defineMAX_PCI_ID  0x
+
+#definePRINTDTE(i) OSCNPRINTF("%02x:%02x:%x - " \
+  "%016llx %016llx %016llx %016llx\n", \
+  PCI_BUS_NUM(i), PCI_SLOT(i), PCI_FUNC(i), \
+  amd_iommu_dev_table[i].data[0], \
+  amd_iommu_dev_table[i].data[1], \
+  amd_iommu_dev_table[i].data[2], \
+  amd_iommu_dev_table[i].data[3])
+
 static struct dentry *iommu_debugfs_dir;
 static DEFINE_RWLOCK(iommu_debugfs_lock);
 
@@ -81,9 +91,174 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+struct bits {
+   uint bit;
+   uint len;
+   char *lbl;
+   char *note;
+};
+
+static struct bits dte_lft[] = {
+   {  0, 1, "V:", "[0]" },
+   {  1, 1, "TV:", "[1]" },
+   {  7, 2, "Host Access Dirty:", "[8:7]" },
+   {  9, 3, "Paging Mode:", "[11:9]" },
+   { 52, 1, "PPR:", "[52]" },
+   { 53, 1, "GPRP:", "[53]" },
+   { 54, 1, "GIoV:", "[54]" },
+   { 55, 1, "GV:", "[55]" },
+   { 56, 2, "GLX:", "[57:56]" },
+   { 61, 1, "IR:", "[61]" },
+   { 62, 1, "IW:", "[62]" },
+   { 96, 1, "I:", "[96]" },
+   { 97, 1, "SE:", "[97]" },
+   { 98, 1, "SA:", "[98]" },
+   { 99, 2, "IOCtl:", "[100:99]" },
+};
+static uint lftlen = sizeof(dte_lft) / sizeof(struct bits);
+
+static struct bits dte_rght[] = {
+   { 101, 1, "Cache:", "[101]" },
+   { 102, 1, "SD:", "[102]" },
+   { 103, 1, "EX  :", "[103]" },
+   { 104, 2, "SysMgt:", "[105:104]" },
+   { 128, 1, "IV:", "[128]" },
+   { 129, 4, "IntTabLen:", "[132:129]" },
+   { 133, 1, "IG:", "[133]" },
+   { 184, 1, "InitPass:", "[184]" },
+   { 185, 1, "EIntPass:", "[185]" },
+   { 186, 1, "NMIPass:", "[186]" },
+   { 188, 2, "IntClt:", "[189:188]" },
+   { 190, 1, "Lint0Pass:", "[190]" },
+   { 191, 1, "Lint1Pass:", "[191]" },
+   { 246, 1, "AttrV:", "[246]" },
+   { 247, 1, "Mode0FC:", "[247]" },
+};
+static uint rghtlen = sizeof(dte_rght) / sizeof(struct bits);
+
+#defineDTE_BIT(ds, p, n)   ((ds[p/64] >> (p%64)) & ((1ULL<<n) - 1))
+
+static void amd_iommu_print_dte_verbose(int devidx, char **buf,
+   unsigned int *buflen,
+   unsigned int *offset)
+{
+   u64 *dte = amd_iommu_dev_table[devidx].data;
+   u64 part1, part2, part3;
+   unsigned int obuflen = *buflen;
+   unsigned int oboff = *offset;
+   struct bits *lft, *rght;
+   char *obuf = *buf;
+   uint max;
+   int j;
+
+   max = lftlen > rghtlen ? lftlen : rghtlen;
+
+   for (j = 0; j < max ; j++) {
+   lft = _lft[j];
+   if (j < lftlen)
+   oboff += OSCNPRINTF("%-19s%3llx %*s", lft->lbl,
+   DTE_BIT(dte, lft->bit, lft->len),
+   (j < rghtlen) ? -16 : 1,
+   lft->note);
+   else
+   oboff += OSCNPRINTF("%38s", "");
+
+   rght = _rght[j];
+   if (j < rghtlen)
+   oboff += OSCNPRINTF("%-19s%3llx %s\n", rght->lbl,
+

[PATCH 1/5] iommu/amd - Add debugfs support

2018-01-26 Thread Gary R Hook
Create the basic debugfs functions. Expose a count of IOMMU device
table entries that appear to be in use.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/Kconfig |9 +++
 drivers/iommu/Makefile|2 -
 drivers/iommu/amd_iommu_debugfs.c |  112 +
 drivers/iommu/amd_iommu_init.c|7 ++
 drivers/iommu/amd_iommu_proto.h   |6 ++
 drivers/iommu/amd_iommu_types.h   |3 +
 6 files changed, 136 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..7753989b6be7 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -135,6 +135,15 @@ config AMD_IOMMU_V2
  hardware. Select this option if you want to use devices that support
  the PCI PRI and PASID interface.
 
+config AMD_IOMMU_DEBUG
+   bool "Expose AMD IOMMU internals in DebugFS"
+   depends on AMD_IOMMU && DEBUG_FS
+   default n
+   help
+ With this option you can enable access to AMD IOMMU registers and
+ data structures through debugfs. Select this to see information
+ about the internal state of the device.
+
 # Intel IOMMU support
 config DMAR_TABLE
bool
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb695854809..d9e9ed5f6cfc 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
-obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
 obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
new file mode 100644
index ..18f70934961d
--- /dev/null
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * AMD IOMMU driver
+ *
+ * Copyright (C) 2018 Advanced Micro Devices, Inc.
+ *
+ * Author: Gary R Hook <gary.h...@amd.com>
+ */
+
+#ifdef CONFIG_DEBUG_FS
+
+#include 
+#include 
+#include 
+#include "amd_iommu_proto.h"
+#include "amd_iommu_types.h"
+
+/* DebugFS helpers */
+#defineOBUFP   (obuf + oboff)
+#defineOBUFLEN obuflen
+#defineOBUFSPC (OBUFLEN - oboff)
+#defineOSCNPRINTF(fmt, ...) \
+   scnprintf(OBUFP, OBUFSPC, fmt, ## __VA_ARGS__)
+
+static struct dentry *iommu_debugfs_dir;
+static DEFINE_RWLOCK(iommu_debugfs_lock);
+
+#defineMAX_NAME_LEN20
+
+static unsigned int amd_iommu_count_valid_dtes(int start, int end)
+{
+   unsigned int n = 0;
+   int i;
+
+   /* Scan the DTE table from entry 'start' through entry 'end' for
+* active entries
+*/
+   for (i = start ; i <= end ; i++)
+   if ((amd_iommu_dev_table[i].data[0] ^ 0x3)
+|| amd_iommu_dev_table[i].data[1])
+   n++;
+   return n;
+}
+
+static ssize_t amd_iommu_debugfs_dtecount_read(struct file *filp,
+  char __user *ubuf,
+  size_t count, loff_t *offp)
+{
+   struct amd_iommu *iommu = filp->private_data;
+   unsigned int obuflen = 512;
+   unsigned int oboff = 0;
+   unsigned int n;
+   ssize_t ret;
+   char *obuf;
+
+   if (!iommu)
+   return 0;
+
+   obuf = kmalloc(OBUFLEN, GFP_KERNEL);
+   if (!obuf)
+   return -ENOMEM;
+
+   n = amd_iommu_count_valid_dtes(0, 0x);
+   oboff += OSCNPRINTF("%d\n", n);
+
+   ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
+   kfree(obuf);
+
+   return ret;
+}
+
+static const struct file_operations amd_iommu_debugfs_dtecount_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_dtecount_read,
+   .write = NULL,
+};
+
+void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
+{
+   char name[MAX_NAME_LEN + 1];
+   struct dentry *d_dte;
+   unsigned long flags;
+
+   if (!debugfs_initialized())
+   return;
+
+   write_lock_irqsave(_debugfs_lock, flags);
+   if (!iommu_debugfs_dir)
+   iommu_debugfs_dir = debugfs_create_dir("amd-iommu", NULL);
+   write_unlock_irqrestore(_debugfs_lock, flags);
+   if (!iommu_debugfs_dir)
+   goto err;
+
+   snprintf(name, MAX_NAME_LEN, "iommu%02d", iommu->index);
+   iommu->debugfs_instance = debugfs_create_dir(name, iommu_debugfs_dir);
+   if (!iommu->debugfs_instance)
+   goto err;

[PATCH 3/5] iommu/amd - Add a README variable for the IOMMU debugfs

2018-01-26 Thread Gary R Hook
Provide help text via a filesystem entry

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   31 +++
 1 file changed, 31 insertions(+)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index c449f3a7452c..5066d3976912 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -81,6 +81,31 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
.write = NULL,
 };
 
+static char readmetext[] =
+"count   Count of active devices\n"
+"verbose Provide additional descriptive text\n"
+"\n";
+
+static ssize_t amd_iommu_debugfs_readme_read(struct file *filp,
+ char __user *ubuf,
+ size_t count, loff_t *offp)
+{
+   ssize_t ret;
+
+   ret = simple_read_from_buffer(ubuf, count, offp,
+ readmetext, strlen(readmetext));
+
+   return ret;
+}
+
+
+static const struct file_operations amd_iommu_debugfs_readme_ops = {
+   .owner = THIS_MODULE,
+   .open = simple_open,
+   .read = amd_iommu_debugfs_readme_read,
+   .write = NULL,
+};
+
 void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
 {
char name[MAX_NAME_LEN + 1];
@@ -115,6 +140,12 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!d_dte)
goto err;
 
+   d_dte = debugfs_create_file("README", 0400,
+   iommu->debugfs_instance, iommu,
+   _iommu_debugfs_readme_ops);
+   if (!d_dte)
+   goto err;
+
return;
 
 err:

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 0/5] Add debugfs info for the AMD IOMMU

2018-01-26 Thread Gary R Hook
The following series creates a debugfs directory for AMD IOMMUs,
constructs a framework for additional entries, an online README,
and a method for dumping device table entries. Data is reported
in a default concise mode, but a verbose mode is enabled via a
filesystem entry.

This is the first of three patch series that will expose a number
of IOMMU registers.

---

Gary R Hook (5):
  iommu/amd - Add debugfs support
  iommu/amd - Add a 'verbose' switch for IOMMU debugfs
  iommu/amd - Add a README variable for the IOMMU debugfs
  iommu/amd - Expose the active IOMMU device table entries
  iommu/amd - Add a debugfs entry to specify a IOMMU device table entry


 drivers/iommu/Kconfig |9 +
 drivers/iommu/Makefile|2 
 drivers/iommu/amd_iommu_debugfs.c |  428 +
 drivers/iommu/amd_iommu_init.c|7 -
 drivers/iommu/amd_iommu_proto.h   |6 +
 drivers/iommu/amd_iommu_types.h   |3 
 6 files changed, 452 insertions(+), 3 deletions(-)
 create mode 100644 drivers/iommu/amd_iommu_debugfs.c

--
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH 2/5] iommu/amd - Add a 'verbose' switch for IOMMU debugfs

2018-01-26 Thread Gary R Hook
Enable more descriptive debugfs output via a 'verbose' variable.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu_debugfs.c |   14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu_debugfs.c 
b/drivers/iommu/amd_iommu_debugfs.c
index 18f70934961d..c449f3a7452c 100644
--- a/drivers/iommu/amd_iommu_debugfs.c
+++ b/drivers/iommu/amd_iommu_debugfs.c
@@ -27,6 +27,8 @@ static DEFINE_RWLOCK(iommu_debugfs_lock);
 
 #defineMAX_NAME_LEN20
 
+static unsigned int amd_iommu_verbose;
+
 static unsigned int amd_iommu_count_valid_dtes(int start, int end)
 {
unsigned int n = 0;
@@ -61,7 +63,10 @@ static ssize_t amd_iommu_debugfs_dtecount_read(struct file 
*filp,
return -ENOMEM;
 
n = amd_iommu_count_valid_dtes(0, 0x);
-   oboff += OSCNPRINTF("%d\n", n);
+   if (amd_iommu_verbose)
+   oboff += OSCNPRINTF("# DTEs:  %d\n", n);
+   else
+   oboff += OSCNPRINTF("%d\n", n);
 
ret = simple_read_from_buffer(ubuf, count, offp, obuf, oboff);
kfree(obuf);
@@ -79,6 +84,7 @@ static const struct file_operations 
amd_iommu_debugfs_dtecount_ops = {
 void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
 {
char name[MAX_NAME_LEN + 1];
+   struct dentry *d_verbose;
struct dentry *d_dte;
unsigned long flags;
 
@@ -97,6 +103,12 @@ void amd_iommu_debugfs_setup(struct amd_iommu *iommu)
if (!iommu->debugfs_instance)
goto err;
 
+   d_verbose = debugfs_create_u32("verbose", 0600,
+  iommu->debugfs_instance,
+  _iommu_verbose);
+   if (!d_verbose)
+   goto err;
+
d_dte = debugfs_create_file("count", 0400,
iommu->debugfs_instance, iommu,
_iommu_debugfs_dtecount_ops);

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v6 2/5] iommu/vt-d: Add debugfs support to show context internals

2018-01-10 Thread Gary R Hook

On 01/09/2018 09:48 PM, Sohil Mehta wrote:

From: Gayatri Kammela 

IOMMU internals states such as root and context can be exported to the
userspace.

Example of such dump in Kabylake:

root@OTC-KBLH-01:~# cat
/sys/kernel/debug/intel_iommu/dmar_translation_struct

IOMMU dmar0: Extended Root Table Addr:402b9e800
Extended Root table entries:
Bus 0 L: 402150001 H: 0
Lower Context table entries for Bus: 0
[entry] DID :B :D .FLow High
[80]:00:0a.00   40214fa05   102
Higher Context table entries for Bus: 0
[80]:00:0a.00   4026c   0

IOMMU dmar1:Root Table Addr:4558a3000
  Root tbl entries:
Bus 0 L: 4558aa001 H: 0
  Context table entries for Bus: 0
[entry] DID :B :D .FLow High
[160]   :00:14.00   4558a9001   102
[184]   :00:17.00   400eac001   302
[248]   :00:1f.00   4558af001   202
[251]   :00:1f.03   40070e001   502
[254]   :00:1f.06   4467c9001   602
  Root tbl entries:
Bus 1 L: 3fc8c2001 H: 0
  Context table entries for Bus: 1
[entry] DID :B :D .FLow High
[0] :01:00.00   3fc8c3001   402

Cc: Sohil Mehta 
Cc: Fenghua Yu 
Cc: Ashok Raj 
Signed-off-by: Jacob Pan 
Signed-off-by: Gayatri Kammela 
---

v6: Change the order of includes to an alphabetical order
 Change seq_printf formatting

v5: Change to a SPDX license tag
 Fix seq_printf formatting

v4: Remove the unused function parameter
 Fix checkpatch.pl warnings
 Remove error reporting for debugfs_create_file function
 Fix unnecessary reprogramming of the context entries
 Simplify and merge the show context and extended context patch into one
 Remove redundant IOMMU null check under for_each_active_iommu

v3: Add a macro for seq file operations
 Change the intel_iommu_ctx file name to dmar_translation_struct

v2: No change

  drivers/iommu/Makefile|   1 +
  drivers/iommu/intel-iommu-debug.c | 139 ++
  drivers/iommu/intel-iommu.c   |   4 ++
  3 files changed, 144 insertions(+)
  create mode 100644 drivers/iommu/intel-iommu-debug.c

diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index 1fb6958..fdbaf46 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
  obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
  obj-$(CONFIG_DMAR_TABLE) += dmar.o
  obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o
+obj-$(CONFIG_INTEL_IOMMU_DEBUG) += intel-iommu-debug.o
  obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
  obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
  obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
diff --git a/drivers/iommu/intel-iommu-debug.c 
b/drivers/iommu/intel-iommu-debug.c
new file mode 100644
index 000..d5b0eea
--- /dev/null
+++ b/drivers/iommu/intel-iommu-debug.c
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright © 2017 Intel Corporation.
+ *
+ * Authors: Gayatri Kammela 
+ *  Jacob Pan 
+ *
+ */
+
+#define pr_fmt(fmt) "INTEL_IOMMU: " fmt
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "irq_remapping.h"
+
+#define TOTAL_BUS_NR (256) /* full bus range 256 */
+#define DEFINE_SHOW_ATTRIBUTE(__name)  \
+static int __name ## _open(struct inode *inode, struct file *file) \
+{  \
+   return single_open(file, __name ## _show, inode->i_private); \
+}  \
+static const struct file_operations __name ## _fops =  \
+{  \
+   .open   = __name ## _open,  \
+   .read   = seq_read, \
+   .llseek = seq_lseek,\
+   .release= single_release,   \
+   .owner  = THIS_MODULE,  \
+}
+
+static void ctx_tbl_entry_show(struct seq_file *m, struct intel_iommu *iommu,
+  int bus, bool ext, bool new_ext)
+{
+   struct context_entry *context;
+   int ctx;
+   unsigned long flags;
+
+   seq_printf(m, "%s Context table entries for Bus: %d\n",
+  ext ? "Lower" : "", bus);
+   seq_puts(m, "[entry]\tDID :B :D .F\tLow\t\tHigh\n");
+
+   spin_lock_irqsave(>lock, flags);
+
+   /* Publish either context entries or extended contenxt entries */


   typo




Re: [PATCH V4 11/26] iommu/amd: deprecate pci_get_bus_and_slot()

2018-01-04 Thread Gary R Hook

On 01/04/2018 10:32 AM, Sinan Kaya wrote:

On 1/4/2018 11:28 AM, Gary R Hook wrote:

On 01/04/2018 06:25 AM, Sinan Kaya wrote:

On 12/19/2017 12:37 AM, Sinan Kaya wrote:

pci_get_bus_and_slot() is restrictive such that it assumes domain=0 as
where a PCI device is present. This restricts the device drivers to be
reused for other domain numbers.

Getting ready to remove pci_get_bus_and_slot() function in favor of
pci_get_domain_bus_and_slot().

Hard-code the domain number as 0 for the AMD IOMMU driver.






Any comments from the IOMMU people?



pci_get_bus_and_slot() appears to (now) be a convenience function that wraps 
pci_get_domain_bus_and_slot() while using a 0 for the domain value. Exactly 
what you are doing here, albeit in a more overt way.

How is this patch advantageous? Seems to me that if other domains need to be 
enabled, that driver could be changed if and when that requirement arises.

But perhaps I'm missing a nuance here.




The benefit of the change was discussed here:

https://lkml.org/lkml/2017/12/19/349

I hope it helps.




Thank you for pointing out that thread directly. I read through it and 
thought further about this change.


I am not the maintainer, but as an AMD developer, this is fine change. I 
can't ACK but I can agree.


Gary
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V4 11/26] iommu/amd: deprecate pci_get_bus_and_slot()

2018-01-04 Thread Gary R Hook

On 01/04/2018 06:25 AM, Sinan Kaya wrote:

On 12/19/2017 12:37 AM, Sinan Kaya wrote:

pci_get_bus_and_slot() is restrictive such that it assumes domain=0 as
where a PCI device is present. This restricts the device drivers to be
reused for other domain numbers.

Getting ready to remove pci_get_bus_and_slot() function in favor of
pci_get_domain_bus_and_slot().

Hard-code the domain number as 0 for the AMD IOMMU driver.




>
> Any comments from the IOMMU people?
>

pci_get_bus_and_slot() appears to (now) be a convenience function that 
wraps pci_get_domain_bus_and_slot() while using a 0 for the domain 
value. Exactly what you are doing here, albeit in a more overt way.


How is this patch advantageous? Seems to me that if other domains need 
to be enabled, that driver could be changed if and when that requirement 
arises.


But perhaps I'm missing a nuance here.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH V2] iommu/amd - Set the device table entry PPR bit for IOMMU V2 devices

2017-12-20 Thread Gary R Hook

On 12/20/2017 01:02 PM, Alex Williamson wrote:

On Tue, 19 Dec 2017 16:15:41 -0600
Gary R Hook <gary.h...@amd.com> wrote:


The AMD IOMMU specification Rev 3.00 (December 2016) introduces a
new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register
offset 0030h (IOMMU Extended Feature Register).

When EPHSup=1, the IOMMU hardware requires the PPR bit of the
device table entry (DTE) to be set in order to support PPR for a
particular endpoint device.

Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for
this revision of the AMD IOMMU specification.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  0 files changed


Hmm, something funky there, but looks fine otherwise.  Applied to
v4.16-iommu/amd.  Thanks,

Alex



Thanks. I have no clue why it says "0 files changed". I just looked 
again and it seems fine here.

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH V2] iommu/amd - Set the device table entry PPR bit for IOMMU V2 devices

2017-12-19 Thread Gary R Hook
The AMD IOMMU specification Rev 3.00 (December 2016) introduces a
new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register
offset 0030h (IOMMU Extended Feature Register).

When EPHSup=1, the IOMMU hardware requires the PPR bit of the
device table entry (DTE) to be set in order to support PPR for a
particular endpoint device.

Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for
this revision of the AMD IOMMU specification.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 0 files changed

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index cb78933ef53f..5f3da95ff6a0 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1818,7 +1818,8 @@ static bool dma_ops_domain(struct protection_domain 
*domain)
return domain->flags & PD_DMA_OPS_MASK;
 }
 
-static void set_dte_entry(u16 devid, struct protection_domain *domain, bool 
ats)
+static void set_dte_entry(u16 devid, struct protection_domain *domain,
+ bool ats, bool ppr)
 {
u64 pte_root = 0;
u64 flags = 0;
@@ -1835,6 +1836,13 @@ static void set_dte_entry(u16 devid, struct 
protection_domain *domain, bool ats)
if (ats)
flags |= DTE_FLAG_IOTLB;
 
+   if (ppr) {
+   struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+   if (iommu_feature(iommu, FEATURE_EPHSUP))
+   pte_root |= 1ULL << DEV_ENTRY_PPR;
+   }
+
if (domain->flags & PD_IOMMUV2_MASK) {
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx  = domain->glx;
@@ -1897,9 +1905,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1;
 
/* Update device table */
-   set_dte_entry(dev_data->devid, domain, ats);
+   set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
if (alias != dev_data->devid)
-   set_dte_entry(alias, domain, ats);
+   set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
 
device_flush_dte(dev_data);
 }
@@ -2278,13 +2286,15 @@ static void update_device_table(struct 
protection_domain *domain)
struct iommu_dev_data *dev_data;
 
list_for_each_entry(dev_data, >dev_list, list) {
-   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
 
if (dev_data->devid == dev_data->alias)
continue;
 
/* There is an alias, update device table entry for it */
-   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
}
 }
 
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f6b24c7d8b70..6a877ebd058b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,6 +98,7 @@
 #define FEATURE_HE (1ULL<<8)
 #define FEATURE_PC (1ULL<<9)
 #define FEATURE_GAM_VAPIC  (1ULL<<21)
+#define FEATURE_EPHSUP (1ULL<<50)
 
 #define FEATURE_PASID_SHIFT32
 #define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
 /* macros and definitions for device table entries */
 #define DEV_ENTRY_VALID 0x00
 #define DEV_ENTRY_TRANSLATION   0x01
+#define DEV_ENTRY_PPR   0x34
 #define DEV_ENTRY_IR0x3d
 #define DEV_ENTRY_IW0x3e
 #define DEV_ENTRY_NO_PAGE_FAULT0x62

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu/amd - Set the device table entry PPR bit for IOMMU V2 devices

2017-12-12 Thread Gary R Hook

Please ignore. I've uncovered a problem and will re-submit.

On 12/04/2017 01:52 PM, Gary R Hook wrote:

The AMD IOMMU specification Rev 3.00 (December 2016) introduces a
new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register
offset 0030h (IOMMU Extended Feature Register).

When EPHSup=1, the IOMMU hardware requires the PPR bit of the
device table entry (DTE) to be set in order to support PPR for a
particular endpoint device.

Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for
this revision of the AMD IOMMU specification.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/amd_iommu.c   |   20 +++-
  drivers/iommu/amd_iommu_types.h |2 ++
  2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index cb78933ef53f..329940ffb8c1 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1818,7 +1818,8 @@ static bool dma_ops_domain(struct protection_domain 
*domain)
return domain->flags & PD_DMA_OPS_MASK;
  }
  
-static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)

+static void set_dte_entry(u16 devid, struct protection_domain *domain,
+ bool ats, bool ppr)
  {
u64 pte_root = 0;
u64 flags = 0;
@@ -1835,6 +1836,13 @@ static void set_dte_entry(u16 devid, struct 
protection_domain *domain, bool ats)
if (ats)
flags |= DTE_FLAG_IOTLB;
  
+	if (ppr) {

+   struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+   if (iommu_feature(iommu, FEATURE_EPHSUP))
+   pte_root |= DEV_ENTRY_PPR;
+   }
+
if (domain->flags & PD_IOMMUV2_MASK) {
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx  = domain->glx;
@@ -1897,9 +1905,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1;
  
  	/* Update device table */

-   set_dte_entry(dev_data->devid, domain, ats);
+   set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
if (alias != dev_data->devid)
-   set_dte_entry(alias, domain, ats);
+   set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
  
  	device_flush_dte(dev_data);

  }
@@ -2278,13 +2286,15 @@ static void update_device_table(struct 
protection_domain *domain)
struct iommu_dev_data *dev_data;
  
  	list_for_each_entry(dev_data, >dev_list, list) {

-   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
  
  		if (dev_data->devid == dev_data->alias)

continue;
  
  		/* There is an alias, update device table entry for it */

-   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
}
  }
  
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h

index f6b24c7d8b70..6a877ebd058b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,6 +98,7 @@
  #define FEATURE_HE(1ULL<<8)
  #define FEATURE_PC(1ULL<<9)
  #define FEATURE_GAM_VAPIC (1ULL<<21)
+#define FEATURE_EPHSUP (1ULL<<50)
  
  #define FEATURE_PASID_SHIFT	32

  #define FEATURE_PASID_MASK(0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
  /* macros and definitions for device table entries */
  #define DEV_ENTRY_VALID 0x00
  #define DEV_ENTRY_TRANSLATION   0x01
+#define DEV_ENTRY_PPR   0x34
  #define DEV_ENTRY_IR0x3d
  #define DEV_ENTRY_IW0x3e
  #define DEV_ENTRY_NO_PAGE_FAULT   0x62

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu



___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu/amd - Record more information about unknown events

2017-12-04 Thread Gary R Hook
When an unknown type event occurs, the default information written to
the syslog should dump raw event data. This could provide insight into
the event that occurred.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c |4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 51f8215877f5..cb78933ef53f 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -617,7 +617,9 @@ static void iommu_print_event(struct amd_iommu *iommu, void 
*__evt)
   address, flags);
break;
default:
-   printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
+   printk(KERN_ERR "UNKNOWN type=0x%02x event[0]=0x%08x "
+  "event[1]=0x%08x event[2]=0x%08x event[3]=0x%08x\n",
+  type, event[0], event[1], event[2], event[3]);
}
 
memset(__evt, 0, 4 * sizeof(u32));

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu/amd - Set the device table entry PPR bit for IOMMU V2 devices

2017-12-04 Thread Gary R Hook
The AMD IOMMU specification Rev 3.00 (December 2016) introduces a
new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register
offset 0030h (IOMMU Extended Feature Register).

When EPHSup=1, the IOMMU hardware requires the PPR bit of the
device table entry (DTE) to be set in order to support PPR for a
particular endpoint device.

Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for
this revision of the AMD IOMMU specification.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c   |   20 +++-
 drivers/iommu/amd_iommu_types.h |2 ++
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index cb78933ef53f..329940ffb8c1 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -1818,7 +1818,8 @@ static bool dma_ops_domain(struct protection_domain 
*domain)
return domain->flags & PD_DMA_OPS_MASK;
 }
 
-static void set_dte_entry(u16 devid, struct protection_domain *domain, bool 
ats)
+static void set_dte_entry(u16 devid, struct protection_domain *domain,
+ bool ats, bool ppr)
 {
u64 pte_root = 0;
u64 flags = 0;
@@ -1835,6 +1836,13 @@ static void set_dte_entry(u16 devid, struct 
protection_domain *domain, bool ats)
if (ats)
flags |= DTE_FLAG_IOTLB;
 
+   if (ppr) {
+   struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+   if (iommu_feature(iommu, FEATURE_EPHSUP))
+   pte_root |= DEV_ENTRY_PPR;
+   }
+
if (domain->flags & PD_IOMMUV2_MASK) {
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
u64 glx  = domain->glx;
@@ -1897,9 +1905,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1;
 
/* Update device table */
-   set_dte_entry(dev_data->devid, domain, ats);
+   set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
if (alias != dev_data->devid)
-   set_dte_entry(alias, domain, ats);
+   set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
 
device_flush_dte(dev_data);
 }
@@ -2278,13 +2286,15 @@ static void update_device_table(struct 
protection_domain *domain)
struct iommu_dev_data *dev_data;
 
list_for_each_entry(dev_data, >dev_list, list) {
-   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
 
if (dev_data->devid == dev_data->alias)
continue;
 
/* There is an alias, update device table entry for it */
-   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
+   set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
+ dev_data->iommu_v2);
}
 }
 
diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index f6b24c7d8b70..6a877ebd058b 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -98,6 +98,7 @@
 #define FEATURE_HE (1ULL<<8)
 #define FEATURE_PC (1ULL<<9)
 #define FEATURE_GAM_VAPIC  (1ULL<<21)
+#define FEATURE_EPHSUP (1ULL<<50)
 
 #define FEATURE_PASID_SHIFT32
 #define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
 /* macros and definitions for device table entries */
 #define DEV_ENTRY_VALID 0x00
 #define DEV_ENTRY_TRANSLATION   0x01
+#define DEV_ENTRY_PPR   0x34
 #define DEV_ENTRY_IR0x3d
 #define DEV_ENTRY_IW0x3e
 #define DEV_ENTRY_NO_PAGE_FAULT0x62

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH] iommu: Limit the IOVA page range to the specified addresses

2017-10-27 Thread Gary R Hook

On 10/26/2017 03:32 AM, Alex Williamson wrote:

On Tue, 17 Oct 2017 16:22:01 -0500
Gary R Hook <gary.h...@amd.com> wrote:


From: amd <a...@sosxen2.amd.com>

The extent of pages specified when applying a reserved region should
include up to the last page of the range, but not the page following
the range.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
  drivers/iommu/amd_iommu.c |2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 27eb0d6fcdc2..bb3ef33e3784 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3271,7 +3271,7 @@ static void amd_iommu_apply_resv_region(struct device 
*dev,
unsigned long start, end;
  
  	start = IOVA_PFN(region->start);

-   end   = IOVA_PFN(region->start + region->length);
+   end   = IOVA_PFN(region->start + region->length - 1);
  
  	WARN_ON_ONCE(reserve_iova(_dom->iovad, start, end) == NULL);

  }


This looks like a fix, should we include:

Fixes: 8d54d6c8b8f3 ('iommu/amd: Implement apply_dm_region call-back')


It turns out there are other places where the computation is incorrect.
Would you prefer a single patch to address all of them, or separate
patches that apply to specific areas of the driver?

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


[PATCH] iommu: Limit the IOVA page range to the specified addresses

2017-10-17 Thread Gary R Hook
From: amd <a...@sosxen2.amd.com>

The extent of pages specified when applying a reserved region should
include up to the last page of the range, but not the page following
the range.

Signed-off-by: Gary R Hook <gary.h...@amd.com>
---
 drivers/iommu/amd_iommu.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 27eb0d6fcdc2..bb3ef33e3784 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -3271,7 +3271,7 @@ static void amd_iommu_apply_resv_region(struct device 
*dev,
unsigned long start, end;
 
start = IOVA_PFN(region->start);
-   end   = IOVA_PFN(region->start + region->length);
+   end   = IOVA_PFN(region->start + region->length - 1);
 
WARN_ON_ONCE(reserve_iova(_dom->iovad, start, end) == NULL);
 }

___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu