diff options
| author | David Herrmann <dh.herrmann@gmail.com> | 2016-11-15 07:01:58 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2016-11-16 03:38:23 -0500 |
| commit | f96acec8c8020807429d21324547f4b904c37177 (patch) | |
| tree | e69e6c294d332d2fed78748076350f5a3b67d415 /arch/x86/kernel | |
| parent | 9164b4ceb7b492a77c7fe770a4b9d1375c9cd45a (diff) | |
x86/sysfb: Fix lfb_size calculation
The screen_info.lfb_size field is shifted by 16 bits *only* in case of
VBE. This has historical reasons since VBE advertised it similarly.
However, in case of EFI framebuffers, the size is no longer shifted. Fix
the x86 simple-framebuffer setup code to use the correct size in the
non-VBE case.
While at it, avoid variable abbreviations and rename 'len' to 'length',
and use the correct types matching the screen_info definition.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matt Fleming <matt.fleming@intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tom Gundersen <teg@jklm.no>
Link: http://lkml.kernel.org/r/20161115120158.15388-3-dh.herrmann@gmail.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel')
| -rw-r--r-- | arch/x86/kernel/sysfb_simplefb.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c index 35b86415871f..85195d447a92 100644 --- a/arch/x86/kernel/sysfb_simplefb.c +++ b/arch/x86/kernel/sysfb_simplefb.c | |||
| @@ -66,8 +66,8 @@ __init int create_simplefb(const struct screen_info *si, | |||
| 66 | { | 66 | { |
| 67 | struct platform_device *pd; | 67 | struct platform_device *pd; |
| 68 | struct resource res; | 68 | struct resource res; |
| 69 | unsigned long len; | 69 | u64 base, size; |
| 70 | u64 base; | 70 | u32 length; |
| 71 | 71 | ||
| 72 | /* | 72 | /* |
| 73 | * If the 64BIT_BASE capability is set, ext_lfb_base will contain the | 73 | * If the 64BIT_BASE capability is set, ext_lfb_base will contain the |
| @@ -82,11 +82,20 @@ __init int create_simplefb(const struct screen_info *si, | |||
| 82 | return -EINVAL; | 82 | return -EINVAL; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | /* don't use lfb_size as it may contain the whole VMEM instead of only | 85 | /* |
| 86 | * the part that is occupied by the framebuffer */ | 86 | * Don't use lfb_size as IORESOURCE size, since it may contain the |
| 87 | len = mode->height * mode->stride; | 87 | * entire VMEM, and thus require huge mappings. Use just the part we |
| 88 | len = PAGE_ALIGN(len); | 88 | * need, that is, the part where the framebuffer is located. But verify |
| 89 | if (len > (u64)si->lfb_size << 16) { | 89 | * that it does not exceed the advertised VMEM. |
| 90 | * Note that in case of VBE, the lfb_size is shifted by 16 bits for | ||
| 91 | * historical reasons. | ||
| 92 | */ | ||
| 93 | size = si->lfb_size; | ||
| 94 | if (si->orig_video_isVGA == VIDEO_TYPE_VLFB) | ||
| 95 | size <<= 16; | ||
| 96 | length = mode->height * mode->stride; | ||
| 97 | length = PAGE_ALIGN(length); | ||
| 98 | if (length > size) { | ||
| 90 | printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); | 99 | printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); |
| 91 | return -EINVAL; | 100 | return -EINVAL; |
| 92 | } | 101 | } |
| @@ -96,7 +105,7 @@ __init int create_simplefb(const struct screen_info *si, | |||
| 96 | res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; | 105 | res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; |
| 97 | res.name = simplefb_resname; | 106 | res.name = simplefb_resname; |
| 98 | res.start = base; | 107 | res.start = base; |
| 99 | res.end = res.start + len - 1; | 108 | res.end = res.start + length - 1; |
| 100 | if (res.end <= res.start) | 109 | if (res.end <= res.start) |
| 101 | return -EINVAL; | 110 | return -EINVAL; |
| 102 | 111 | ||
