blob: a3dbf22ee365a86d11b85792e1163f8256e9cdda [file] [log] [blame]
Rusty Russell07ad1572007-07-19 01:49:22 -07001#include <linux/linkage.h>
2#include <linux/lguest.h>
3#include <asm/asm-offsets.h>
4#include <asm/thread_info.h>
Rusty Russell876be9d2007-07-20 22:12:56 +10005#include <asm/processor-flags.h>
Rusty Russell07ad1572007-07-19 01:49:22 -07006
7/*
8 * This is where we begin: we have a magic signature which the launcher looks
9 * for. The plan is that the Linux boot protocol will be extended with a
10 * "platform type" field which will guide us here from the normal entry point,
Rusty Russelld7e28ff2007-07-19 01:49:23 -070011 * but for the moment this suffices. We pass the virtual address of the boot
12 * info to lguest_init().
Rusty Russell07ad1572007-07-19 01:49:22 -070013 *
14 * We put it in .init.text will be discarded after boot.
15 */
16.section .init.text, "ax", @progbits
17.ascii "GenuineLguest"
18 /* Set up initial stack. */
19 movl $(init_thread_union+THREAD_SIZE),%esp
Rusty Russelld7e28ff2007-07-19 01:49:23 -070020 movl %esi, %eax
21 addl $__PAGE_OFFSET, %eax
Rusty Russell07ad1572007-07-19 01:49:22 -070022 jmp lguest_init
23
24/* The templates for inline patching. */
25#define LGUEST_PATCH(name, insns...) \
26 lgstart_##name: insns; lgend_##name:; \
27 .globl lgstart_##name; .globl lgend_##name
28
29LGUEST_PATCH(cli, movl $0, lguest_data+LGUEST_DATA_irq_enabled)
30LGUEST_PATCH(sti, movl $X86_EFLAGS_IF, lguest_data+LGUEST_DATA_irq_enabled)
31LGUEST_PATCH(popf, movl %eax, lguest_data+LGUEST_DATA_irq_enabled)
32LGUEST_PATCH(pushf, movl lguest_data+LGUEST_DATA_irq_enabled, %eax)
33
34.text
35/* These demark the EIP range where host should never deliver interrupts. */
36.global lguest_noirq_start
37.global lguest_noirq_end
38
39/*
40 * We move eflags word to lguest_data.irq_enabled to restore interrupt state.
41 * For page faults, gpfs and virtual interrupts, the hypervisor has saved
42 * eflags manually, otherwise it was delivered directly and so eflags reflects
43 * the real machine IF state, ie. interrupts on. Since the kernel always dies
44 * if it takes such a trap with interrupts disabled anyway, turning interrupts
45 * back on unconditionally here is OK.
46 */
47ENTRY(lguest_iret)
48 pushl %eax
49 movl 12(%esp), %eax
50lguest_noirq_start:
51 movl %eax,%ss:lguest_data+LGUEST_DATA_irq_enabled
52 popl %eax
53 iret
54lguest_noirq_end: