* Query regarding x86_64 purgatory and IA32-e compatibility mode
@ 2012-10-25 20:54 Vivek Goyal
2012-10-26 3:14 ` Eric W. Biederman
0 siblings, 1 reply; 3+ messages in thread
From: Vivek Goyal @ 2012-10-25 20:54 UTC (permalink / raw)
To: Eric W. Biederman, Kexec Mailing List
Hi Eric,
I am reading up x86_64 purgatory code to understand how transition to
32bit protected mode happens.
My understanding is that we enter in purgatory_start (setup-x86_64.S).
Then we jump to entry64 in entry64.S.
We run following code in arch/x86_64/entry64.S
movq $stack_init, %rsp
pushq $0x10 /* CS */
pushq $new_cs_exit
lretq
new_cs_exit:
/* Load the registers */
movq rax(%rip), %rax
movq rbx(%rip), %rbx
movq rcx(%rip), %rcx
movq rdx(%rip), %rdx
movq rsi(%rip), %rsi
movq rdi(%rip), %rdi
movq rsp(%rip), %rsp
movq rbp(%rip), %rbp
movq r8(%rip), %r8
movq r9(%rip), %r9
movq r10(%rip), %r10
movq r11(%rip), %r11
movq r12(%rip), %r12
movq r13(%rip), %r13
movq r14(%rip), %r14
movq r15(%rip), %r15
Will above lretq call not switch us in compatibility mode (from 64bit
mode)? We have taken a long jump and our new CS seems to have L bit
0.
Following is our gdt.
gdt: /* 0x00 unusable segment
* 0x08 unused
* so use them as the gdt ptr
*/
.word gdt_end - gdt - 1
.quad gdt
.word 0, 0, 0
/* 0x10 4GB flat code segment */
.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
/* 0x18 4GB flat data segment */
.word 0xFFFF, 0x0000, 0x9200, 0x00CF
gdt_end:
I see that bit 21 in second doubleword is 0. IIUC, that means that we
will switch to compatibility mode. If yes, we are still continuing to
use 64bit instructions and continue to access registers (rip, r8-15)
which are available in 64bit mode only. Is this correct? How does this
work?
Thanks
Vivek
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: Query regarding x86_64 purgatory and IA32-e compatibility mode
2012-10-25 20:54 Query regarding x86_64 purgatory and IA32-e compatibility mode Vivek Goyal
@ 2012-10-26 3:14 ` Eric W. Biederman
2012-10-26 13:19 ` Vivek Goyal
0 siblings, 1 reply; 3+ messages in thread
From: Eric W. Biederman @ 2012-10-26 3:14 UTC (permalink / raw)
To: Vivek Goyal; +Cc: Kexec Mailing List
Vivek Goyal <vgoyal@redhat.com> writes:
> Hi Eric,
>
> I am reading up x86_64 purgatory code to understand how transition to
> 32bit protected mode happens.
>
> My understanding is that we enter in purgatory_start (setup-x86_64.S).
> Then we jump to entry64 in entry64.S.
>
> We run following code in arch/x86_64/entry64.S
>
> movq $stack_init, %rsp
> pushq $0x10 /* CS */
> pushq $new_cs_exit
> lretq
> new_cs_exit:
>
> /* Load the registers */
> movq rax(%rip), %rax
> movq rbx(%rip), %rbx
> movq rcx(%rip), %rcx
> movq rdx(%rip), %rdx
> movq rsi(%rip), %rsi
> movq rdi(%rip), %rdi
> movq rsp(%rip), %rsp
> movq rbp(%rip), %rbp
> movq r8(%rip), %r8
> movq r9(%rip), %r9
> movq r10(%rip), %r10
> movq r11(%rip), %r11
> movq r12(%rip), %r12
> movq r13(%rip), %r13
> movq r14(%rip), %r14
> movq r15(%rip), %r15
>
> Will above lretq call not switch us in compatibility mode (from 64bit
> mode)? We have taken a long jump and our new CS seems to have L bit
> 0.
> Following is our gdt.
>
> gdt: /* 0x00 unusable segment
> * 0x08 unused
> * so use them as the gdt ptr
> */
> .word gdt_end - gdt - 1
> .quad gdt
> .word 0, 0, 0
>
> /* 0x10 4GB flat code segment */
> .word 0xFFFF, 0x0000, 0x9A00, 0x00AF
>
> /* 0x18 4GB flat data segment */
> .word 0xFFFF, 0x0000, 0x9200, 0x00CF
> gdt_end:
>
> I see that bit 21 in second doubleword is 0. IIUC, that means that we
> will switch to compatibility mode. If yes, we are still continuing to
> use 64bit instructions and continue to access registers (rip, r8-15)
> which are available in 64bit mode only. Is this correct? How does this
> work?
/* 0x10 4GB flat code segment */
.word 0xFFFF, 0x0000, 0x9A00, 0x00AF
The high 16bits of that are:
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1
Since L is bit 21 I read that as L=1.
I don't know how you see L=1 there.
The transition happens in entry64-32.S
We get there via:
jmp *rip(%rip)
The default value of rip is entry32.
That is where we clear bit 21 in
ljmp *lm_exit_addr(%rip)
Eric
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: Query regarding x86_64 purgatory and IA32-e compatibility mode
2012-10-26 3:14 ` Eric W. Biederman
@ 2012-10-26 13:19 ` Vivek Goyal
0 siblings, 0 replies; 3+ messages in thread
From: Vivek Goyal @ 2012-10-26 13:19 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: Kexec Mailing List
On Thu, Oct 25, 2012 at 08:14:58PM -0700, Eric W. Biederman wrote:
[..]
> > I see that bit 21 in second doubleword is 0. IIUC, that means that we
> > will switch to compatibility mode. If yes, we are still continuing to
> > use 64bit instructions and continue to access registers (rip, r8-15)
> > which are available in 64bit mode only. Is this correct? How does this
> > work?
>
> /* 0x10 4GB flat code segment */
> .word 0xFFFF, 0x0000, 0x9A00, 0x00AF
>
> The high 16bits of that are:
> 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
> 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1
>
> Since L is bit 21 I read that as L=1.
>
> I don't know how you see L=1 there.
My bad. I did not take care of little endianness and read the bits in
reverse order.
0x00AF
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1
And concluded that bit 21 is 0.
>
> The transition happens in entry64-32.S
> We get there via:
> jmp *rip(%rip)
>
> The default value of rip is entry32.
>
> That is where we clear bit 21 in
> ljmp *lm_exit_addr(%rip)
Ok, now I understand. In entry64-32.S we load a different GDT
where bit 21, L = 0. Hence long jump will put it in compatibility
mode.
0x00CF
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16
0 0 0 0 0 0 0 0 1 1 0 0 1 1 1 1
Thanks for explaining this.
Thanks
Vivek
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-10-26 13:19 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-25 20:54 Query regarding x86_64 purgatory and IA32-e compatibility mode Vivek Goyal
2012-10-26 3:14 ` Eric W. Biederman
2012-10-26 13:19 ` Vivek Goyal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox