Skip to content

Commit 7b0a911

Browse files
daveyoungIngo Molnar
authored andcommitted
efi/x86: Move the EFI BGRT init code to early init code
Before invoking the arch specific handler, efi_mem_reserve() reserves the given memory region through memblock. efi_bgrt_init() will call efi_mem_reserve() after mm_init(), at which time memblock is dead and should not be used anymore. The EFI BGRT code depends on ACPI initialization to get the BGRT ACPI table, so move parsing of the BGRT table to ACPI early boot code to ensure that efi_mem_reserve() in EFI BGRT code still use memblock safely. Tested-by: Bhupesh Sharma <bhsharma@redhat.com> Signed-off-by: Dave Young <dyoung@redhat.com> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Cc: Len Brown <lenb@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Matt Fleming <matt@codeblueprint.co.uk> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rafael J. Wysocki <rjw@rjwysocki.net> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: linux-acpi@vger.kernel.org Cc: linux-efi@vger.kernel.org Link: http://lkml.kernel.org/r/1485868902-20401-9-git-send-email-ard.biesheuvel@linaro.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent c4c39c7 commit 7b0a911

File tree

6 files changed

+59
-54
lines changed

6 files changed

+59
-54
lines changed

arch/x86/kernel/acpi/boot.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <linux/bootmem.h>
3636
#include <linux/ioport.h>
3737
#include <linux/pci.h>
38+
#include <linux/efi-bgrt.h>
3839

3940
#include <asm/irqdomain.h>
4041
#include <asm/pci_x86.h>
@@ -1557,6 +1558,12 @@ int __init early_acpi_boot_init(void)
15571558
return 0;
15581559
}
15591560

1561+
static int __init acpi_parse_bgrt(struct acpi_table_header *table)
1562+
{
1563+
efi_bgrt_init(table);
1564+
return 0;
1565+
}
1566+
15601567
int __init acpi_boot_init(void)
15611568
{
15621569
/* those are executed after early-quirks are executed */
@@ -1581,6 +1588,8 @@ int __init acpi_boot_init(void)
15811588
acpi_process_madt();
15821589

15831590
acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
1591+
if (IS_ENABLED(CONFIG_ACPI_BGRT))
1592+
acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt);
15841593

15851594
if (!acpi_noirq)
15861595
x86_init.pci.init = pci_acpi_init;

arch/x86/platform/efi/efi-bgrt.c

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,75 +19,66 @@
1919
#include <linux/efi.h>
2020
#include <linux/efi-bgrt.h>
2121

22-
struct acpi_table_bgrt *bgrt_tab;
23-
void *__initdata bgrt_image;
22+
struct acpi_table_bgrt bgrt_tab;
2423
size_t __initdata bgrt_image_size;
2524

2625
struct bmp_header {
2726
u16 id;
2827
u32 size;
2928
} __packed;
3029

31-
void __init efi_bgrt_init(void)
30+
void __init efi_bgrt_init(struct acpi_table_header *table)
3231
{
33-
acpi_status status;
3432
void *image;
3533
struct bmp_header bmp_header;
34+
struct acpi_table_bgrt *bgrt = &bgrt_tab;
3635

3736
if (acpi_disabled)
3837
return;
3938

40-
status = acpi_get_table("BGRT", 0,
41-
(struct acpi_table_header **)&bgrt_tab);
42-
if (ACPI_FAILURE(status))
43-
return;
44-
45-
if (bgrt_tab->header.length < sizeof(*bgrt_tab)) {
39+
if (table->length < sizeof(bgrt_tab)) {
4640
pr_notice("Ignoring BGRT: invalid length %u (expected %zu)\n",
47-
bgrt_tab->header.length, sizeof(*bgrt_tab));
41+
table->length, sizeof(bgrt_tab));
4842
return;
4943
}
50-
if (bgrt_tab->version != 1) {
44+
*bgrt = *(struct acpi_table_bgrt *)table;
45+
if (bgrt->version != 1) {
5146
pr_notice("Ignoring BGRT: invalid version %u (expected 1)\n",
52-
bgrt_tab->version);
53-
return;
47+
bgrt->version);
48+
goto out;
5449
}
55-
if (bgrt_tab->status & 0xfe) {
50+
if (bgrt->status & 0xfe) {
5651
pr_notice("Ignoring BGRT: reserved status bits are non-zero %u\n",
57-
bgrt_tab->status);
58-
return;
52+
bgrt->status);
53+
goto out;
5954
}
60-
if (bgrt_tab->image_type != 0) {
55+
if (bgrt->image_type != 0) {
6156
pr_notice("Ignoring BGRT: invalid image type %u (expected 0)\n",
62-
bgrt_tab->image_type);
63-
return;
57+
bgrt->image_type);
58+
goto out;
6459
}
65-
if (!bgrt_tab->image_address) {
60+
if (!bgrt->image_address) {
6661
pr_notice("Ignoring BGRT: null image address\n");
67-
return;
62+
goto out;
6863
}
6964

70-
image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB);
65+
image = early_memremap(bgrt->image_address, sizeof(bmp_header));
7166
if (!image) {
7267
pr_notice("Ignoring BGRT: failed to map image header memory\n");
73-
return;
68+
goto out;
7469
}
7570

7671
memcpy(&bmp_header, image, sizeof(bmp_header));
77-
memunmap(image);
72+
early_memunmap(image, sizeof(bmp_header));
7873
if (bmp_header.id != 0x4d42) {
7974
pr_notice("Ignoring BGRT: Incorrect BMP magic number 0x%x (expected 0x4d42)\n",
8075
bmp_header.id);
81-
return;
76+
goto out;
8277
}
8378
bgrt_image_size = bmp_header.size;
79+
efi_mem_reserve(bgrt->image_address, bgrt_image_size);
8480

85-
bgrt_image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB);
86-
if (!bgrt_image) {
87-
pr_notice("Ignoring BGRT: failed to map image memory\n");
88-
bgrt_image = NULL;
89-
return;
90-
}
91-
92-
efi_mem_reserve(bgrt_tab->image_address, bgrt_image_size);
81+
return;
82+
out:
83+
memset(bgrt, 0, sizeof(bgrt_tab));
9384
}

