From: "Rafael J. Wysocki" <rjw-KKrjLPT3xs0@public.gmane.org>
To: kernel-testers-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: ACPI Devel Maling List
<linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
Andi Kleen <andi-Vw/NltI1exuRpAAqCnN02g@public.gmane.org>,
LKML <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>,
pm list
<linux-pm-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org>,
"H. Peter Anvin" <hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>,
Pavel Machek <pavel-+ZI9xUNit7I@public.gmane.org>
Subject: [RFT] x86 acpi: normalize segment descriptor register on resume
Date: Tue, 1 Jul 2008 01:48:01 +0200 [thread overview]
Message-ID: <200807010148.02135.rjw@sisk.pl> (raw)
Hi,
The appended patch fixes a regression and is considered as 2.6.26 material.
Everyone having a box with working suspend to RAM is gently requested to test
it and verify if it doesn't break things.
The patch applies to the current -git.
Thanks,
Rafael
---
From: H. Peter Anvin <hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
x86 acpi: normalize segment descriptor register on resume
Some Dell laptops enter resume with apparent garbage in the segment
descriptor registers (almost certainly the result of a botched
transition from protected to real mode.) The only way to clean that
up is to enter protected mode ourselves and clean out the descriptor
registers.
This fixes resume on Dell XPS M1210 and Dell D620.
Reference: http://bugzilla.kernel.org/show_bug.cgi?id=10927
Signed-off-by: H. Peter Anvin <hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
Tested-by: Kirill A. Shutemov <kirill-oKw7cIdHH8eLwutG50LtGA@public.gmane.org>
Signed-off-by: Rafael J. Wysocki <rjw-KKrjLPT3xs0@public.gmane.org>
---
arch/x86/kernel/acpi/realmode/wakeup.S | 38 ++++++++++++++++++++++++++++++++-
arch/x86/kernel/acpi/realmode/wakeup.h | 5 ++++
arch/x86/kernel/acpi/sleep.c | 16 +++++++++++++
drivers/acpi/sleep/main.c | 5 +---
4 files changed, 59 insertions(+), 5 deletions(-)
Index: linux-2.6/arch/x86/kernel/acpi/realmode/wakeup.S
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/realmode/wakeup.S
+++ linux-2.6/arch/x86/kernel/acpi/realmode/wakeup.S
@@ -5,6 +5,7 @@
#include <asm/msr-index.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <asm/processor-flags.h>
.code16
.section ".header", "a"
@@ -24,6 +25,11 @@ pmode_gdt: .quad 0
realmode_flags: .long 0
real_magic: .long 0
trampoline_segment: .word 0
+_pad1: .byte 0
+wakeup_jmp: .byte 0xea /* ljmpw */
+wakeup_jmp_off: .word 3f
+wakeup_jmp_seg: .word 0
+wakeup_gdt: .quad 0, 0, 0
signature: .long 0x51ee1111
.text
@@ -34,11 +40,34 @@ _start:
cli
cld
+ /* Apparently some dimwit BIOS programmers don't know how to
+ program a PM to RM transition, and we might end up here with
+ junk in the data segment descriptor registers. The only way
+ to repair that is to go into PM and fix it ourselves... */
+ movw $16, %cx
+ lgdtl %cs:wakeup_gdt
+ movl %cr0, %eax
+ orb $X86_CR0_PE, %al
+ movl %eax, %cr0
+ jmp 1f
+1: ljmpw $8, $2f
+2:
+ movw %cx, %ds
+ movw %cx, %es
+ movw %cx, %ss
+ movw %cx, %fs
+ movw %cx, %gs
+
+ andb $~X86_CR0_PE, %al
+ movl %eax, %cr0
+ jmp wakeup_jmp
+3:
/* Set up segments */
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
+ lidtl wakeup_idt
movl $wakeup_stack_end, %esp
@@ -98,7 +127,14 @@ bogus_real_magic:
jmp 1b
.data
- .balign 4
+ .balign 8
+
+ /* This is the standard real-mode IDT */
+wakeup_idt:
+ .word 0xffff /* limit */
+ .long 0 /* address */
+ .word 0
+
.globl HEAP, heap_end
HEAP:
.long wakeup_heap
Index: linux-2.6/arch/x86/kernel/acpi/realmode/wakeup.h
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/realmode/wakeup.h
+++ linux-2.6/arch/x86/kernel/acpi/realmode/wakeup.h
@@ -24,6 +24,11 @@ struct wakeup_header {
u32 realmode_flags;
u32 real_magic;
u16 trampoline_segment; /* segment with trampoline code, 64-bit only */
+ u8 _pad1;
+ u8 wakeup_jmp;
+ u16 wakeup_jmp_off;
+ u16 wakeup_jmp_seg;
+ u64 wakeup_gdt[3];
u32 signature; /* To check we have correct structure */
} __attribute__((__packed__));
Index: linux-2.6/arch/x86/kernel/acpi/sleep.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/acpi/sleep.c
+++ linux-2.6/arch/x86/kernel/acpi/sleep.c
@@ -50,6 +50,20 @@ int acpi_save_state_mem(void)
header->video_mode = saved_video_mode;
+ header->wakeup_jmp_seg = acpi_wakeup_address >> 4;
+ /* GDT[0]: GDT self-pointer */
+ header->wakeup_gdt[0] =
+ (u64)(sizeof(header->wakeup_gdt) - 1) +
+ ((u64)(acpi_wakeup_address +
+ ((char *)&header->wakeup_gdt - (char *)acpi_realmode))
+ << 16);
+ /* GDT[1]: real-mode-like code segment */
+ header->wakeup_gdt[1] = (0x009bULL << 40) +
+ ((u64)acpi_wakeup_address << 16) + 0xffff;
+ /* GDT[2]: real-mode-like data segment */
+ header->wakeup_gdt[2] = (0x0093ULL << 40) +
+ ((u64)acpi_wakeup_address << 16) + 0xffff;
+
#ifndef CONFIG_64BIT
store_gdt((struct desc_ptr *)&header->pmode_gdt);
@@ -111,7 +125,7 @@ void __init acpi_reserve_bootmem(void)
return;
}
- acpi_wakeup_address = acpi_realmode;
+ acpi_wakeup_address = virt_to_phys((void *)acpi_realmode);
}
Index: linux-2.6/drivers/acpi/sleep/main.c
===================================================================
--- linux-2.6.orig/drivers/acpi/sleep/main.c
+++ linux-2.6/drivers/acpi/sleep/main.c
@@ -32,9 +32,8 @@ static int acpi_sleep_prepare(u32 acpi_s
if (!acpi_wakeup_address) {
return -EFAULT;
}
- acpi_set_firmware_waking_vector((acpi_physical_address)
- virt_to_phys((void *)
- acpi_wakeup_address));
+ acpi_set_firmware_waking_vector(
+ (acpi_physical_address)acpi_wakeup_address);
}
ACPI_FLUSH_CPU_CACHE();
next reply other threads:[~2008-06-30 23:48 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-30 23:48 Rafael J. Wysocki [this message]
[not found] ` <200807010148.02135.rjw-KKrjLPT3xs0@public.gmane.org>
2008-07-01 0:05 ` [RFT] x86 acpi: normalize segment descriptor register on resume H. Peter Anvin
2008-07-01 6:31 ` Ingo Molnar
[not found] ` <20080701063133.GC16642-X9Un+BFzKDI@public.gmane.org>
2008-07-01 6:54 ` H. Peter Anvin
2008-07-01 9:19 ` Pavel Machek
2008-07-01 20:39 ` Rafael J. Wysocki
2008-07-01 20:42 ` Andi Kleen
2008-07-01 20:50 ` Rafael J. Wysocki
2008-07-01 20:52 ` Andi Kleen
[not found] ` <486A96C1.2020106-Vw/NltI1exuRpAAqCnN02g@public.gmane.org>
2008-07-12 6:29 ` Andy Lutomirski
2008-07-12 12:08 ` Andi Kleen
[not found] ` <48789EC3.2070701-Vw/NltI1exuRpAAqCnN02g@public.gmane.org>
2008-07-12 15:08 ` Andy Lutomirski
[not found] ` <48784F51.1010407-YSGFQ8SKJZVDPfheJLI6IQ@public.gmane.org>
2008-07-12 18:51 ` Rafael J. Wysocki
[not found] ` <200807122051.25634.rjw-KKrjLPT3xs0@public.gmane.org>
2008-07-12 20:39 ` Andy Lutomirski
[not found] ` <48791484.4010408@myrealbox.com>
[not found] ` <48791484.4010408-YSGFQ8SKJZVDPfheJLI6IQ@public.gmane.org>
2008-07-12 20:47 ` Rafael J. Wysocki
[not found] ` <48791675.6060805@myrealbox.com>
[not found] ` <48791675.6060805-YSGFQ8SKJZVDPfheJLI6IQ@public.gmane.org>
2008-07-12 20:53 ` Rafael J. Wysocki
2008-07-01 7:02 ` H. Peter Anvin
2008-07-01 13:01 ` Andi Kleen
2008-07-01 15:55 ` H. Peter Anvin
[not found] ` <486A5378.7020601-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org>
2008-07-01 16:21 ` Andi Kleen
2008-07-01 17:28 ` H. Peter Anvin
2008-07-01 7:20 ` Ingo Molnar
[not found] ` <20080701072024.GB26601-X9Un+BFzKDI@public.gmane.org>
2008-07-01 7:28 ` Andrew Morton
2008-07-01 7:45 ` Ingo Molnar
-- strict thread matches above, loose matches on Subject: below --
2008-07-12 23:07 H. Peter Anvin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200807010148.02135.rjw@sisk.pl \
--to=rjw-kkrjlpt3xs0@public.gmane.org \
--cc=andi-Vw/NltI1exuRpAAqCnN02g@public.gmane.org \
--cc=hpa-YMNOUZJC4hwAvxtiuMwx3w@public.gmane.org \
--cc=kernel-testers-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-pm-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=pavel-+ZI9xUNit7I@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).