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

Merge tag 'x86-boot-2024-03-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 boot updates from Ingo Molnar:

 - Continuing work by Ard Biesheuvel to improve the x86 early startup
   code, with the long-term goal to make it position independent:

      - Get rid of early accesses to global objects, either by moving
        them to the stack, deferring the access until later, or dropping
        the globals entirely

      - Move all code that runs early via the 1:1 mapping into
        .head.text, and move code that does not out of it, so that build
        time checks can be added later to ensure that no inadvertent
        absolute references were emitted into code that does not
        tolerate them

      - Remove fixup_pointer() and occurrences of __pa_symbol(), which
        rely on the compiler emitting absolute references, which is not
        guaranteed

 - Improve the early console code

 - Add early console message about ignored NMIs, so that users are at
   least warned about their existence - even if we cannot do anything
   about them

 - Improve the kexec code's kernel load address handling

 - Enable more X86S (simplified x86) bits

 - Simplify early boot GDT handling

 - Micro-optimize the boot code a bit

 - Misc cleanups

* tag 'x86-boot-2024-03-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (22 commits)
  x86/sev: Move early startup code into .head.text section
  x86/sme: Move early SME kernel encryption handling into .head.text
  x86/boot: Move mem_encrypt= parsing to the decompressor
  efi/libstub: Add generic support for parsing mem_encrypt=
  x86/startup_64: Simplify virtual switch on primary boot
  x86/startup_64: Simplify calculation of initial page table address
  x86/startup_64: Defer assignment of 5-level paging global variables
  x86/startup_64: Simplify CR4 handling in startup code
  x86/boot: Use 32-bit XOR to clear registers
  efi/x86: Set the PE/COFF header's NX compat flag unconditionally
  x86/boot/64: Load the final kernel GDT during early boot directly, remove startup_gdt[]
  x86/boot/64: Use RIP_REL_REF() to access early_top_pgt[]
  x86/boot/64: Use RIP_REL_REF() to access early page tables
  x86/boot/64: Use RIP_REL_REF() to access '__supported_pte_mask'
  x86/boot/64: Use RIP_REL_REF() to access early_dynamic_pgts[]
  x86/boot/64: Use RIP_REL_REF() to assign 'phys_base'
  x86/boot/64: Simplify global variable accesses in GDT/IDT programming
  x86/trampoline: Bypass compat mode in trampoline_start64() if not needed
  kexec: Allocate kernel above bzImage's pref_address
  x86/boot: Add a message about ignored early NMIs
  ...
parents e66c58f7 2e2bc42c
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -878,7 +878,8 @@ Protocol: 2.10+
  address if possible.

  A non-relocatable kernel will unconditionally move itself and to run
  at this address.
  at this address. A relocatable kernel will move itself to this address if it
  loaded below this address.

============	=======
Field name:	init_size
+5 −5
Original line number Diff line number Diff line
@@ -2111,11 +2111,11 @@ config PHYSICAL_START
	help
	  This gives the physical address where the kernel is loaded.

	  If kernel is a not relocatable (CONFIG_RELOCATABLE=n) then
	  bzImage will decompress itself to above physical address and
	  run from there. Otherwise, bzImage will run from the address where
	  it has been loaded by the boot loader and will ignore above physical
	  address.
	  If the kernel is not relocatable (CONFIG_RELOCATABLE=n) then bzImage
	  will decompress itself to above physical address and run from there.
	  Otherwise, bzImage will run from the address where it has been loaded
	  by the boot loader. The only exception is if it is loaded below the
	  above physical address, in which case it will relocate itself there.

	  In normal kdump cases one does not have to set/change this option
	  as now bzImage can be compiled as a completely relocatable image
+1 −1
Original line number Diff line number Diff line
@@ -389,5 +389,5 @@ void do_boot_page_fault(struct pt_regs *regs, unsigned long error_code)

void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code)
{
	/* Empty handler to ignore NMI during early boot */
	spurious_nmi_count++;
}
+45 −10
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ struct port_io_ops pio_ops;

memptr free_mem_ptr;
memptr free_mem_end_ptr;
int spurious_nmi_count;

static char *vidmem;
static int vidport;
@@ -164,21 +165,34 @@ void __putstr(const char *s)
	outb(0xff & (pos >> 1), vidport+1);
}

void __puthex(unsigned long value)
static noinline void __putnum(unsigned long value, unsigned int base,
			      int mindig)
{
	char alpha[2] = "0";
	int bits;
	char buf[8*sizeof(value)+1];
	char *p;

	p = buf + sizeof(buf);
	*--p = '\0';

	for (bits = sizeof(value) * 8 - 4; bits >= 0; bits -= 4) {
		unsigned long digit = (value >> bits) & 0xf;
	while (mindig-- > 0 || value) {
		unsigned char digit = value % base;
		digit += (digit >= 10) ? ('a'-10) : '0';
		*--p = digit;

		if (digit < 0xA)
			alpha[0] = '0' + digit;
		else
			alpha[0] = 'a' + (digit - 0xA);
		value /= base;
	}

		__putstr(alpha);
	__putstr(p);
}

void __puthex(unsigned long value)
{
	__putnum(value, 16, sizeof(value)*2);
}

void __putdec(unsigned long value)
{
	__putnum(value, 10, 1);
}

#ifdef CONFIG_X86_NEED_RELOCS
@@ -357,6 +371,19 @@ unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
	return entry;
}

/*
 * Set the memory encryption xloadflag based on the mem_encrypt= command line
 * parameter, if provided.
 */
static void parse_mem_encrypt(struct setup_header *hdr)
{
	int on = cmdline_find_option_bool("mem_encrypt=on");
	int off = cmdline_find_option_bool("mem_encrypt=off");

	if (on > off)
		hdr->xloadflags |= XLF_MEM_ENCRYPTION;
}

/*
 * The compressed kernel image (ZO), has been moved so that its position
 * is against the end of the buffer used to hold the uncompressed kernel
@@ -387,6 +414,8 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
	/* Clear flags intended for solely in-kernel use. */
	boot_params_ptr->hdr.loadflags &= ~KASLR_FLAG;

	parse_mem_encrypt(&boot_params_ptr->hdr);

	sanitize_boot_params(boot_params_ptr);

	if (boot_params_ptr->screen_info.orig_video_mode == 7) {
@@ -493,6 +522,12 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
	/* Disable exception handling before booting the kernel */
	cleanup_exception_handling();

	if (spurious_nmi_count) {
		error_putstr("Spurious early NMIs ignored: ");
		error_putdec(spurious_nmi_count);
		error_putstr("\n");
	}

	return output + entry_offset;
}

+3 −0
Original line number Diff line number Diff line
@@ -59,12 +59,15 @@ extern char _head[], _end[];
/* misc.c */
extern memptr free_mem_ptr;
extern memptr free_mem_end_ptr;
extern int spurious_nmi_count;
void *malloc(int size);
void free(void *where);
void __putstr(const char *s);
void __puthex(unsigned long value);
void __putdec(unsigned long value);
#define error_putstr(__x)  __putstr(__x)
#define error_puthex(__x)  __puthex(__x)
#define error_putdec(__x)  __putdec(__x)

#ifdef CONFIG_X86_VERBOSE_BOOTUP

Loading