Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI fixes from Thomas Gleixner: "Three fixes from EFI land: - prevent accessing a Graphic Output Device (GOP) which the kernel does not know to handle - prevent PCI reconfiguration to modify a BAR which covers the framebuffer because that's already in use through the EFI GOP interface - avoid reserving EFI runtime regions as this results in bogus memory mappings" * 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/efi: Don't try to reserve runtime regions efi/fb: Avoid reconfiguration of BAR that covers the framebuffer efi/libstub: Skip GOP with PIXEL_BLT_ONLY format
This commit is contained in:
commit
f399ecb4b4
@ -201,6 +201,10 @@ void __init efi_arch_mem_reserve(phys_addr_t addr, u64 size)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No need to reserve regions that will never be freed. */
|
||||||
|
if (md.attribute & EFI_MEMORY_RUNTIME)
|
||||||
|
return;
|
||||||
|
|
||||||
size += addr % EFI_PAGE_SIZE;
|
size += addr % EFI_PAGE_SIZE;
|
||||||
size = round_up(size, EFI_PAGE_SIZE);
|
size = round_up(size, EFI_PAGE_SIZE);
|
||||||
addr = round_down(addr, EFI_PAGE_SIZE);
|
addr = round_down(addr, EFI_PAGE_SIZE);
|
||||||
|
@ -149,7 +149,8 @@ setup_gop32(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
|||||||
|
|
||||||
status = __gop_query32(sys_table_arg, gop32, &info, &size,
|
status = __gop_query32(sys_table_arg, gop32, &info, &size,
|
||||||
¤t_fb_base);
|
¤t_fb_base);
|
||||||
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
if (status == EFI_SUCCESS && (!first_gop || conout_found) &&
|
||||||
|
info->pixel_format != PIXEL_BLT_ONLY) {
|
||||||
/*
|
/*
|
||||||
* Systems that use the UEFI Console Splitter may
|
* Systems that use the UEFI Console Splitter may
|
||||||
* provide multiple GOP devices, not all of which are
|
* provide multiple GOP devices, not all of which are
|
||||||
@ -266,7 +267,8 @@ setup_gop64(efi_system_table_t *sys_table_arg, struct screen_info *si,
|
|||||||
|
|
||||||
status = __gop_query64(sys_table_arg, gop64, &info, &size,
|
status = __gop_query64(sys_table_arg, gop64, &info, &size,
|
||||||
¤t_fb_base);
|
¤t_fb_base);
|
||||||
if (status == EFI_SUCCESS && (!first_gop || conout_found)) {
|
if (status == EFI_SUCCESS && (!first_gop || conout_found) &&
|
||||||
|
info->pixel_format != PIXEL_BLT_ONLY) {
|
||||||
/*
|
/*
|
||||||
* Systems that use the UEFI Console Splitter may
|
* Systems that use the UEFI Console Splitter may
|
||||||
* provide multiple GOP devices, not all of which are
|
* provide multiple GOP devices, not all of which are
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <linux/efi.h>
|
#include <linux/efi.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/screen_info.h>
|
#include <linux/screen_info.h>
|
||||||
#include <video/vga.h>
|
#include <video/vga.h>
|
||||||
@ -143,6 +144,8 @@ static struct attribute *efifb_attrs[] = {
|
|||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(efifb);
|
ATTRIBUTE_GROUPS(efifb);
|
||||||
|
|
||||||
|
static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */
|
||||||
|
|
||||||
static int efifb_probe(struct platform_device *dev)
|
static int efifb_probe(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
struct fb_info *info;
|
struct fb_info *info;
|
||||||
@ -152,7 +155,7 @@ static int efifb_probe(struct platform_device *dev)
|
|||||||
unsigned int size_total;
|
unsigned int size_total;
|
||||||
char *option = NULL;
|
char *option = NULL;
|
||||||
|
|
||||||
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
|
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI || pci_dev_disabled)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (fb_get_options("efifb", &option))
|
if (fb_get_options("efifb", &option))
|
||||||
@ -360,3 +363,64 @@ static struct platform_driver efifb_driver = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
builtin_platform_driver(efifb_driver);
|
builtin_platform_driver(efifb_driver);
|
||||||
|
|
||||||
|
#if defined(CONFIG_PCI) && !defined(CONFIG_X86)
|
||||||
|
|
||||||
|
static bool pci_bar_found; /* did we find a BAR matching the efifb base? */
|
||||||
|
|
||||||
|
static void claim_efifb_bar(struct pci_dev *dev, int idx)
|
||||||
|
{
|
||||||
|
u16 word;
|
||||||
|
|
||||||
|
pci_bar_found = true;
|
||||||
|
|
||||||
|
pci_read_config_word(dev, PCI_COMMAND, &word);
|
||||||
|
if (!(word & PCI_COMMAND_MEMORY)) {
|
||||||
|
pci_dev_disabled = true;
|
||||||
|
dev_err(&dev->dev,
|
||||||
|
"BAR %d: assigned to efifb but device is disabled!\n",
|
||||||
|
idx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pci_claim_resource(dev, idx)) {
|
||||||
|
pci_dev_disabled = true;
|
||||||
|
dev_err(&dev->dev,
|
||||||
|
"BAR %d: failed to claim resource for efifb!\n", idx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void efifb_fixup_resources(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
u64 base = screen_info.lfb_base;
|
||||||
|
u64 size = screen_info.lfb_size;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
|
||||||
|
base |= (u64)screen_info.ext_lfb_base << 32;
|
||||||
|
|
||||||
|
if (!base)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < PCI_STD_RESOURCE_END; i++) {
|
||||||
|
struct resource *res = &dev->resource[i];
|
||||||
|
|
||||||
|
if (!(res->flags & IORESOURCE_MEM))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (res->start <= base && res->end >= base + size - 1) {
|
||||||
|
claim_efifb_bar(dev, i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY,
|
||||||
|
16, efifb_fixup_resources);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user