Merge branch 'for-linus' of git://git.o-hand.com/linux-rpurdie-backlight
[linux-2.6] / drivers / lguest / lguest_asm.S
1 #include <linux/linkage.h>
2 #include <linux/lguest.h>
3 #include <asm/asm-offsets.h>
4 #include <asm/thread_info.h>
5 #include <asm/processor-flags.h>
6
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,
11  * but for the moment this suffices.  We pass the virtual address of the boot
12  * info to lguest_init().
13  *
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
20         movl %esi, %eax
21         addl $__PAGE_OFFSET, %eax
22         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
29 LGUEST_PATCH(cli, movl $0, lguest_data+LGUEST_DATA_irq_enabled)
30 LGUEST_PATCH(sti, movl $X86_EFLAGS_IF, lguest_data+LGUEST_DATA_irq_enabled)
31 LGUEST_PATCH(popf, movl %eax, lguest_data+LGUEST_DATA_irq_enabled)
32 LGUEST_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  */
47 ENTRY(lguest_iret)
48         pushl   %eax
49         movl    12(%esp), %eax
50 lguest_noirq_start:
51         movl    %eax,%ss:lguest_data+LGUEST_DATA_irq_enabled
52         popl    %eax
53         iret
54 lguest_noirq_end: