Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/efi: Fix multiple GOP device support

When multiple GOP devices exists, but none of them implements
ConOut, the code should just choose the first GOP (according to
the comments). But currently 'fb_base' will refer to the last GOP,
while other parameters to the first GOP, which will likely
result in a garbled display.

I can reliably reproduce this bug using my ASRock Z87M Extreme4
motherboard with CSM and integrated GPU disabled, and two PCIe
video cards (NVidia GT640 and GTX980), booting from efi-stub
(booting from grub works fine). On the primary display the
ASRock logo remains and on the secondary screen it is garbled
up completely.

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Cc: <stable@vger.kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matthew Garrett <mjg59@srcf.ucam.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/1444659236-24837-2-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Kővágó, Zoltán and committed by
Ingo Molnar
8a53554e 5b5f1455

+6 -2
+6 -2
arch/x86/boot/compressed/eboot.c
··· 667 667 bool conout_found = false; 668 668 void *dummy = NULL; 669 669 u32 h = handles[i]; 670 + u32 current_fb_base; 670 671 671 672 status = efi_call_early(handle_protocol, h, 672 673 proto, (void **)&gop32); ··· 679 678 if (status == EFI_SUCCESS) 680 679 conout_found = true; 681 680 682 - status = __gop_query32(gop32, &info, &size, &fb_base); 681 + status = __gop_query32(gop32, &info, &size, &current_fb_base); 683 682 if (status == EFI_SUCCESS && (!first_gop || conout_found)) { 684 683 /* 685 684 * Systems that use the UEFI Console Splitter may ··· 693 692 pixel_format = info->pixel_format; 694 693 pixel_info = info->pixel_information; 695 694 pixels_per_scan_line = info->pixels_per_scan_line; 695 + fb_base = current_fb_base; 696 696 697 697 /* 698 698 * Once we've found a GOP supporting ConOut, ··· 772 770 bool conout_found = false; 773 771 void *dummy = NULL; 774 772 u64 h = handles[i]; 773 + u32 current_fb_base; 775 774 776 775 status = efi_call_early(handle_protocol, h, 777 776 proto, (void **)&gop64); ··· 784 781 if (status == EFI_SUCCESS) 785 782 conout_found = true; 786 783 787 - status = __gop_query64(gop64, &info, &size, &fb_base); 784 + status = __gop_query64(gop64, &info, &size, &current_fb_base); 788 785 if (status == EFI_SUCCESS && (!first_gop || conout_found)) { 789 786 /* 790 787 * Systems that use the UEFI Console Splitter may ··· 798 795 pixel_format = info->pixel_format; 799 796 pixel_info = info->pixel_information; 800 797 pixels_per_scan_line = info->pixels_per_scan_line; 798 + fb_base = current_fb_base; 801 799 802 800 /* 803 801 * Once we've found a GOP supporting ConOut,