[ 3.8.y.z extended stable ] Patch "x86/PCI: Map PCI setup data with ioremap() so it can be in highmem" has been added to staging queue
Kamal Mostafa
kamal at canonical.com
Fri Jun 7 20:29:26 UTC 2013
This is a note to let you know that I have just added a patch titled
x86/PCI: Map PCI setup data with ioremap() so it can be in highmem
to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree
which can be found at:
http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue
This patch is scheduled to be released in version 3.8.13.3.
If you, or anyone else, feels it should not be added to this tree, please
reply to this email.
For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
Thanks.
-Kamal
------
>From 0e797044f189bf40d69c64c0cb3af8c522f5c643 Mon Sep 17 00:00:00 2001
From: Matt Fleming <matt.fleming at intel.com>
Date: Wed, 5 Jun 2013 15:15:41 +0100
Subject: x86/PCI: Map PCI setup data with ioremap() so it can be in highmem
commit 65694c5aaddfedd9da082e4e150cafc6b3fc8a6a upstream.
f9a37be0f0 ("x86: Use PCI setup data") added support for using PCI ROM
images from setup_data. This used phys_to_virt(), which is not valid for
highmem addresses, and can cause a crash when booting a 32-bit kernel via
the EFI boot stub.
pcibios_add_device() assumes that the physical addresses stored in
setup_data are accessible via the direct kernel mapping, and that calling
phys_to_virt() is valid. This isn't guaranteed to be true on x86 where the
direct mapping range is much smaller than on x86-64.
Calling phys_to_virt() on a highmem address results in the following:
BUG: unable to handle kernel paging request at 39a3c198
IP: [<c262be0f>] pcibios_add_device+0x2f/0x90
...
Call Trace:
[<c2370c73>] pci_device_add+0xe3/0x130
[<c274640b>] pci_scan_single_device+0x8b/0xb0
[<c2370d08>] pci_scan_slot+0x48/0x100
[<c2371904>] pci_scan_child_bus+0x24/0xc0
[<c262a7b0>] pci_acpi_scan_root+0x2c0/0x490
[<c23b7203>] acpi_pci_root_add+0x312/0x42f
...
The solution is to use ioremap() instead of phys_to_virt() to map the
setup data into the kernel address space.
[bhelgaas: changelog]
Tested-by: Jani Nikula <jani.nikula at intel.com>
Signed-off-by: Matt Fleming <matt.fleming at intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas at google.com>
Cc: Matthew Garrett <mjg59 at srcf.ucam.org>
Cc: Seth Forshee <seth.forshee at canonical.com>
Cc: Jesse Barnes <jbarnes at virtuousgeek.org>
Signed-off-by: Kamal Mostafa <kamal at canonical.com>
---
arch/x86/pci/common.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index ccd0ab3..f24ba14 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -618,7 +618,9 @@ int pcibios_add_device(struct pci_dev *dev)
pa_data = boot_params.hdr.setup_data;
while (pa_data) {
- data = phys_to_virt(pa_data);
+ data = ioremap(pa_data, sizeof(*rom));
+ if (!data)
+ return -ENOMEM;
if (data->type == SETUP_PCI) {
rom = (struct pci_setup_rom *)data;
@@ -635,6 +637,7 @@ int pcibios_add_device(struct pci_dev *dev)
}
}
pa_data = data->next;
+ iounmap(data);
}
return 0;
}
--
1.8.1.2
More information about the kernel-team
mailing list