[ 107/135] xhci: Make handover code more robust

2012-09-16 Thread Ben Hutchings
3.2-stable review patch.  If anyone has any objections, please let me know.

--

From: Matthew Garrett 

commit e955a1cd086de4d165ae0f4c7be7289d84b63bdc upstream.

My test platform (Intel DX79SI) boots reliably under BIOS, but frequently
crashes when booting via UEFI. I finally tracked this down to the xhci
handoff code. It seems that reads from the device occasionally just return
0xff, resulting in xhci_find_next_cap_offset generating a value that's
larger than the resource region. We then oops when attempting to read the
value. Sanity checking that value lets us avoid the crash.

I've no idea what's causing the underlying problem, and xhci still doesn't
actually *work* even with this, but the machine at least boots which will
probably make further debugging easier.

This should be backported to kernels as old as 2.6.31, that contain the
commit 66d4eadd8d067269ea8fead1a50fe87c2979a80d "USB: xhci: BIOS handoff
and HW initialization."

Signed-off-by: Matthew Garrett 
Signed-off-by: Sarah Sharp 
Signed-off-by: Ben Hutchings 
---
 drivers/usb/host/pci-quirks.c |   12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 20b9f45..966d148 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -841,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct 
pci_dev *pdev)
void __iomem *op_reg_base;
u32 val;
int timeout;
+   int len = pci_resource_len(pdev, 0);
 
if (!mmio_resource_enabled(pdev, 0))
return;
 
-   base = ioremap_nocache(pci_resource_start(pdev, 0),
-   pci_resource_len(pdev, 0));
+   base = ioremap_nocache(pci_resource_start(pdev, 0), len);
if (base == NULL)
return;
 
@@ -856,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct 
pci_dev *pdev)
 */
ext_cap_offset = xhci_find_next_cap_offset(base, 
XHCI_HCC_PARAMS_OFFSET);
do {
+   if ((ext_cap_offset + sizeof(val)) > len) {
+   /* We're reading garbage from the controller */
+   dev_warn(>dev,
+"xHCI controller failing to respond");
+   return;
+   }
+
if (!ext_cap_offset)
/* We've reached the end of the extended capabilities */
goto hc_init;
+
val = readl(base + ext_cap_offset);
if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)
break;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[ 107/135] xhci: Make handover code more robust

2012-09-16 Thread Ben Hutchings
3.2-stable review patch.  If anyone has any objections, please let me know.

--

From: Matthew Garrett m...@redhat.com

commit e955a1cd086de4d165ae0f4c7be7289d84b63bdc upstream.

My test platform (Intel DX79SI) boots reliably under BIOS, but frequently
crashes when booting via UEFI. I finally tracked this down to the xhci
handoff code. It seems that reads from the device occasionally just return
0xff, resulting in xhci_find_next_cap_offset generating a value that's
larger than the resource region. We then oops when attempting to read the
value. Sanity checking that value lets us avoid the crash.

I've no idea what's causing the underlying problem, and xhci still doesn't
actually *work* even with this, but the machine at least boots which will
probably make further debugging easier.

This should be backported to kernels as old as 2.6.31, that contain the
commit 66d4eadd8d067269ea8fead1a50fe87c2979a80d USB: xhci: BIOS handoff
and HW initialization.

Signed-off-by: Matthew Garrett m...@redhat.com
Signed-off-by: Sarah Sharp sarah.a.sh...@linux.intel.com
Signed-off-by: Ben Hutchings b...@decadent.org.uk
---
 drivers/usb/host/pci-quirks.c |   12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 20b9f45..966d148 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -841,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct 
pci_dev *pdev)
void __iomem *op_reg_base;
u32 val;
int timeout;
+   int len = pci_resource_len(pdev, 0);
 
if (!mmio_resource_enabled(pdev, 0))
return;
 
-   base = ioremap_nocache(pci_resource_start(pdev, 0),
-   pci_resource_len(pdev, 0));
+   base = ioremap_nocache(pci_resource_start(pdev, 0), len);
if (base == NULL)
return;
 
@@ -856,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct 
pci_dev *pdev)
 */
ext_cap_offset = xhci_find_next_cap_offset(base, 
XHCI_HCC_PARAMS_OFFSET);
do {
+   if ((ext_cap_offset + sizeof(val))  len) {
+   /* We're reading garbage from the controller */
+   dev_warn(pdev-dev,
+xHCI controller failing to respond);
+   return;
+   }
+
if (!ext_cap_offset)
/* We've reached the end of the extended capabilities */
goto hc_init;
+
val = readl(base + ext_cap_offset);
if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)
break;


--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/