aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2016-11-15 07:01:57 -0500
committerIngo Molnar <mingo@kernel.org>2016-11-16 03:38:22 -0500
commit9164b4ceb7b492a77c7fe770a4b9d1375c9cd45a (patch)
treeb4a665157bc8148a14bfd148a5aeaf4f70b7f90e
parent81bcfe5e48f9b8c42cf547f1c74c7f60c44c34c8 (diff)
x86/sysfb: Add support for 64bit EFI lfb_base
The screen_info object was extended to support 64-bit lfb_base addresses in: ae2ee627dc87 ("efifb: Add support for 64-bit frame buffer addresses") However, the x86 simple-framebuffer setup code never made use of it. Fix it to properly assemble and verify the lfb_base before advertising simple-framebuffer devices. In particular, this means if VIDEO_CAPABILITY_64BIT_BASE is set, the screen_info->ext_lfb_base field will contain the upper 32bit of the actual lfb_base. Make sure the address is not 0 (i.e., unset), as well as does not overflow the physical address type. 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-2-dh.herrmann@gmail.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--arch/x86/kernel/sysfb_simplefb.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/arch/x86/kernel/sysfb_simplefb.c b/arch/x86/kernel/sysfb_simplefb.c
index 764a29f84de7..35b86415871f 100644
--- a/arch/x86/kernel/sysfb_simplefb.c
+++ b/arch/x86/kernel/sysfb_simplefb.c
@@ -67,6 +67,20 @@ __init int create_simplefb(const struct screen_info *si,
67 struct platform_device *pd; 67 struct platform_device *pd;
68 struct resource res; 68 struct resource res;
69 unsigned long len; 69 unsigned long len;
70 u64 base;
71
72 /*
73 * If the 64BIT_BASE capability is set, ext_lfb_base will contain the
74 * upper half of the base address. Assemble the address, then make sure
75 * it is valid and we can actually access it.
76 */
77 base = si->lfb_base;
78 if (si->capabilities & VIDEO_CAPABILITY_64BIT_BASE)
79 base |= (u64)si->ext_lfb_base << 32;
80 if (!base || (u64)(resource_size_t)base != base) {
81 printk(KERN_DEBUG "sysfb: inaccessible VRAM base\n");
82 return -EINVAL;
83 }
70 84
71 /* don't use lfb_size as it may contain the whole VMEM instead of only 85 /* don't use lfb_size as it may contain the whole VMEM instead of only
72 * the part that is occupied by the framebuffer */ 86 * the part that is occupied by the framebuffer */
@@ -81,8 +95,8 @@ __init int create_simplefb(const struct screen_info *si,
81 memset(&res, 0, sizeof(res)); 95 memset(&res, 0, sizeof(res));
82 res.flags = IORESOURCE_MEM | IORESOURCE_BUSY; 96 res.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
83 res.name = simplefb_resname; 97 res.name = simplefb_resname;
84 res.start = si->lfb_base; 98 res.start = base;
85 res.end = si->lfb_base + len - 1; 99 res.end = res.start + len - 1;
86 if (res.end <= res.start) 100 if (res.end <= res.start)
87 return -EINVAL; 101 return -EINVAL;
88 102