Skip to contentSkip to conversation

arm efi minor fixes

PATCH Superseded Ard Biesheuvel 4 participants 16 messages Jan 28, 2016 – Feb 3, 2016

Subsystems (2)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover arm efi minor fixes

This fixes two minor issues with the handling of .init data in the stub (#1, #2)

Patch #3 replaces some instances of early_memremap() with early_memremap_ro() where the region in question is only accessed in r/o mode.

Ard Biesheuvel (3):
arm64: efistub: drop __init annotation from handle_kernel_image()
arm64: vmlinux.lds.S: handle .init.rodata.xxx and .init.bss sections
efi: arm-init: use read-only early mappings

 arch/arm64/kernel/vmlinux.lds.S           |  1 +
 drivers/firmware/efi/arm-init.c           | 14 +++++++-------
 drivers/firmware/efi/libstub/arm64-stub.c | 14 +++++++-------
 3 files changed, 15 insertions(+), 14 deletions(-)
Signature · 1 line
2.5.0
#1 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

After moving arm64-stub.c to libstub/, all of its sections are emitted as .init.xxx sections automatically, and the __init annotation of handle_kernel_image() causes it to end up in .init.init.text, which is not recognized as an __init section by the linker scripts. So drop the annotation.

---
 drivers/firmware/efi/libstub/arm64-stub.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +7 -7
index 78dfbd34b6bf..9e0342745e4f 100644
@@ -13,13 +13,13 @@
 #include <asm/efi.h>
 #include <asm/sections.h>
 
-efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
-					unsigned long *image_addr,
-					unsigned long *image_size,
-					unsigned long *reserve_addr,
-					unsigned long *reserve_size,
-					unsigned long dram_base,
-					efi_loaded_image_t *image)
+efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
+				 unsigned long *image_addr,
+				 unsigned long *image_size,
+				 unsigned long *reserve_addr,
+				 unsigned long *reserve_size,
+				 unsigned long dram_base,
+				 efi_loaded_image_t *image)
 {
 	efi_status_t status;
 	unsigned long kernel_size, kernel_memsize = 0;
Signature · 1 line
2.5.0
#2 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 10 lines · Ard Biesheuvel

After moving arm64-stub.c to libstub/, all of its sections are emitted as .init.xxx sections automatically, and the __init annotation of handle_kernel_image() causes it to end up in .init.init.text, which is not recognized as an __init section by the linker scripts. So drop the annotation.

---
 drivers/firmware/efi/libstub/arm64-stub.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

Will

Quoted 28 lines
drivers/firmware/efi/libstub/arm64-stub.c +7 -7
index 78dfbd34b6bf..9e0342745e4f 100644
@@ -13,13 +13,13 @@
 #include <asm/efi.h>
 #include <asm/sections.h>
 
-efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
-					unsigned long *image_addr,
-					unsigned long *image_size,
-					unsigned long *reserve_addr,
-					unsigned long *reserve_size,
-					unsigned long dram_base,
-					efi_loaded_image_t *image)
+efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
+				 unsigned long *image_addr,
+				 unsigned long *image_size,
+				 unsigned long *reserve_addr,
+				 unsigned long *reserve_size,
+				 unsigned long dram_base,
+				 efi_loaded_image_t *image)
 {
 	efi_status_t status;
 	unsigned long kernel_size, kernel_memsize = 0;
Signature · 1 line
2.5.0
#3 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

In reply to Ard Biesheuvel
Quoted 39 lines · Ard Biesheuvel

After moving arm64-stub.c to libstub/, all of its sections are emitted as .init.xxx sections automatically, and the __init annotation of handle_kernel_image() causes it to end up in .init.init.text, which is not recognized as an __init section by the linker scripts. So drop the annotation.

---
 drivers/firmware/efi/libstub/arm64-stub.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +7 -7
index 78dfbd34b6bf..9e0342745e4f 100644
@@ -13,13 +13,13 @@
 #include <asm/efi.h>
 #include <asm/sections.h>
 
-efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
-					unsigned long *image_addr,
-					unsigned long *image_size,
-					unsigned long *reserve_addr,
-					unsigned long *reserve_size,
-					unsigned long dram_base,
-					efi_loaded_image_t *image)
+efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
+				 unsigned long *image_addr,
+				 unsigned long *image_size,
+				 unsigned long *reserve_addr,
+				 unsigned long *reserve_size,
+				 unsigned long dram_base,
+				 efi_loaded_image_t *image)
 {
 	efi_status_t status;
 	unsigned long kernel_size, kernel_memsize = 0;
Signature · 1 line
2.5.0

Would it make more sense to #undef __init in one of the arm64 efistub header files? I'm thinking of the case where some poor unsuspecting developer writes a new function and marks it as __init, and we miss it during review.

At least if we do the #undef we can document why __init makes no sense in the EFI stub, and at the same time automatically fix things up.

An alternative would be to write some Kbuild magic that complains if it sees __init, but that seems like more work than is reasonable.

#4 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 37 lines · Matt Fleming
Quoted 36 lines · Ard Biesheuvel

After moving arm64-stub.c to libstub/, all of its sections are emitted as .init.xxx sections automatically, and the __init annotation of handle_kernel_image() causes it to end up in .init.init.text, which is not recognized as an __init section by the linker scripts. So drop the annotation.

---
 drivers/firmware/efi/libstub/arm64-stub.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/firmware/efi/libstub/arm64-stub.c +7 -7
index 78dfbd34b6bf..9e0342745e4f 100644
@@ -13,13 +13,13 @@
 #include <asm/efi.h>
 #include <asm/sections.h>
 
-efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
-                                     unsigned long *image_addr,
-                                     unsigned long *image_size,
-                                     unsigned long *reserve_addr,
-                                     unsigned long *reserve_size,
-                                     unsigned long dram_base,
-                                     efi_loaded_image_t *image)
+efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg,
+                              unsigned long *image_addr,
+                              unsigned long *image_size,
+                              unsigned long *reserve_addr,
+                              unsigned long *reserve_size,
+                              unsigned long dram_base,
+                              efi_loaded_image_t *image)
 {
      efi_status_t status;
      unsigned long kernel_size, kernel_memsize = 0;
Quoted 9 lines
Quoted 3 lines

--
2.5.0

Would it make more sense to #undef __init in one of the arm64 efistub header files? I'm thinking of the case where some poor unsuspecting developer writes a new function and marks it as __init, and we miss it during review.

Yes, I can add it to efistub.h, and make sure it gets included in all the files

Should we #undef it and #define it to a string that is easily grep'ed for, so it is easy to find the explanatory comment that goes along with it?
E.g.,

#define __init __init_not_supported_in_efi_stub

Quoted 5 lines

At least if we do the #undef we can document why __init makes no sense in the EFI stub, and at the same time automatically fix things up.

An alternative would be to write some Kbuild magic that complains if it sees __init, but that seems like more work than is reasonable.

#5 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 8 lines · Ard Biesheuvel
Quoted 6 lines · Matt Fleming

Would it make more sense to #undef __init in one of the arm64 efistub header files? I'm thinking of the case where some poor unsuspecting developer writes a new function and marks it as __init, and we miss it during review.

Quoted 8 lines

Yes, I can add it to efistub.h, and make sure it gets included in all the files

Should we #undef it and #define it to a string that is easily grep'ed for, so it is easy to find the explanatory comment that goes along with it?
E.g.,

#define __init __init_not_supported_in_efi_stub

This would produce a compilation failure if someone tags something as __init right? Looks fine to me.

#6 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 16 lines · Matt Fleming
Quoted 15 lines · Ard Biesheuvel
Quoted 6 lines · Matt Fleming

Would it make more sense to #undef __init in one of the arm64 efistub header files? I'm thinking of the case where some poor unsuspecting developer writes a new function and marks it as __init, and we miss it during review.

Yes, I can add it to efistub.h, and make sure it gets included in all the files

Should we #undef it and #define it to a string that is easily grep'ed for, so it is easy to find the explanatory comment that goes along with it?
E.g.,

Quoted 4 lines
Quoted 1 line

#define __init __init_not_supported_in_efi_stub

This would produce a compilation failure if someone tags something as __init right? Looks fine to me.

Yes, but it makes the error message difficult to decipher, since __init is printed and not what it resolves to. Locally, I tried this, which seems to work:

#undef __init
#define __init __attribute__((__init_not_supported_in_efi_stub)) #pragma GCC diagnostic error "-Wattributes"

which produces

CC drivers/firmware/efi/libstub/arm-stub.o
/home/ard/linux-2.6/drivers/firmware/efi/libstub/arm-stub.c:24:1:
error: ?__init_not_supported_in_efi_stub? attribute directive ignored [-Werror=attributes]
{
^
cc1: some warnings being treated as errors

which is slightly dodgy, but at least puts the string right in the error message

#7 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 40 lines · Ard Biesheuvel
Quoted 16 lines · Matt Fleming
Quoted 15 lines · Ard Biesheuvel
Quoted 6 lines · Matt Fleming

Would it make more sense to #undef __init in one of the arm64 efistub header files? I'm thinking of the case where some poor unsuspecting developer writes a new function and marks it as __init, and we miss it during review.

Yes, I can add it to efistub.h, and make sure it gets included in all the files

Should we #undef it and #define it to a string that is easily grep'ed for, so it is easy to find the explanatory comment that goes along with it?
E.g.,

Quoted 4 lines
Quoted 1 line

#define __init __init_not_supported_in_efi_stub

This would produce a compilation failure if someone tags something as __init right? Looks fine to me.

Yes, but it makes the error message difficult to decipher, since __init is printed and not what it resolves to. Locally, I tried this, which seems to work:

#undef __init
#define __init __attribute__((__init_not_supported_in_efi_stub)) #pragma GCC diagnostic error "-Wattributes"

which produces

CC drivers/firmware/efi/libstub/arm-stub.o
/home/ard/linux-2.6/drivers/firmware/efi/libstub/arm-stub.c:24:1:
error: ?__init_not_supported_in_efi_stub? attribute directive ignored [-Werror=attributes]
{
^
cc1: some warnings being treated as errors

Quoted 1 line

which is slightly dodgy, but at least puts the string right in the error message

What about,

#define __init __compiletime_error("__init not supported in EFI boot stub")

?

#8 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 41 lines · Matt Fleming
Quoted 40 lines · Ard Biesheuvel
Quoted 16 lines · Matt Fleming
Quoted 15 lines · Ard Biesheuvel
Quoted 6 lines · Matt Fleming

Would it make more sense to #undef __init in one of the arm64 efistub header files? I'm thinking of the case where some poor unsuspecting developer writes a new function and marks it as __init, and we miss it during review.

Yes, I can add it to efistub.h, and make sure it gets included in all the files

Should we #undef it and #define it to a string that is easily grep'ed for, so it is easy to find the explanatory comment that goes along with it?
E.g.,

Quoted 4 lines
Quoted 1 line

#define __init __init_not_supported_in_efi_stub

This would produce a compilation failure if someone tags something as __init right? Looks fine to me.

Yes, but it makes the error message difficult to decipher, since __init is printed and not what it resolves to. Locally, I tried this, which seems to work:

#undef __init
#define __init __attribute__((__init_not_supported_in_efi_stub)) #pragma GCC diagnostic error "-Wattributes"

which produces

CC drivers/firmware/efi/libstub/arm-stub.o
/home/ard/linux-2.6/drivers/firmware/efi/libstub/arm-stub.c:24:1:
error: ?__init_not_supported_in_efi_stub? attribute directive ignored [-Werror=attributes]
{
^
cc1: some warnings being treated as errors

Quoted 6 lines
Quoted 1 line

which is slightly dodgy, but at least puts the string right in the error message

What about,

#define __init __compiletime_error("__init not supported in EFI boot stub")

That only works for invocations, i.e., it needs to be used in header files, and will trigger the error if a call to the function remains after optimization. We want it at function definition time instead.

#9 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 10 lines · Ard Biesheuvel
Quoted 5 lines · Matt Fleming

What about,

#define __init __compiletime_error("__init not supported in EFI boot stub")

That only works for invocations, i.e., it needs to be used in header files, and will trigger the error if a call to the function remains after optimization. We want it at function definition time instead.

Good point.

OK, how about we just do the #undef, call it good, and I add the task of printing some helpful error message to my growing TODO list?

#10 lore raw

PATCH 1/3 arm64: efistub: drop __init annotation from handle_kernel_image()

Quoted 8 lines · Matt Fleming
Quoted 7 lines · Ard Biesheuvel
Quoted 5 lines · Matt Fleming

What about,

#define __init __compiletime_error("__init not supported in EFI boot stub")

Quoted 8 lines
Quoted 3 lines

That only works for invocations, i.e., it needs to be used in header files, and will trigger the error if a call to the function remains after optimization. We want it at function definition time instead.

Good point.

OK, how about we just do the #undef, call it good, and I add the task of printing some helpful error message to my growing TODO list?

I take it you didn't like my #pragma then? :-)

In any case, I don't care deeply about this, so just #undef'ing it is fine by me

#11 lore raw

PATCH 2/3 arm64: vmlinux.lds.S: handle .init.rodata.xxx and .init.bss sections

In reply to Ard Biesheuvel

The EFI stub is typically built into the decompressor (x86, ARM) so none of its symbols are annotated as __init. However, on arm64, the stub is linked into the kernel proper, and the code is __init annotated at the section level by prepending all names of SHF_ALLOC sections with '.init'.

This results in section names like .init.rodata.str1.8 (for string literals) and .init.bss (which is tiny), both of which can be moved into the .init.data output section.

---
 arch/arm64/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/kernel/vmlinux.lds.S +1 -0
index e3928f578891..cbf4db440e9c 100644
@@ -134,6 +134,7 @@ SECTIONS
 		CON_INITCALL
 		SECURITY_INITCALL
 		INIT_RAM_FS
+		*(.init.rodata.* .init.bss)	/* from the EFI stub */
 	}
 	.exit.data : {
 		ARM_EXIT_KEEP(EXIT_DATA)
Signature · 1 line
2.5.0
#12 lore raw

PATCH 2/3 arm64: vmlinux.lds.S: handle .init.rodata.xxx and .init.bss sections

Quoted 5 lines · Ard Biesheuvel

The EFI stub is typically built into the decompressor (x86, ARM) so none of its symbols are annotated as __init. However, on arm64, the stub is linked into the kernel proper, and the code is __init annotated at the section level by prepending all names of SHF_ALLOC sections with '.init'.

Quoted 8 lines

This results in section names like .init.rodata.str1.8 (for string literals) and .init.bss (which is tiny), both of which can be moved into the .init.data output section.

---
 arch/arm64/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)

Will

Quoted 15 lines
arch/arm64/kernel/vmlinux.lds.S +1 -0
index e3928f578891..cbf4db440e9c 100644
@@ -134,6 +134,7 @@ SECTIONS
 		CON_INITCALL
 		SECURITY_INITCALL
 		INIT_RAM_FS
+		*(.init.rodata.* .init.bss)	/* from the EFI stub */
 	}
 	.exit.data : {
 		ARM_EXIT_KEEP(EXIT_DATA)
Signature · 1 line
2.5.0
#13 lore raw

PATCH 2/3 arm64: vmlinux.lds.S: handle .init.rodata.xxx and .init.bss sections

In reply to Ard Biesheuvel
Quoted 19 lines · Ard Biesheuvel

The EFI stub is typically built into the decompressor (x86, ARM) so none of its symbols are annotated as __init. However, on arm64, the stub is linked into the kernel proper, and the code is __init annotated at the section level by prepending all names of SHF_ALLOC sections with '.init'.

This results in section names like .init.rodata.str1.8 (for string literals) and .init.bss (which is tiny), both of which can be moved into the .init.data output section.

---
 arch/arm64/kernel/vmlinux.lds.S | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/kernel/vmlinux.lds.S +0 -0
index e3928f578891..cbf4db440e9c 100644

arch/arm64/kernel/vmlinux.lds.S SECTIONS · line 140

Quoted 7 lines
arch/arm64/kernel/vmlinux.lds.S +1 -0
@@ -134,6 +134,7 @@ SECTIONS
 		CON_INITCALL
 		SECURITY_INITCALL
 		INIT_RAM_FS
+		*(.init.rodata.* .init.bss)	/* from the EFI stub */
 	}
 	.exit.data : {
 		ARM_EXIT_KEEP(EXIT_DATA)

FWIW,

#14 lore raw

PATCH 3/3 efi: arm-init: use read-only early mappings

In reply to Ard Biesheuvel

The early mappings of the EFI system table contents and the UEFI memory map are read-only from the OS point of view. So map them read-only to protect them from inadvertent modification.

---
 drivers/firmware/efi/arm-init.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/firmware/efi/arm-init.c +7 -7
index 9e15d571b53c..aa1f743152a2 100644
@@ -61,8 +61,8 @@ static int __init uefi_init(void)
 	char vendor[100] = "unknown";
 	int i, retval;
 
-	efi.systab = early_memremap(efi_system_table,
-				    sizeof(efi_system_table_t));
+	efi.systab = early_memremap_ro(efi_system_table,
+				       sizeof(efi_system_table_t));
 	if (efi.systab == NULL) {
 		pr_warn("Unable to map EFI system table.\n");
 		return -ENOMEM;
@@ -86,8 +86,8 @@ static int __init uefi_init(void)
 			efi.systab->hdr.revision & 0xffff);
 
 	/* Show what we know for posterity */
-	c16 = early_memremap(efi_to_phys(efi.systab->fw_vendor),
-			     sizeof(vendor) * sizeof(efi_char16_t));
+	c16 = early_memremap_ro(efi_to_phys(efi.systab->fw_vendor),
+				sizeof(vendor) * sizeof(efi_char16_t));
 	if (c16) {
 		for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
 			vendor[i] = c16[i];
@@ -100,8 +100,8 @@ static int __init uefi_init(void)
 		efi.systab->hdr.revision & 0xffff, vendor);
 
 	table_size = sizeof(efi_config_table_64_t) * efi.systab->nr_tables;
-	config_tables = early_memremap(efi_to_phys(efi.systab->tables),
-				       table_size);
+	config_tables = early_memremap_ro(efi_to_phys(efi.systab->tables),
+					  table_size);
 	if (config_tables == NULL) {
 		pr_warn("Unable to map EFI config table array.\n");
 		retval = -ENOMEM;
@@ -185,7 +185,7 @@ void __init efi_init(void)
 	efi_system_table = params.system_table;
 
 	memmap.phys_map = params.mmap;
-	memmap.map = early_memremap(params.mmap, params.mmap_size);
+	memmap.map = early_memremap_ro(params.mmap, params.mmap_size);
 	if (memmap.map == NULL) {
 		/*
 		* If we are booting via UEFI, the UEFI memory map is the only
Signature · 1 line
2.5.0
reviewer
#15 lore raw

cover arm efi minor fixes

In reply to Ard Biesheuvel
Quoted 4 lines · Ard Biesheuvel

This fixes two minor issues with the handling of .init data in the stub (#1, #2)

Patch #3 replaces some instances of early_memremap() with early_memremap_ro() where the region in question is only accessed in r/o mode.

Nice!

The series looks sensible to me, and having given it a spin on Juno (atop of v4.5-rc1 defconfig) everything seems to work, so FWIW:

Mark.

Quoted 13 lines

Ard Biesheuvel (3):
arm64: efistub: drop __init annotation from handle_kernel_image()
arm64: vmlinux.lds.S: handle .init.rodata.xxx and .init.bss sections
efi: arm-init: use read-only early mappings

 arch/arm64/kernel/vmlinux.lds.S           |  1 +
 drivers/firmware/efi/arm-init.c           | 14 +++++++-------
 drivers/firmware/efi/libstub/arm64-stub.c | 14 +++++++-------
 3 files changed, 15 insertions(+), 14 deletions(-)
Signature · 1 line
2.5.0