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