Skip to content

Commit 2d03cfa

Browse files
Yunhong Jiangallenpais
authored andcommitted
x86/realmode: Make the location of the trampoline configurable
x86 CPUs boot in real mode. This mode uses 20-bit memory addresses (16-bit registers plus 4-bit segment selectors). This implies that the trampoline must reside under the 1MB memory boundary. There are platforms in which the firmware boots the secondary CPUs, switches them to long mode and transfers control to the kernel. An example of such mechanism is the ACPI Multiprocessor Wakeup Structure. In this scenario there is no restriction to locate the trampoline under 1MB memory. Moreover, certain platforms (for example, Hyper-V VTL guests) may not have memory available for allocation under 1MB. Add a new member to struct x86_init_resources to specify the upper bound for the location of the trampoline memory. Keep the default upper bound of 1MB to conserve the current behavior. Reviewed-by: Michael Kelley <[email protected]> Originally-by: Thomas Gleixner <[email protected]> Signed-off-by: Yunhong Jiang <[email protected]> Signed-off-by: Ricardo Neri <[email protected]>
1 parent 3f932a8 commit 2d03cfa

File tree

3 files changed

+9
-4
lines changed

3 files changed

+9
-4
lines changed

arch/x86/include/asm/x86_init.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,15 @@ struct x86_init_mpparse {
3131
* platform
3232
* @memory_setup: platform specific memory setup
3333
* @dmi_setup: platform specific DMI setup
34+
* @realmode_limit: platform specific address limit for the real mode trampoline
35+
* (default 1M)
3436
*/
3537
struct x86_init_resources {
3638
void (*probe_roms)(void);
3739
void (*reserve_resources)(void);
3840
char *(*memory_setup)(void);
3941
void (*dmi_setup)(void);
42+
unsigned long realmode_limit;
4043
};
4144

4245
/**

arch/x86/kernel/x86_init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/export.h>
1010
#include <linux/pci.h>
1111
#include <linux/acpi.h>
12+
#include <linux/sizes.h>
1213

1314
#include <asm/acpi.h>
1415
#include <asm/bios_ebda.h>
@@ -69,6 +70,8 @@ struct x86_init_ops x86_init __initdata = {
6970
.reserve_resources = reserve_standard_io_resources,
7071
.memory_setup = e820__memory_setup_default,
7172
.dmi_setup = dmi_setup,
73+
/* Has to be under 1M so we can execute real-mode AP code. */
74+
.realmode_limit = SZ_1M,
7275
},
7376

7477
.mpparse = {

arch/x86/realmode/init.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,17 @@ void load_trampoline_pgtable(void)
4545

4646
void __init reserve_real_mode(void)
4747
{
48-
phys_addr_t mem;
48+
phys_addr_t mem, limit = x86_init.resources.realmode_limit;
4949
size_t size = real_mode_size_needed();
5050

5151
if (!size)
5252
return;
5353

5454
WARN_ON(slab_is_available());
5555

56-
/* Has to be under 1M so we can execute real-mode AP code. */
57-
mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, 1<<20);
56+
mem = memblock_phys_alloc_range(size, PAGE_SIZE, 0, limit);
5857
if (!mem)
59-
pr_info("No sub-1M memory is available for the trampoline\n");
58+
pr_info("No memory below %pa for the real-mode trampoline\n", &limit);
6059
else
6160
set_real_mode_mem(mem);
6261

0 commit comments

Comments
 (0)