From c133cc38e21d21f36ae62685e7e64d3e07542814 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 16 Jun 2009 14:19:34 +0100 Subject: [PATCH] x86: fix s3 resume on AMD CPUs Avoid longjmp as it has different semantics than on Intel CPUs in long mode. Also add a few comments and remove a pointless reload of DS. Signed-off-by: Christoph Egger Signed-off-by: Keir Fraser --- xen/arch/x86/acpi/wakeup_prot.S | 6 ++++++ xen/arch/x86/boot/wakeup.S | 21 +++++++-------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/acpi/wakeup_prot.S b/xen/arch/x86/acpi/wakeup_prot.S index 8a91488b32..cf876ed147 100644 --- a/xen/arch/x86/acpi/wakeup_prot.S +++ b/xen/arch/x86/acpi/wakeup_prot.S @@ -142,6 +142,12 @@ __ret_point: LOAD_GREG(sp) #if defined(__x86_64__) + /* Reload code selector */ + pushq $(__HYPERVISOR_CS64) + leaq 1f(%rip),%rax + pushq %rax + lretq +1: mov REF(saved_cr8), %rax mov %rax, %cr8 diff --git a/xen/arch/x86/boot/wakeup.S b/xen/arch/x86/boot/wakeup.S index cf40d8bfaa..db367995ab 100644 --- a/xen/arch/x86/boot/wakeup.S +++ b/xen/arch/x86/boot/wakeup.S @@ -110,6 +110,7 @@ video_flags: .long 0 # Add offset for any reference to xen specific symbols wakeup_32: + /* Set up segment registers and initial stack for protected mode */ mov $BOOT_DS, %eax mov %eax, %ds mov %eax, %ss @@ -152,6 +153,7 @@ wakeup_32: wbinvd + /* Enable paging and flush prefetch queue */ mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */ mov %eax,%cr0 jmp 1f @@ -163,31 +165,22 @@ wakeup_32: ljmp $BOOT_CS64, $bootsym_phys(wakeup_64) .code64 - .align 8 - .word 0,0,0 -lgdt_descr: - .word LAST_RESERVED_GDT_BYTE - .quad boot_cpu_gdt_table - FIRST_RESERVED_GDT_BYTE - wakeup_64: - lgdt lgdt_descr(%rip) - mov $(__HYPERVISOR_DS64), %eax - mov %eax, %ds - - # long jump to return point, with cs reload - rex64 ljmp *ret_point(%rip) + /* Jump to high mappings and the higher-level wakeup code. */ + movq ret_point(%rip), %rbx + jmp *%rbx - .align 8 ret_point: .quad __ret_point - .word __HYPERVISOR_CS64 #else /* !defined(__x86_64__) */ + lgdt gdt_descr mov $(__HYPERVISOR_DS), %eax mov %eax, %ds ljmp $(__HYPERVISOR_CS), $__ret_point + #endif bogus_saved_magic: -- 2.39.5