Misc updates:

- Add the initrdmem= boot option to specify an initrd embedded in RAM (flash most likely)
  - Sanitize the CS value earlier during boot, which also fixes SEV-ES.
  - Various fixes and smaller cleanups.
 
 Signed-off-by: Ingo Molnar <mingo@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEBpT5eoXrXCwVQwEKEnMQ0APhK1gFAl7VKk8RHG1pbmdvQGtl
 cm5lbC5vcmcACgkQEnMQ0APhK1i25w/6A8okusHJMXyXMYddRHNiL57x3DcTRsTO
 09Wz7e0YrL53HqQEyaqtSam/0VqgSaHDQb/gRb2Ci0G+XzZ3BFYvICVWTW6NcvnA
 VSUoHC8Mr83Aq3UfAEcJZZ0bHNuoKymO256v2tZPGCSGgZoxQdoe4/6W1uMxxjLr
 NFpeyAm93zTe1+MmA/ZcFxH+xOZPYVPhl7+KgO3muMH/hGoS3Dt+RCuB9VHTgMvf
 4mN6IxN3cVHDogt7usdtWjgrYnhY0SjiWo858+MDWsrW5oXifsXLJ5jJr1Ea1nGx
 qqVyaCqAVNobOkpsBLHg1DiD/rr9A4sfS/etmAjWsPO6kAx9Mq9+B2DG5fTU/gB+
 zd76M3Jl3wyjdy6hPMyiZGlFFM9l3efyp/iYPhFWgPqVlkkOvbO+9FWVDbFtErQw
 WpEG2d8KHN4+ph8D04ExeKJKCKaYnAaHKk13fZnjjeQhatyGGAYn6hx+rT/x+onM
 2CeRG/+KcnlzKgXqYX6/YT++XlaCKgMntO/FdLT99/4CD92rqQdhwJ6JNH1U8nXO
 LWjrV5ZH6R3n5Hr5+J/Kcd9/kIfAqWG3t/eiTEPEjJIUWXEdhBoQWErSce4on5a7
 6eBfkKEQxIYAdC1iO2uoKEtEpMDvFWoIIVjdlVTFiJ8Np9uvv7lPByr/0TJ+N5b7
 fgOrzglWuxo=
 =U/uh
 -----END PGP SIGNATURE-----

Merge tag 'x86-boot-2020-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot updates from Ingo Molnar:
 "Misc updates:

   - Add the initrdmem= boot option to specify an initrd embedded in RAM
     (flash most likely)

   - Sanitize the CS value earlier during boot, which also fixes SEV-ES

   - Various fixes and smaller cleanups"

* tag 'x86-boot-2020-06-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/boot: Correct relocation destination on old linkers
  x86/boot/compressed/64: Switch to __KERNEL_CS after GDT is loaded
  x86/boot: Fix -Wint-to-pointer-cast build warning
  x86/boot: Add kstrtoul() from lib/
  x86/tboot: Mark tboot static
  x86/setup: Add an initrdmem= option to specify initrd physical address
This commit is contained in:
Linus Torvalds 2020-06-01 13:44:28 -07:00
commit ae1a4113c2
10 changed files with 90 additions and 17 deletions

View File

@ -1748,6 +1748,13 @@
initrd= [BOOT] Specify the location of the initial ramdisk initrd= [BOOT] Specify the location of the initial ramdisk
initrdmem= [KNL] Specify a physical address and size from which to
load the initrd. If an initrd is compiled in or
specified in the bootparams, it takes priority over this
setting.
Format: ss[KMG],nn[KMG]
Default is 0, 0
init_on_alloc= [MM] Fill newly allocated pages and heap objects with init_on_alloc= [MM] Fill newly allocated pages and heap objects with
zeroes. zeroes.
Format: 0 | 1 Format: 0 | 1

View File

