Commit af2a9c6a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'efi-urgent-for-v6.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi

Pull EFI fixes from Ard Biesheuvel:

 - Deal with a regression in the recently refactored x86 EFI stub code
   on older Dell systems by disabling randomization of the physical load
   address

 - Use the correct load address for relocatable Loongarch kernels

* tag 'efi-urgent-for-v6.7-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
  efi/x86: Avoid physical KASLR on older Dell systems
  efi/loongarch: Use load address to calculate kernel entry address
parents 88035e56 50d7cdf7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -32,6 +32,6 @@ static inline unsigned long efi_get_kimg_min_align(void)

#define EFI_KIMG_PREFERRED_ADDRESS	PHYSADDR(VMLINUX_LOAD_ADDRESS)

unsigned long kernel_entry_address(void);
unsigned long kernel_entry_address(unsigned long kernel_addr);

#endif /* _ASM_LOONGARCH_EFI_H */
+2 −2
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
	return status;
}

unsigned long kernel_entry_address(void)
unsigned long kernel_entry_address(unsigned long kernel_addr)
{
	unsigned long base = (unsigned long)&kernel_offset - kernel_offset;

	return (unsigned long)&kernel_entry - base + VMLINUX_LOAD_ADDRESS;
	return (unsigned long)&kernel_entry - base + kernel_addr;
}
+3 −3
Original line number Diff line number Diff line
@@ -37,9 +37,9 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv)
	return EFI_SUCCESS;
}

unsigned long __weak kernel_entry_address(void)
unsigned long __weak kernel_entry_address(unsigned long kernel_addr)
{
	return *(unsigned long *)(PHYSADDR(VMLINUX_LOAD_ADDRESS) + 8);
	return *(unsigned long *)(kernel_addr + 8) - VMLINUX_LOAD_ADDRESS + kernel_addr;
}

efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
@@ -73,7 +73,7 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
	csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
	csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);

	real_kernel_entry = (void *)kernel_entry_address();
	real_kernel_entry = (void *)kernel_entry_address(kernel_addr);

	real_kernel_entry(true, (unsigned long)cmdline_ptr,
			  (unsigned long)efi_system_table);
+24 −7
Original line number Diff line number Diff line
@@ -307,18 +307,21 @@ static void setup_unaccepted_memory(void)
		efi_err("Memory acceptance protocol failed\n");
}

static efi_char16_t *efistub_fw_vendor(void)
{
	unsigned long vendor = efi_table_attr(efi_system_table, fw_vendor);

	return (efi_char16_t *)vendor;
}

static const efi_char16_t apple[] = L"Apple";

static void setup_quirks(struct boot_params *boot_params)
{
	efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long)
		efi_table_attr(efi_system_table, fw_vendor);

	if (!memcmp(fw_vendor, apple, sizeof(apple))) {
		if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))
	if (IS_ENABLED(CONFIG_APPLE_PROPERTIES) &&
	    !memcmp(efistub_fw_vendor(), apple, sizeof(apple)))
		retrieve_apple_device_properties(boot_params);
}
}

/*
 * See if we have Universal Graphics Adapter (UGA) protocol
@@ -765,11 +768,25 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)

	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
		u64 range = KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR - kernel_total_size;
		static const efi_char16_t ami[] = L"American Megatrends";

		efi_get_seed(seed, sizeof(seed));

		virt_addr += (range * seed[1]) >> 32;
		virt_addr &= ~(CONFIG_PHYSICAL_ALIGN - 1);

		/*
		 * Older Dell systems with AMI UEFI firmware v2.0 may hang
		 * while decompressing the kernel if physical address
		 * randomization is enabled.
		 *
		 * https://bugzilla.kernel.org/show_bug.cgi?id=218173
		 */
		if (efi_system_table->hdr.revision <= EFI_2_00_SYSTEM_TABLE_REVISION &&
		    !memcmp(efistub_fw_vendor(), ami, sizeof(ami))) {
			efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n");
			seed[0] = 0;
		}
	}

	status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr,