浏览代码

Merge branch 'x86-grub2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 grub2 updates from Ingo Molnar:
 "This extends the x86 boot protocol to include an address for the RSDP
  table - utilized by Xen currently.

  Matching Grub2 patches are pending as well. (Juergen Gross)"

* 'x86-grub2-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/acpi, x86/boot: Take RSDP address for boot params if available
  x86/boot: Add ACPI RSDP address to setup_header
  x86/xen: Fix boot loader version reported for PVH guests
Linus Torvalds 6 年之前
父节点
当前提交
ac73e08eda

+ 31 - 1
Documentation/x86/boot.txt

@@ -61,6 +61,18 @@ Protocol 2.12:	(Kernel 3.8) Added the xloadflags field and extension fields
 	 	to struct boot_params for loading bzImage and ramdisk
 	 	to struct boot_params for loading bzImage and ramdisk
 		above 4G in 64bit.
 		above 4G in 64bit.
 
 
+Protocol 2.13:	(Kernel 3.14) Support 32- and 64-bit flags being set in
+		xloadflags to support booting a 64-bit kernel from 32-bit
+		EFI
+
+Protocol 2.14:	(Kernel 4.20) Added acpi_rsdp_addr holding the physical
+		address of the ACPI RSDP table.
+		The bootloader updates version with:
+		0x8000 | min(kernel-version, bootloader-version)
+		kernel-version being the protocol version supported by
+		the kernel and bootloader-version the protocol version
+		supported by the bootloader.
+
 **** MEMORY LAYOUT
 **** MEMORY LAYOUT
 
 
 The traditional memory map for the kernel loader, used for Image or
 The traditional memory map for the kernel loader, used for Image or
@@ -197,6 +209,7 @@ Offset	Proto	Name		Meaning
 0258/8	2.10+	pref_address	Preferred loading address
 0258/8	2.10+	pref_address	Preferred loading address
 0260/4	2.10+	init_size	Linear memory required during initialization
 0260/4	2.10+	init_size	Linear memory required during initialization
 0264/4	2.11+	handover_offset	Offset of handover entry point
 0264/4	2.11+	handover_offset	Offset of handover entry point
+0268/8	2.14+	acpi_rsdp_addr	Physical address of RSDP table
 
 
 (1) For backwards compatibility, if the setup_sects field contains 0, the
 (1) For backwards compatibility, if the setup_sects field contains 0, the
     real value is 4.
     real value is 4.
@@ -309,7 +322,7 @@ Protocol:	2.00+
   Contains the magic number "HdrS" (0x53726448).
   Contains the magic number "HdrS" (0x53726448).
 
 
 Field name:	version
 Field name:	version
-Type:		read
+Type:		modify
 Offset/size:	0x206/2
 Offset/size:	0x206/2
 Protocol:	2.00+
 Protocol:	2.00+
 
 
@@ -317,6 +330,12 @@ Protocol:	2.00+
   e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
   e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
   10.17.
   10.17.
 
 
+  Up to protocol version 2.13 this information is only read by the
+  bootloader. From protocol version 2.14 onwards the bootloader will
+  write the used protocol version or-ed with 0x8000 to the field. The
+  used protocol version will be the minimum of the supported protocol
+  versions of the bootloader and the kernel.
+
 Field name:	realmode_swtch
 Field name:	realmode_swtch
 Type:		modify (optional)
 Type:		modify (optional)
 Offset/size:	0x208/4
 Offset/size:	0x208/4
@@ -744,6 +763,17 @@ Offset/size:	0x264/4
 
 
   See EFI HANDOVER PROTOCOL below for more details.
   See EFI HANDOVER PROTOCOL below for more details.
 
 
+Field name:	acpi_rsdp_addr
+Type:		write
+Offset/size:	0x268/8
+Protocol:	2.14+
+
+  This field can be set by the boot loader to tell the kernel the
+  physical address of the ACPI RSDP table.
+
+  A value of 0 indicates the kernel should fall back to the standard
+  methods to locate the RSDP.
+
 
 
 **** THE IMAGE CHECKSUM
 **** THE IMAGE CHECKSUM
 
 

+ 5 - 1
arch/x86/boot/header.S

@@ -300,7 +300,7 @@ _start:
 	# Part 2 of the header, from the old setup.S
 	# Part 2 of the header, from the old setup.S
 
 
 		.ascii	"HdrS"		# header signature
 		.ascii	"HdrS"		# header signature
