Skip to content

Commit

Permalink
real_mode: Fix long to protected mode transition
Browse files Browse the repository at this point in the history
Going into real mode would crash when clearing EFER_LME, i.e., when
transitioning from long to protected mode. This happened because paging
was still enabled. Before disabling paging, we must also set the %ds.

Signed-off-by: Johannes Wikner <[email protected]>
  • Loading branch information
sktt authored and wipawel committed Aug 29, 2023
1 parent a5164e3 commit 06a81f4
Showing 1 changed file with 12 additions and 10 deletions.
22 changes: 12 additions & 10 deletions arch/x86/real_mode.S
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,18 @@ END_FUNC(_prot_to_real)

.align 16
.Lfrom_long_mode:
/* Disable LME in EFER */
/* Use protected mode data segment */
mov $__KERN_DS32, %eax
mov %eax, %ds
mov %eax, %ss

/* Disable paging to enter protected mode. */
/* Clearing PG implicitly clears EFER.LMA, see Intel SDM 9.8.5.4, */
mov %cr0, %eax
and $~(X86_CR0_PG | X86_CR0_WP), %eax
mov %eax, %cr0

/* Disable LME in EFER. */
movl $MSR_EFER, %ecx
rdmsr
and $~EFER_LME, %eax
Expand All @@ -151,15 +162,6 @@ END_FUNC(_prot_to_real)
lgdt rmode_gdt_ptr
lidt rmode_idt_ptr

/* Disable paging to enter protected mode */
mov %cr0, %eax
and $~(X86_CR0_PG | X86_CR0_WP), %eax
mov %eax, %cr0

/* Use protected mode data selector */
mov $__KERN_DS32, %eax
mov %eax, %ds

/* Use real mode accessible stack */
mov rmode_stack, %esp

Expand Down

0 comments on commit 06a81f4

Please sign in to comment.