Skip to content

Commit ae7e123

Browse files
jgross1Ingo Molnar
authored andcommitted
x86/boot: Add ACPI RSDP address to setup_header
Xen PVH guests receive the address of the RSDP table from Xen. In order to support booting a Xen PVH guest via Grub2 using the standard x86 boot entry we need a way for Grub2 to pass the RSDP address to the kernel. For this purpose expand the struct setup_header to hold the physical address of the RSDP address. Being zero means it isn't specified and has to be located the legacy way (searching through low memory or EBDA). While documenting the new setup_header layout and protocol version 2.14 add the missing documentation of protocol version 2.13. There are Grub2 versions in several distros with a downstream patch violating the boot protocol by writing past the end of setup_header. This requires another update of the boot protocol to enable the kernel to distinguish between a specified RSDP address and one filled with garbage by such a broken Grub2. From protocol 2.14 on Grub2 will write the version it is supporting (but never a higher value than found to be supported by the kernel) ored with 0x8000 to the version field of setup_header. This enables the kernel to know up to which field Grub2 has written information to. All fields after that are supposed to be clobbered. Signed-off-by: Juergen Gross <jgross@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: boris.ostrovsky@oracle.com Cc: bp@alien8.de Cc: corbet@lwn.net Cc: linux-doc@vger.kernel.org Cc: xen-devel@lists.xenproject.org Link: http://lkml.kernel.org/r/20181010061456.22238-3-jgross@suse.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent 357d291 commit ae7e123

File tree

7 files changed

+62
-2
lines changed

7 files changed

+62
-2
lines changed

Documentation/x86/boot.txt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@ Protocol 2.12: (Kernel 3.8) Added the xloadflags field and extension fields
6161
to struct boot_params for loading bzImage and ramdisk
6262
above 4G in 64bit.
6363

64+
Protocol 2.13: (Kernel 3.14) Support 32- and 64-bit flags being set in
65+
xloadflags to support booting a 64-bit kernel from 32-bit
66+
EFI
67+
68+
Protocol 2.14: (Kernel 4.20) Added acpi_rsdp_addr holding the physical
69+
address of the ACPI RSDP table.
70+
The bootloader updates version with:
71+
0x8000 | min(kernel-version, bootloader-version)
72+
kernel-version being the protocol version supported by
73+
the kernel and bootloader-version the protocol version
74+
supported by the bootloader.
75+
6476
**** MEMORY LAYOUT
6577

6678
The traditional memory map for the kernel loader, used for Image or
@@ -197,6 +209,7 @@ Offset Proto Name Meaning
197209
0258/8 2.10+ pref_address Preferred loading address
198210
0260/4 2.10+ init_size Linear memory required during initialization
199211
0264/4 2.11+ handover_offset Offset of handover entry point
212+
0268/8 2.14+ acpi_rsdp_addr Physical address of RSDP table
200213

201214
(1) For backwards compatibility, if the setup_sects field contains 0, the
202215
real value is 4.
@@ -309,14 +322,20 @@ Protocol: 2.00+
309322
Contains the magic number "HdrS" (0x53726448).
310323

311324
Field name: version
312-
Type: read
325+
Type: modify
313326
Offset/size: 0x206/2
314327
Protocol: 2.00+
315328

316329
Contains the boot protocol version, in (major << 8)+minor format,
317330
e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version
318331
10.17.
319332

333+
Up to protocol version 2.13 this information is only read by the
334+
bootloader. From protocol version 2.14 onwards the bootloader will
335+
write the used protocol version or-ed with 0x8000 to the field. The
336+
used protocol version will be the minimum of the supported protocol
337+
versions of the bootloader and the kernel.
338+
320339
Field name: realmode_swtch
321340
Type: modify (optional)
322341
Offset/size: 0x208/4
@@ -744,6 +763,17 @@ Offset/size: 0x264/4
744763

745764
See EFI HANDOVER PROTOCOL below for more details.
746765

766+
Field name: acpi_rsdp_addr
767+
Type: write
768+
Offset/size: 0x268/8
769+
Protocol: 2.14+
770+
771+
This field can be set by the boot loader to tell the kernel the
772+
physical address of the ACPI RSDP table.
773+
774+
A value of 0 indicates the kernel should fall back to the standard
775+
methods to locate the RSDP.
776+
747777

748778
**** THE IMAGE CHECKSUM
749779

arch/x86/boot/header.S

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ _start:
300300
# Part 2 of the header, from the old setup.S
301301

302302
.ascii "HdrS" # header signature
303-
.word 0x020d # header version number (>= 0x0105)
303+
.word 0x020e # header version number (>= 0x0105)
304304
# or else old loadlin-1.5 will fail)
305305
.globl realmode_swtch
306306
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -558,6 +558,10 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
558558
init_size: .long INIT_SIZE # kernel initialization size
559559
handover_offset: .long 0 # Filled in by build.c
560560

561+
acpi_rsdp_addr: .quad 0 # 64-bit physical pointer to the
562+
# ACPI RSDP table, added with
563+
# version 2.14
564+
561565
# End of setup header #####################################################
562566

563567
.section ".entrytext", "ax"

arch/x86/include/asm/x86_init.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,4 +303,6 @@ extern void x86_init_noop(void);
303303
extern void x86_init_uint_noop(unsigned int unused);
304304
extern bool x86_pnpbios_disabled(void);
305305

306+
void x86_verify_bootdata_version(void);
307+
306308
#endif

arch/x86/include/uapi/asm/bootparam.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#define RAMDISK_PROMPT_FLAG 0x8000
1717
#define RAMDISK_LOAD_FLAG 0x4000
1818

19+
/* version flags */
20+
#define VERSION_WRITTEN 0x8000
21+
1922
/* loadflags */
2023
#define LOADED_HIGH (1<<0)
2124
#define KASLR_FLAG (1<<1)
@@ -86,6 +89,7 @@ struct setup_header {
8689
__u64 pref_address;
8790
__u32 init_size;
8891
__u32 handover_offset;
92+
__u64 acpi_rsdp_addr;
8993
} __attribute__((packed));
9094

9195
struct sys_desc_table {

arch/x86/kernel/head32.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ asmlinkage __visible void __init i386_start_kernel(void)
3737
cr4_init_shadow();
3838

3939
sanitize_boot_params(&boot_params);
40+
x86_verify_bootdata_version();
4041

4142
x86_early_init_platform_quirks();
4243

arch/x86/kernel/head64.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ void __init x86_64_start_reservations(char *real_mode_data)
457457
if (!boot_params.hdr.version)
458458
copy_bootdata(__va(real_mode_data));
459459

460+
x86_verify_bootdata_version();
461+
460462
x86_early_init_platform_quirks();
461463

462464
switch (boot_params.hdr.hardware_subarch) {

arch/x86/kernel/setup.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,23 @@ void __init setup_arch(char **cmdline_p)
12811281
unwind_init();
12821282
}
12831283

1284+
/*
1285+
* From boot protocol 2.14 onwards we expect the bootloader to set the
1286+
* version to "0x8000 | <used version>". In case we find a version >= 2.14
1287+
* without the 0x8000 we assume the boot loader supports 2.13 only and
1288+
* reset the version accordingly. The 0x8000 flag is removed in any case.
1289+
*/
1290+
void __init x86_verify_bootdata_version(void)
1291+
{
1292+
if (boot_params.hdr.version & VERSION_WRITTEN)
1293+
boot_params.hdr.version &= ~VERSION_WRITTEN;
1294+
else if (boot_params.hdr.version >= 0x020e)
1295+
boot_params.hdr.version = 0x020d;
1296+
1297+
if (boot_params.hdr.version < 0x020e)
1298+
boot_params.hdr.acpi_rsdp_addr = 0;
1299+
}
1300+
12841301
#ifdef CONFIG_X86_32
12851302

12861303
static struct resource video_ram_resource = {

0 commit comments

Comments
 (0)