-		.word	0x020d		# header version number (>= 0x0105)
+		.word	0x020e		# header version number (>= 0x0105)
 					# or else old loadlin-1.5 will fail)
 					# or else old loadlin-1.5 will fail)
 		.globl realmode_swtch
 		.globl realmode_swtch
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
@@ -558,6 +558,10 @@ pref_address:		.quad LOAD_PHYSICAL_ADDR	# preferred load addr
 init_size:		.long INIT_SIZE		# kernel initialization size
 init_size:		.long INIT_SIZE		# kernel initialization size
 handover_offset:	.long 0			# Filled in by build.c
 handover_offset:	.long 0			# Filled in by build.c
 
 
+acpi_rsdp_addr:		.quad 0			# 64-bit physical pointer to the
+						# ACPI RSDP table, added with
+						# version 2.14
+
 # End of setup header #####################################################
 # End of setup header #####################################################
 
 
 	.section ".entrytext", "ax"
 	.section ".entrytext", "ax"

+ 7 - 0
arch/x86/include/asm/acpi.h

@@ -142,6 +142,8 @@ static inline u64 acpi_arch_get_root_pointer(void)
 
 
 void acpi_generic_reduced_hw_init(void);
 void acpi_generic_reduced_hw_init(void);
 
 
+u64 x86_default_get_root_pointer(void);
+
 #else /* !CONFIG_ACPI */
 #else /* !CONFIG_ACPI */
 
 
 #define acpi_lapic 0
 #define acpi_lapic 0
@@ -153,6 +155,11 @@ static inline void disable_acpi(void) { }
 
 
 static inline void acpi_generic_reduced_hw_init(void) { }
 static inline void acpi_generic_reduced_hw_init(void) { }
 
 
+static inline u64 x86_default_get_root_pointer(void)
+{
+	return 0;
+}
+
 #endif /* !CONFIG_ACPI */
 #endif /* !CONFIG_ACPI */
 
 
 #define ARCH_HAS_POWER_INIT	1
 #define ARCH_HAS_POWER_INIT	1

+ 2 - 0
arch/x86/include/asm/x86_init.h

@@ -303,4 +303,6 @@ extern void x86_init_noop(void);
 extern void x86_init_uint_noop(unsigned int unused);
 extern void x86_init_uint_noop(unsigned int unused);
 extern bool x86_pnpbios_disabled(void);
 extern bool x86_pnpbios_disabled(void);
 
 
+void x86_verify_bootdata_version(void);
+
 #endif
 #endif

+ 4 - 0
arch/x86/include/uapi/asm/bootparam.h

@@ -16,6 +16,9 @@
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_PROMPT_FLAG		0x8000
 #define RAMDISK_LOAD_FLAG		0x4000
 #define RAMDISK_LOAD_FLAG		0x4000
 
 
+/* version flags */
+#define VERSION_WRITTEN	0x8000
+
 /* loadflags */
 /* loadflags */
 #define LOADED_HIGH	(1<<0)
 #define LOADED_HIGH	(1<<0)
 #define KASLR_FLAG	(1<<1)
 #define KASLR_FLAG	(1<<1)
@@ -86,6 +89,7 @@ struct setup_header {
 	__u64	pref_address;
 	__u64	pref_address;
 	__u32	init_size;
 	__u32	init_size;
 	__u32	handover_offset;
 	__u32	handover_offset;
+	__u64	acpi_rsdp_addr;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
 struct sys_desc_table {
 struct sys_desc_table {

+ 6 - 0
arch/x86/kernel/acpi/boot.c

@@ -48,6 +48,7 @@
 #include <asm/mpspec.h>
 #include <asm/mpspec.h>
 #include <asm/smp.h>
 #include <asm/smp.h>
 #include <asm/i8259.h>
 #include <asm/i8259.h>
+#include <asm/setup.h>
 
 
 #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */
 #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */
 static int __initdata acpi_force = 0;
 static int __initdata acpi_force = 0;
@@ -1771,3 +1772,8 @@ void __init arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 	e820__range_add(addr, size, E820_TYPE_ACPI);
 	e820__range_add(addr, size, E820_TYPE_ACPI);
 	e820__update_table_print();
 	e820__update_table_print();
 }
 }
+
+u64 x86_default_get_root_pointer(void)
+{
+	return boot_params.hdr.acpi_rsdp_addr;
+}

+ 1 - 0
arch/x86/kernel/head32.c

@@ -37,6 +37,7 @@ asmlinkage __visible void __init i386_start_kernel(void)
 	cr4_init_shadow();
 	cr4_init_shadow();
 
 
 	sanitize_boot_params(&boot_params);
 	sanitize_boot_params(&boot_params);
+	x86_verify_bootdata_version();
 
 
 	x86_early_init_platform_quirks();
 	x86_early_init_platform_quirks();
 
 

+ 2 - 0
arch/x86/kernel/head64.c

@@ -457,6 +457,8 @@ void __init x86_64_start_reservations(char *real_mode_data)
 	if (!boot_params.hdr.version)
 	if (!boot_params.hdr.version)
 		copy_bootdata(__va(real_mode_data));
 		copy_bootdata(__va(real_mode_data));
 
 
+	x86_verify_bootdata_version();
+
 	x86_early_init_platform_quirks();
 	x86_early_init_platform_quirks();
 
 
 	switch (boot_params.hdr.hardware_subarch) {
 	switch (boot_params.hdr.hardware_subarch) {

+ 17 - 0
arch/x86/kernel/setup.c

@@ -1281,6 +1281,23 @@ void __init setup_arch(char **cmdline_p)
 	unwind_init();
 	unwind_init();
 }
 }
 
 
+/*
+ * From boot protocol 2.14 onwards we expect the bootloader to set the
+ * version to "0x8000 | <used version>". In case we find a version >= 2.14
+ * without the 0x8000 we assume the boot loader supports 2.13 only and
+ * reset the version accordingly. The 0x8000 flag is removed in any case.
+ */
+void __init x86_verify_bootdata_version(void)
+{
+	if (boot_params.hdr.version & VERSION_WRITTEN)
+		boot_params.hdr.version &= ~VERSION_WRITTEN;
+	else if (boot_params.hdr.version >= 0x020e)
+		boot_params.hdr.version = 0x020d;
+
+	if (boot_params.hdr.version < 0x020e)
+		boot_params.hdr.acpi_rsdp_addr = 0;
+}
+
 #ifdef CONFIG_X86_32
 #ifdef CONFIG_X86_32
 
 
 static struct resource video_ram_resource = {
 static struct resource video_ram_resource = {

+ 1 - 2
arch/x86/kernel/x86_init.c

@@ -31,7 +31,6 @@ static int __init iommu_init_noop(void) { return 0; }
 static void iommu_shutdown_noop(void) { }
 static void iommu_shutdown_noop(void) { }
 static bool __init bool_x86_init_noop(void) { return false; }
 static bool __init bool_x86_init_noop(void) { return false; }
 static void x86_op_int_noop(int cpu) { }
 static void x86_op_int_noop(int cpu) { }
-static u64 u64_x86_init_noop(void) { return 0; }
 
 
 /*
 /*
  * The platform setup functions are preset with the default functions
  * The platform setup functions are preset with the default functions
@@ -96,7 +95,7 @@ struct x86_init_ops x86_init __initdata = {
 	},
 	},
 
 
 	.acpi = {
 	.acpi = {
-		.get_root_pointer	= u64_x86_init_noop,
+		.get_root_pointer	= x86_default_get_root_pointer,
 		.reduced_hw_early_init	= acpi_generic_reduced_hw_init,
 		.reduced_hw_early_init	= acpi_generic_reduced_hw_init,
 	},
 	},
 };
 };

+ 1 - 1
arch/x86/xen/enlighten_pvh.c

@@ -76,7 +76,7 @@ static void __init init_pvh_bootparams(void)
 	 * Version 2.12 supports Xen entry point but we will use default x86/PC
 	 * Version 2.12 supports Xen entry point but we will use default x86/PC
 	 * environment (i.e. hardware_subarch 0).
 	 * environment (i.e. hardware_subarch 0).
 	 */
 	 */
-	pvh_bootparams.hdr.version = 0x212;
+	pvh_bootparams.hdr.version = (2 << 8) | 12;
 	pvh_bootparams.hdr.type_of_loader = (9 << 4) | 0; /* Xen loader */
 	pvh_bootparams.hdr.type_of_loader = (9 << 4) | 0; /* Xen loader */
 
 
 	x86_init.acpi.get_root_pointer = pvh_get_root_pointer;
 	x86_init.acpi.get_root_pointer = pvh_get_root_pointer;