diff options
author | Wang YanQing <udknight@gmail.com> | 2016-05-05 09:14:21 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-05-05 10:01:00 -0400 |
commit | c10fcb14c7afd6688c7b197a814358fecf244222 (patch) | |
tree | fc70c2fe4fbb5b974eb7ec07eeec5f409b2fca0c | |
parent | 7f9b474c92713067237c8188f32791cc4007b5da (diff) |
x86/sysfb_efi: Fix valid BAR address range check
The code for checking whether a BAR address range is valid will break
out of the loop when a start address of 0x0 is encountered.
This behaviour is wrong since by breaking out of the loop we may miss
the BAR that describes the EFI frame buffer in a later iteration.
Because of this bug I can't use video=efifb: boot parameter to get
efifb on my new ThinkPad E550 for my old linux system hard disk with
3.10 kernel. In 3.10, efifb is the only choice due to DRM/I915 not
supporting the GPU.
This patch also add a trivial optimization to break out after we find
the frame buffer address range without testing later BARs.
Signed-off-by: Wang YanQing <udknight@gmail.com>
[ Rewrote changelog. ]
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Peter Jones <pjones@redhat.com>
Cc: <stable@vger.kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: David Herrmann <dh.herrmann@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tomi Valkeinen <tomi.valkeinen@ti.com>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/1462454061-21561-2-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/kernel/sysfb_efi.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/x86/kernel/sysfb_efi.c b/arch/x86/kernel/sysfb_efi.c index b285d4e8c68e..5da924bbf0a0 100644 --- a/arch/x86/kernel/sysfb_efi.c +++ b/arch/x86/kernel/sysfb_efi.c | |||
@@ -106,14 +106,24 @@ static int __init efifb_set_system(const struct dmi_system_id *id) | |||
106 | continue; | 106 | continue; |
107 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 107 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
108 | resource_size_t start, end; | 108 | resource_size_t start, end; |
109 | unsigned long flags; | ||
110 | |||
111 | flags = pci_resource_flags(dev, i); | ||
112 | if (!(flags & IORESOURCE_MEM)) | ||
113 | continue; | ||
114 | |||
115 | if (flags & IORESOURCE_UNSET) | ||
116 | continue; | ||
117 | |||
118 | if (pci_resource_len(dev, i) == 0) | ||
119 | continue; | ||
109 | 120 | ||
110 | start = pci_resource_start(dev, i); | 121 | start = pci_resource_start(dev, i); |
111 | if (start == 0) | ||
112 | break; | ||
113 | end = pci_resource_end(dev, i); | 122 | end = pci_resource_end(dev, i); |
114 | if (screen_info.lfb_base >= start && | 123 | if (screen_info.lfb_base >= start && |
115 | screen_info.lfb_base < end) { | 124 | screen_info.lfb_base < end) { |
116 | found_bar = 1; | 125 | found_bar = 1; |
126 | break; | ||
117 | } | 127 | } |
118 | } | 128 | } |
119 | } | 129 | } |