linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] iommu/vt-d: Make RMRR matching compatible with older kernels
@ 2014-10-02 10:09 Joerg Roedel
  2014-10-02 10:09 ` [PATCH 1/2] iommu/vt-d: Store bus information in RMRR PCI device path Joerg Roedel
  2014-10-02 10:09 ` [PATCH 2/2] iommu/vt-d: Work around broken RMRR firmware entries Joerg Roedel
  0 siblings, 2 replies; 4+ messages in thread
From: Joerg Roedel @ 2014-10-02 10:09 UTC (permalink / raw)
  To: iommu, linux-kernel; +Cc: David Woodhouse, Jiang Liu, jroedel, joro

Hi,

here is a patch-set to make RMRR matching in the Intel IOMMU
driver compatible with older kernels. This is needed because
some BIOS vendors build RMRR entries to work with older
kernels, but that will break on newer ones that implement
the correct PCI device scope matching scheme defined in the
VT-d specification.

Make the current Intel IOMMU driver work with the old RMRR
entries too.

These patches have been tested in an affected system and fix
the issue seen there (newer kernel did not setup RMRR
entries for a plugged in device).

Regards,

	Joerg

Joerg Roedel (2):
  iommu/vt-d: Store bus information in RMRR PCI device path
  iommu/vt-d: Work around broken RMRR firmware entries

 drivers/iommu/dmar.c | 23 ++++++++++++++++++++---
 include/linux/dmar.h |  8 +++++++-
 2 files changed, 27 insertions(+), 4 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] iommu/vt-d: Store bus information in RMRR PCI device path
  2014-10-02 10:09 [PATCH 0/2] iommu/vt-d: Make RMRR matching compatible with older kernels Joerg Roedel
@ 2014-10-02 10:09 ` Joerg Roedel
  2014-10-02 10:09 ` [PATCH 2/2] iommu/vt-d: Work around broken RMRR firmware entries Joerg Roedel
  1 sibling, 0 replies; 4+ messages in thread
From: Joerg Roedel @ 2014-10-02 10:09 UTC (permalink / raw)
  To: iommu, linux-kernel; +Cc: David Woodhouse, Jiang Liu, jroedel, joro

From: Joerg Roedel <jroedel@suse.de>