arch/x86/platform/efi/efi.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -542,11 +542,6 @@ void __init efi_init(void)
542542
efi_print_memmap();
543543
}
544544

545-
void __init efi_late_init(void)
546-
{
547-
efi_bgrt_init();
548-
}
549-
550545
void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
551546
{
552547
u64 addr, npages;

drivers/acpi/bgrt.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,40 +15,41 @@
1515
#include <linux/sysfs.h>
1616
#include <linux/efi-bgrt.h>
1717

18+
static void *bgrt_image;
1819
static struct kobject *bgrt_kobj;
1920

2021
static ssize_t show_version(struct device *dev,
2122
struct device_attribute *attr, char *buf)
2223
{
23-
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->version);
24+
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.version);
2425
}
2526
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
2627

2728
static ssize_t show_status(struct device *dev,
2829
struct device_attribute *attr, char *buf)
2930
{
30-
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->status);
31+
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.status);
3132
}
3233
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3334

3435
static ssize_t show_type(struct device *dev,
3536
struct device_attribute *attr, char *buf)
3637
{
37-
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_type);
38+
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_type);
3839
}
3940
static DEVICE_ATTR(type, S_IRUGO, show_type, NULL);
4041

4142
static ssize_t show_xoffset(struct device *dev,
4243
struct device_attribute *attr, char *buf)
4344
{
44-
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_x);
45+
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_x);
4546
}
4647
static DEVICE_ATTR(xoffset, S_IRUGO, show_xoffset, NULL);
4748

4849
static ssize_t show_yoffset(struct device *dev,
4950
struct device_attribute *attr, char *buf)
5051
{
51-
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab->image_offset_y);
52+
return snprintf(buf, PAGE_SIZE, "%d\n", bgrt_tab.image_offset_y);
5253
}
5354
static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL);
5455

@@ -84,15 +85,24 @@ static int __init bgrt_init(void)
8485
{
8586
int ret;
8687

87-
if (!bgrt_image)
88+
if (!bgrt_tab.image_address)
8889
return -ENODEV;
8990

91+
bgrt_image = memremap(bgrt_tab.image_address, bgrt_image_size,
92+
MEMREMAP_WB);
93+
if (!bgrt_image) {
94+
pr_notice("Ignoring BGRT: failed to map image memory\n");
95+
return -ENOMEM;
96+
}
97+
9098
bin_attr_image.private = bgrt_image;
9199
bin_attr_image.size = bgrt_image_size;
92100

93101
bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj);
94-
if (!bgrt_kobj)
95-
return -EINVAL;
102+
if (!bgrt_kobj) {
103+
ret = -EINVAL;
104+
goto out_memmap;
105+
}
96106

97107
ret = sysfs_create_group(bgrt_kobj, &bgrt_attribute_group);
98108
if (ret)
@@ -102,6 +112,8 @@ static int __init bgrt_init(void)
102112

103113
out_kobject:
104114
kobject_put(bgrt_kobj);
115+
out_memmap:
116+
memunmap(bgrt_image);
105117
return ret;
106118
}
107119
device_initcall(bgrt_init);

include/linux/efi-bgrt.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
#ifndef _LINUX_EFI_BGRT_H
22
#define _LINUX_EFI_BGRT_H
33

4-
#ifdef CONFIG_ACPI_BGRT
5-
64
#include <linux/acpi.h>
75

8-
void efi_bgrt_init(void);
6+
#ifdef CONFIG_ACPI_BGRT
7+
8+
void efi_bgrt_init(struct acpi_table_header *table);
99

1010
/* The BGRT data itself; only valid if bgrt_image != NULL. */
11-
extern void *bgrt_image;
1211
extern size_t bgrt_image_size;
13-
extern struct acpi_table_bgrt *bgrt_tab;
12+
extern struct acpi_table_bgrt bgrt_tab;
1413

1514
#else /* !CONFIG_ACPI_BGRT */
1615

17-
static inline void efi_bgrt_init(void) {}
16+
static inline void efi_bgrt_init(struct acpi_table_header *table) {}
1817

1918
#endif /* !CONFIG_ACPI_BGRT */
2019

init/main.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,6 @@ asmlinkage __visible void __init start_kernel(void)
663663
sfi_init_late();
664664

665665
if (efi_enabled(EFI_RUNTIME_SERVICES)) {
666-
efi_late_init();
667666
efi_free_boot_services();
668667
}
669668

0 commit comments

Comments
 (0)