diff options
Diffstat (limited to 'arch/i386/kernel/head.S')
-rw-r--r-- | arch/i386/kernel/head.S | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index 5b14e95ac8b9..edef5084ce17 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S | |||
@@ -55,6 +55,12 @@ | |||
55 | */ | 55 | */ |
56 | ENTRY(startup_32) | 56 | ENTRY(startup_32) |
57 | 57 | ||
58 | #ifdef CONFIG_PARAVIRT | ||
59 | movl %cs, %eax | ||
60 | testl $0x3, %eax | ||
61 | jnz startup_paravirt | ||
62 | #endif | ||
63 | |||
58 | /* | 64 | /* |
59 | * Set segments to known values. | 65 | * Set segments to known values. |
60 | */ | 66 | */ |
@@ -486,6 +492,33 @@ ignore_int: | |||
486 | #endif | 492 | #endif |
487 | iret | 493 | iret |
488 | 494 | ||
495 | #ifdef CONFIG_PARAVIRT | ||
496 | startup_paravirt: | ||
497 | cld | ||
498 | movl $(init_thread_union+THREAD_SIZE),%esp | ||
499 | |||
500 | /* We take pains to preserve all the regs. */ | ||
501 | pushl %edx | ||
502 | pushl %ecx | ||
503 | pushl %eax | ||
504 | |||
505 | /* paravirt.o is last in link, and that probe fn never returns */ | ||
506 | pushl $__start_paravirtprobe | ||
507 | 1: | ||
508 | movl 0(%esp), %eax | ||
509 | pushl (%eax) | ||
510 | movl 8(%esp), %eax | ||
511 | call *(%esp) | ||
512 | popl %eax | ||
513 | |||
514 | movl 4(%esp), %eax | ||
515 | movl 8(%esp), %ecx | ||
516 | movl 12(%esp), %edx | ||
517 | |||
518 | addl $4, (%esp) | ||
519 | jmp 1b | ||
520 | #endif | ||
521 | |||
489 | /* | 522 | /* |
490 | * Real beginning of normal "text" segment | 523 | * Real beginning of normal "text" segment |
491 | */ | 524 | */ |