]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/x86/boot/compressed/pgtable_64.c
x86/boot/compressed/64: Find a place for 32-bit trampoline
[mirror_ubuntu-jammy-kernel.git] / arch / x86 / boot / compressed / pgtable_64.c
CommitLineData
08529078 1#include <asm/processor.h>
3548e131 2#include "pgtable.h"
08529078
KS
3
4/*
5 * __force_order is used by special_insns.h asm code to force instruction
6 * serialization.
7 *
8 * It is not referenced from the code, but GCC < 5 with -fPIE would fail
9 * due to an undefined symbol. Define it to make these ancient GCCs work.
10 */
11unsigned long __force_order;
12
3548e131
KS
13#define BIOS_START_MIN 0x20000U /* 128K, less than this is insane */
14#define BIOS_START_MAX 0x9f000U /* 640K, absolute maximum */
15
4440977b
KS
16struct paging_config {
17 unsigned long trampoline_start;
18 unsigned long l5_required;
19};
08529078 20
3548e131
KS
21/*
22 * Trampoline address will be printed by extract_kernel() for debugging
23 * purposes.
24 *
25 * Avoid putting the pointer into .bss as it will be cleared between
26 * paging_prepare() and extract_kernel().
27 */
28unsigned long *trampoline_32bit __section(.data);
29
4440977b
KS
30struct paging_config paging_prepare(void)
31{
32 struct paging_config paging_config = {};
3548e131 33 unsigned long bios_start, ebda_start;
08529078 34
a403d798
KS
35 /*
36 * Check if LA57 is desired and supported.
37 *
38 * There are two parts to the check:
39 * - if the kernel supports 5-level paging: CONFIG_X86_5LEVEL=y
40 * - if the machine supports 5-level paging:
41 * + CPUID leaf 7 is supported
42 * + the leaf has the feature bit set
43 *
44 * That's substitute for boot_cpu_has() in early boot code.
45 */
46 if (IS_ENABLED(CONFIG_X86_5LEVEL) &&
47 native_cpuid_eax(0) >= 7 &&
48 (native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)))) {
4440977b 49 paging_config.l5_required = 1;
a403d798 50 }
08529078 51
3548e131
KS
52 /*
53 * Find a suitable spot for the trampoline.
54 * This code is based on reserve_bios_regions().
55 */
56
57 ebda_start = *(unsigned short *)0x40e << 4;
58 bios_start = *(unsigned short *)0x413 << 10;
59
60 if (bios_start < BIOS_START_MIN || bios_start > BIOS_START_MAX)
61 bios_start = BIOS_START_MAX;
62
63 if (ebda_start > BIOS_START_MIN && ebda_start < bios_start)
64 bios_start = ebda_start;
65
66 /* Place the trampoline just below the end of low memory, aligned to 4k */
67 paging_config.trampoline_start = bios_start - TRAMPOLINE_32BIT_SIZE;
68 paging_config.trampoline_start = round_down(paging_config.trampoline_start, PAGE_SIZE);
69
70 trampoline_32bit = (unsigned long *)paging_config.trampoline_start;
71
4440977b 72 return paging_config;
08529078 73}