diff mbox

[edk2] apparent KVM problem with LRET in TianoCore S3 resume trampoline

Message ID 52A1006D.2070304@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Laszlo Ersek Dec. 5, 2013, 10:38 p.m. UTC
On 12/05/13 18:42, Paolo Bonzini wrote:

> diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
> index e59fd04..d1cac9d 100644
> --- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
> +++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
> @@ -19,7 +19,7 @@ ASM_PFX(AsmTransferControl):
>      # rcx S3WakingVector    :DWORD
>      # rdx AcpiLowMemoryBase :DWORD
>      lea   _AsmTransferControl_al_0000(%rip), %eax 
> -    movq  $0x2800000000, %r8 
> +    movq  $0x1000000000, %r8 
>      orq   %r8, %rax
>      pushq %rax
>      shrd  $20, %ecx, %ebx
> @@ -28,24 +28,32 @@ ASM_PFX(AsmTransferControl):
>      movl  %ebx, jmp_addr(%rip) 
>      lret
>  _AsmTransferControl_al_0000:
> +    # Old SS should still be okay?
> +    addl  _AsmTransferControl_al_0001-_AsmTransferControl_al_0000, %eax
> +    pushl $0x28
> +    pushl %eax
> +    movq  %cr0, %rax
> +    movq  %cr4, %rbx
> +    andl  $0x7fffffff, %eax
> +    andb  $0xdf, %bl
> +    movq  %rax, %cr0             # sets EFER.LMA=0 too, so says Intel
> +    movl  $0x0c0000080, %ecx
> +    rdmsr
> +    andb  $0xfe, %ah             # set EFER.LME=0
> +    wrmsr
> +    movq  %rbx, %cr4             # only now set CR4.PAE=0
> +    lret
> +_AsmTransferControl_al_0001:
>      .byte    0x0b8, 0x30, 0      # mov ax, 30h as selector
>      movl  %eax, %ds
>      movl  %eax, %es
>      movl  %eax, %fs
>      movl  %eax, %gs
>      movl  %eax, %ss
> -    movq  %cr0, %rax
> -    movq  %cr4, %rbx
> -    .byte    0x66
> -    andl  $0x7ffffffe, %eax 
> -    andb  $0xdf, %bl 
> -    movq  %rax, %cr0
> -    .byte    0x66
> -    movl  $0x0c0000080, %ecx 
> -    rdmsr
> -    andb  $0xfe, %ah 
> -    wrmsr
> -    movq  %rbx, %cr4
> +    movl  %cr0, %rax        # Get control register 0
> +    .byte 0x66
> +    .byte 0x83,0xe0,0xfe    # and    eax, 0fffffffeh  ; Clear PE bit (bit #0)
> +    .byte 0xf,0x22,0xc0     # mov    cr0, eax         ; Activate real mode

I had to add this incremental patch to get it to compile:


The 2nd lret is reached (just before _AsmTransferControl_al_0001), but then the CPU goes off in the woods. For a while it seems to be spinning who knows where, and in 15-20 seconds or so the guest reboots.

Does gas support mode switches in one file? I found examples on the net (for nasm I think) where people were thunking to real mode and back to protected mode in a single assembly file, and they could use native mnemonics for each part. (They just switched the assembler's mode in sync with execution modes.)

Thanks
Laszlo

Thanks,
Laszlo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

David Woodhouse Dec. 7, 2013, 4:25 p.m. UTC | #1
On Thu, 2013-12-05 at 23:38 +0100, Laszlo Ersek wrote:
> 
> Does gas support mode switches in one file? I found examples on the
> net (for nasm I think) where people were thunking to real mode and
> back to protected mode in a single assembly file, and they could use
> native mnemonics for each part. (They just switched the assembler's
> mode in sync with execution modes.)

$DEITY yes. See the patch I posted to fix Thunk16.S last week, which
does exactly that. Without that, it's basically unmaintainable.

As Andrew points out, LLVM doesn't support .code16. There's a bug filed.

But frankly, I don't think we should care. Let them fix it. There *is*
active development on LLVM and it *can* be fixed, relatively easily.
It's not like we're talking about requiring fixes to the effectively
unmaintained Microsoft toolchain — which we can't even describe as
"stuck in the 20th century" since it doesn't even support the last C
standard from *that* century either :)
diff mbox

Patch

diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
index c28df3f..85d2a36 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
@@ -30,8 +30,8 @@  ASM_PFX(AsmTransferControl):
 _AsmTransferControl_al_0000:
     # Old SS should still be okay?
     addl  _AsmTransferControl_al_0001-_AsmTransferControl_al_0000, %eax
-    pushl $0x28
-    pushl %eax
+    .byte 0x6a,0x28              # pushl $0x28 ; opnd sz = 32bits in seg 0x10
+    .byte 0x50                   # pushl %eax
     movq  %cr0, %rax
     movq  %cr4, %rbx
     andl  $0x7fffffff, %eax
@@ -50,7 +50,7 @@  _AsmTransferControl_al_0001:
     movl  %eax, %fs
     movl  %eax, %gs
     movl  %eax, %ss
-    movl  %cr0, %rax        # Get control register 0
+    .byte 0x0f,0x20,0xc0    # movl  %cr0, %eax        ; Get control register 0
     .byte 0x66
     .byte 0x83,0xe0,0xfe    # and    eax, 0fffffffeh  ; Clear PE bit (bit #0)
     .byte 0xf,0x22,0xc0     # mov    cr0, eax         ; Activate real mode