This will be used later to match broken RMRR entries.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/dmar.c | 1 +
 include/linux/dmar.h | 8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 06d268a..6ba28b0 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -155,6 +155,7 @@ dmar_alloc_pci_notify_info(struct pci_dev *dev, unsigned long event)
 	if (event == BUS_NOTIFY_ADD_DEVICE) {
 		for (tmp = dev; tmp; tmp = tmp->bus->self) {
 			level--;
+			info->path[level].bus = tmp->bus->number;
 			info->path[level].device = PCI_SLOT(tmp->devfn);
 			info->path[level].function = PCI_FUNC(tmp->devfn);
 			if (pci_is_root_bus(tmp->bus))
diff --git a/include/linux/dmar.h b/include/linux/dmar.h
index 1deece4..593fff9 100644
--- a/include/linux/dmar.h
+++ b/include/linux/dmar.h
@@ -56,13 +56,19 @@ struct dmar_drhd_unit {
 	struct intel_iommu *iommu;
 };
 
+struct dmar_pci_path {
+	u8 bus;
+	u8 device;
+	u8 function;
+};
+
 struct dmar_pci_notify_info {
 	struct pci_dev			*dev;
 	unsigned long			event;
 	int				bus;
 	u16				seg;
 	u16				level;
-	struct acpi_dmar_pci_path	path[];
+	struct dmar_pci_path		path[];
 }  __attribute__((packed));
 
 extern struct rw_semaphore dmar_global_lock;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] iommu/vt-d: Work around broken RMRR firmware entries
  2014-10-02 10:09 [PATCH 0/2] iommu/vt-d: Make RMRR matching compatible with older kernels Joerg Roedel
  2014-10-02 10:09 ` [PATCH 1/2] iommu/vt-d: Store bus information in RMRR PCI device path Joerg Roedel
@ 2014-10-02 10:09 ` Joerg Roedel
  2014-10-07  0:59   ` Jiang Liu
  1 sibling, 1 reply; 4+ messages in thread
From: Joerg Roedel @ 2014-10-02 10:09 UTC (permalink / raw)
  To: iommu, linux-kernel; +Cc: David Woodhouse, Jiang Liu, jroedel, joro

From: Joerg Roedel <jroedel@suse.de>

The VT-d specification states that an RMRR entry in the DMAR
table needs to specify the full path to the device. This is
also how newer Linux kernels implement it.

Unfortunatly older drivers just match for the target device
and not the full path to the device, so that BIOS vendors
implement that behavior into their BIOSes to make them work
with older Linux kernels. But those RMRR entries break on
newer Linux kernels.

Work around this issue by adding a fall-back into the RMRR
matching code to match those old RMRR entries too.

Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/iommu/dmar.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 6ba28b0..371ff33 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -178,17 +178,33 @@ static bool dmar_match_pci_path(struct dmar_pci_notify_info *info, int bus,
 	int i;
 
 	if (info->bus != bus)
-		return false;
+		goto fallback;
 	if (info->level != count)
-		return false;
+		goto fallback;
 
 	for (i = 0; i < count; i++) {
 		if (path[i].device != info->path[i].device ||
 		    path[i].function != info->path[i].function)
-			return false;
+			goto fallback;
 	}
 
 	return true;
+
+fallback:
+
+	if (count != 1)
+		return false;
+
+	i = info->level - 1;
+	if (bus              == info->path[i].bus &&
+	    path[0].device   == info->path[i].device &&
+	    path[0].function == info->path[i].function) {
+		pr_info(FW_BUG "RMRR entry for device %02x:%02x.%x is broken - applying workaround\n",
+			bus, path[0].device, path[0].function);
+		return true;
+	}
+
+	return false;
 }
 
 /* Return: > 0 if match found, 0 if no match found, < 0 if error happens */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 2/2] iommu/vt-d: Work around broken RMRR firmware entries
  2014-10-02 10:09 ` [PATCH 2/2] iommu/vt-d: Work around broken RMRR firmware entries Joerg Roedel
@ 2014-10-07  0:59   ` Jiang Liu
  0 siblings, 0 replies; 4+ messages in thread
From: Jiang Liu @ 2014-10-07  0:59 UTC (permalink / raw)
  To: Joerg Roedel, iommu, linux-kernel; +Cc: David Woodhouse, jroedel


On 2014/10/2 18:09, Joerg Roedel wrote:
> From: Joerg Roedel <jroedel@suse.de>
> 
> The VT-d specification states that an RMRR entry in the DMAR
> table needs to specify the full path to the device. This is
> also how newer Linux kernels implement it.
> 
> Unfortunatly older drivers just match for the target device
> and not the full path to the device, so that BIOS vendors
> implement that behavior into their BIOSes to make them work
> with older Linux kernels. But those RMRR entries break on
> newer Linux kernels.
> 
> Work around this issue by adding a fall-back into the RMRR
> matching code to match those old RMRR entries too.
> 
> Signed-off-by: Joerg Roedel <jroedel@suse.de>
> ---
>  drivers/iommu/dmar.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
> index 6ba28b0..371ff33 100644
> --- a/drivers/iommu/dmar.c
> +++ b/drivers/iommu/dmar.c
> @@ -178,17 +178,33 @@ static bool dmar_match_pci_path(struct dmar_pci_notify_info *info, int bus,
>  	int i;
>  
>  	if (info->bus != bus)
> -		return false;
> +		goto fallback;
>  	if (info->level != count)
> -		return false;
> +		goto fallback;
>  
>  	for (i = 0; i < count; i++) {
>  		if (path[i].device != info->path[i].device ||
>  		    path[i].function != info->path[i].function)
> -			return false;
> +			goto fallback;
>  	}
>  
>  	return true;
> +
> +fallback:
> +
> +	if (count != 1)
> +		return false;
> +
> +	i = info->level - 1;
> +	if (bus              == info->path[i].bus &&
> +	    path[0].device   == info->path[i].device &&
> +	    path[0].function == info->path[i].function) {
> +		pr_info(FW_BUG "RMRR entry for device %02x:%02x.%x is broken - applying workaround\n",
> +			bus, path[0].device, path[0].function);
> +		return true;
> +	}
> +
> +	return false;
>  }
>  
>  /* Return: > 0 if match found, 0 if no match found, < 0 if error happens */
> 
Hi Joerg,
	Thanks for fixing this:)
	Reviewed-by: Jiang Liu <jiang.liu@linux.intel.com>
Regards!
Gerry

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-10-07  0:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-02 10:09 [PATCH 0/2] iommu/vt-d: Make RMRR matching compatible with older kernels Joerg Roedel
2014-10-02 10:09 ` [PATCH 1/2] iommu/vt-d: Store bus information in RMRR PCI device path Joerg Roedel
2014-10-02 10:09 ` [PATCH 2/2] iommu/vt-d: Work around broken RMRR firmware entries Joerg Roedel
2014-10-07  0:59   ` Jiang Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).