Merge branch 'packaging' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek...
[linux-block.git] / arch / x86 / kernel / trampoline.c
CommitLineData
77ad386e 1#include <linux/io.h>
a9ce6bc1 2#include <linux/memblock.h>
77ad386e
IM
3
4#include <asm/trampoline.h>
4822b7fc 5#include <asm/cacheflush.h>
fd89a137 6#include <asm/pgtable.h>
77ad386e 7
4822b7fc 8unsigned char *x86_trampoline_base;
7a4b7e5e 9
4822b7fc 10void __init setup_trampolines(void)
3e1e9002 11{
a9ce6bc1 12 phys_addr_t mem;
4822b7fc 13 size_t size = PAGE_ALIGN(x86_trampoline_end - x86_trampoline_start);
893f38d1 14
3e1e9002 15 /* Has to be in very low memory so we can execute real-mode AP code. */
4822b7fc 16 mem = memblock_find_in_range(0, 1<<20, size, PAGE_SIZE);
a9ce6bc1 17 if (mem == MEMBLOCK_ERROR)
893f38d1
YL
18 panic("Cannot allocate trampoline\n");
19
4822b7fc
PA
20 x86_trampoline_base = __va(mem);
21 memblock_x86_reserve_range(mem, mem + size, "TRAMPOLINE");
22
23 printk(KERN_DEBUG "Base memory trampoline at [%p] %llx size %zu\n",
24 x86_trampoline_base, (unsigned long long)mem, size);
25
26 memcpy(x86_trampoline_base, x86_trampoline_start, size);
3e1e9002
RW
27}
28
77ad386e 29/*
4822b7fc
PA
30 * setup_trampolines() gets called very early, to guarantee the
31 * availability of low memory. This is before the proper kernel page
32 * tables are set up, so we cannot set page permissions in that
33 * function. Thus, we use an arch_initcall instead.
77ad386e 34 */
4822b7fc 35static int __init configure_trampolines(void)
77ad386e 36{
4822b7fc
PA
37 size_t size = PAGE_ALIGN(x86_trampoline_end - x86_trampoline_start);
38
39 set_memory_x((unsigned long)x86_trampoline_base, size >> PAGE_SHIFT);
40 return 0;
77ad386e 41}
4822b7fc 42arch_initcall(configure_trampolines);