@ -280,9 +280,9 @@ acpi_physical_address get_rsdp_addr(void)
*/ */
#define MAX_ADDR_LEN 19 #define MAX_ADDR_LEN 19
static acpi_physical_address get_cmdline_acpi_rsdp(void) static unsigned long get_cmdline_acpi_rsdp(void)
{ {
acpi_physical_address addr = 0; unsigned long addr = 0;
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
char val[MAX_ADDR_LEN] = { }; char val[MAX_ADDR_LEN] = { };
@ -292,7 +292,7 @@ static acpi_physical_address get_cmdline_acpi_rsdp(void)
if (ret < 0) if (ret < 0)
return 0; return 0;
if (kstrtoull(val, 16, &addr)) if (boot_kstrtoul(val, 16, &addr))
return 0; return 0;
#endif #endif
return addr; return addr;
@ -314,7 +314,6 @@ static unsigned long get_acpi_srat_table(void)
* different ideas about whether to trust a command-line parameter. * different ideas about whether to trust a command-line parameter.
*/ */
rsdp = (struct acpi_table_rsdp *)get_cmdline_acpi_rsdp(); rsdp = (struct acpi_table_rsdp *)get_cmdline_acpi_rsdp();
if (!rsdp) if (!rsdp)
rsdp = (struct acpi_table_rsdp *)(long) rsdp = (struct acpi_table_rsdp *)(long)
boot_params->acpi_rsdp_addr; boot_params->acpi_rsdp_addr;

View File

@ -49,16 +49,17 @@
* Position Independent Executable (PIE) so that linker won't optimize * Position Independent Executable (PIE) so that linker won't optimize
* R_386_GOT32X relocation to its fixed symbol address. Older * R_386_GOT32X relocation to its fixed symbol address. Older
* linkers generate R_386_32 relocations against locally defined symbols, * linkers generate R_386_32 relocations against locally defined symbols,
* _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less * _bss, _ebss, _got, _egot and _end, in PIE. It isn't wrong, just less
* optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle
* R_386_32 relocations when relocating the kernel. To generate * R_386_32 relocations when relocating the kernel. To generate
* R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as * R_386_RELATIVE relocations, we mark _bss, _ebss, _got, _egot and _end as
* hidden: * hidden:
*/ */
.hidden _bss .hidden _bss
.hidden _ebss .hidden _ebss
.hidden _got .hidden _got
.hidden _egot .hidden _egot
.hidden _end
__HEAD __HEAD
SYM_FUNC_START(startup_32) SYM_FUNC_START(startup_32)

View File

@ -42,6 +42,7 @@
.hidden _ebss .hidden _ebss
.hidden _got .hidden _got
.hidden _egot .hidden _egot
.hidden _end
__HEAD __HEAD
.code32 .code32
@ -393,6 +394,14 @@ SYM_CODE_START(startup_64)
addq %rax, 2(%rax) addq %rax, 2(%rax)
lgdt (%rax) lgdt (%rax)
/* Reload CS so IRET returns to a CS actually in the GDT */
pushq $__KERNEL_CS
leaq .Lon_kernel_cs(%rip), %rax
pushq %rax
lretq
.Lon_kernel_cs:
/* /*
* paging_prepare() sets up the trampoline and checks if we need to * paging_prepare() sets up the trampoline and checks if we need to
* enable 5-level paging. * enable 5-level paging.

View File

@ -117,7 +117,6 @@ static unsigned int simple_guess_base(const char *cp)
* @endp: A pointer to the end of the parsed string will be placed here * @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use * @base: The number base to use
*/ */
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
{ {
unsigned long long result = 0; unsigned long long result = 0;
@ -335,3 +334,45 @@ int kstrtoull(const char *s, unsigned int base, unsigned long long *res)
s++; s++;
return _kstrtoull(s, base, res); return _kstrtoull(s, base, res);
} }
static int _kstrtoul(const char *s, unsigned int base, unsigned long *res)
{
unsigned long long tmp;
int rv;
rv = kstrtoull(s, base, &tmp);
if (rv < 0)
return rv;
if (tmp != (unsigned long)tmp)
return -ERANGE;
*res = tmp;
return 0;
}
/**
* kstrtoul - convert a string to an unsigned long
* @s: The start of the string. The string must be null-terminated, and may also
* include a single newline before its terminating null. The first character
* may also be a plus sign, but not a minus sign.
* @base: The number base to use. The maximum supported base is 16. If base is
* given as 0, then the base of the string is automatically detected with the
* conventional semantics - If it begins with 0x the number will be parsed as a
* hexadecimal (case insensitive), if it otherwise begins with 0, it will be
* parsed as an octal number. Otherwise it will be parsed as a decimal.
* @res: Where to write the result of the conversion on success.
*
* Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
* Used as a replacement for the simple_strtoull.
*/
int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res)
{
/*
* We want to shortcut function call, but
* __builtin_types_compatible_p(unsigned long, unsigned long long) = 0.
*/
if (sizeof(unsigned long) == sizeof(unsigned long long) &&
__alignof__(unsigned long) == __alignof__(unsigned long long))
return kstrtoull(s, base, (unsigned long long *)res);
else
return _kstrtoul(s, base, res);
}

View File

@ -30,4 +30,5 @@ extern unsigned long long simple_strtoull(const char *cp, char **endp,
unsigned int base); unsigned int base);
int kstrtoull(const char *s, unsigned int base, unsigned long long *res); int kstrtoull(const char *s, unsigned int base, unsigned long long *res);
int boot_kstrtoul(const char *s, unsigned int base, unsigned long *res);
#endif /* BOOT_STRING_H */ #endif /* BOOT_STRING_H */

View File

@ -237,6 +237,9 @@ static u64 __init get_ramdisk_image(void)
ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32; ramdisk_image |= (u64)boot_params.ext_ramdisk_image << 32;
if (ramdisk_image == 0)
ramdisk_image = phys_initrd_start;
return ramdisk_image; return ramdisk_image;
} }
static u64 __init get_ramdisk_size(void) static u64 __init get_ramdisk_size(void)
@ -245,6 +248,9 @@ static u64 __init get_ramdisk_size(void)
ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32; ramdisk_size |= (u64)boot_params.ext_ramdisk_size << 32;
if (ramdisk_size == 0)
ramdisk_size = phys_initrd_size;
return ramdisk_size; return ramdisk_size;
} }

View File

@ -35,8 +35,7 @@
#include "../realmode/rm/wakeup.h" #include "../realmode/rm/wakeup.h"
/* Global pointer to shared data; NULL means no measured launch. */ /* Global pointer to shared data; NULL means no measured launch. */
struct tboot *tboot __read_mostly; static struct tboot *tboot __read_mostly;
EXPORT_SYMBOL(tboot);
/* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */ /* timeout for APs (in secs) to enter wait-for-SIPI state during shutdown */
#define AP_WAIT_TIMEOUT 1 #define AP_WAIT_TIMEOUT 1
@ -46,6 +45,11 @@ EXPORT_SYMBOL(tboot);
static u8 tboot_uuid[16] __initdata = TBOOT_UUID; static u8 tboot_uuid[16] __initdata = TBOOT_UUID;
bool tboot_enabled(void)
{
return tboot != NULL;
}
void __init tboot_probe(void) void __init tboot_probe(void)
{ {
/* Look for valid page-aligned address for shared page. */ /* Look for valid page-aligned address for shared page. */

View File

@ -121,13 +121,7 @@ struct tboot {
#define TBOOT_UUID {0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\ #define TBOOT_UUID {0xff, 0x8d, 0x3c, 0x66, 0xb3, 0xe8, 0x82, 0x4b, 0xbf,\
0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8} 0xaa, 0x19, 0xea, 0x4d, 0x5, 0x7a, 0x8}
extern struct tboot *tboot; bool tboot_enabled(void);
static inline int tboot_enabled(void)
{
return tboot != NULL;
}
extern void tboot_probe(void); extern void tboot_probe(void);
extern void tboot_shutdown(u32 shutdown_type); extern void tboot_shutdown(u32 shutdown_type);
extern struct acpi_table_header *tboot_get_dmar_table( extern struct acpi_table_header *tboot_get_dmar_table(

View File

@ -28,7 +28,7 @@ static int __init no_initrd(char *str)
__setup("noinitrd", no_initrd); __setup("noinitrd", no_initrd);
static int __init early_initrd(char *p) static int __init early_initrdmem(char *p)
{ {
phys_addr_t start; phys_addr_t start;
unsigned long size; unsigned long size;
@ -43,6 +43,17 @@ static int __init early_initrd(char *p)
} }
return 0; return 0;
} }
early_param("initrdmem", early_initrdmem);
/*
* This is here as the initrd keyword has been in use since 11/2018
* on ARM, PowerPC, and MIPS.
* It should not be; it is reserved for bootloaders.
*/
static int __init early_initrd(char *p)
{
return early_initrdmem(p);
}
early_param("initrd", early_initrd); early_param("initrd", early_initrd);
static int init_linuxrc(struct subprocess_info *info, struct cred *new) static int init_linuxrc(struct subprocess_info *info, struct cred *new)