linux-acpi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFT] x86 acpi: normalize segment descriptor register on resume
@ 2008-06-30 23:48 Rafael J. Wysocki
       [not found] ` <200807010148.02135.rjw-KKrjLPT3xs0@public.gmane.org>
  2008-07-01  7:20 ` Ingo Molnar
  0 siblings, 2 replies; 54+ messages in thread
From: Rafael J. Wysocki @ 2008-06-30 23:48 UTC (permalink / raw)
  To: kernel-testers-u79uwXL29TY76Z2rM5mHXA
  Cc: ACPI Devel Maling List, Andi Kleen, LKML, pm list, H. Peter Anvin,
	Pavel Machek

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();

^ permalink raw reply	[flat|nested] 54+ messages in thread
* Re: [RFT] x86 acpi: normalize segment descriptor register on resume
@ 2008-07-12 23:07 H. Peter Anvin
  0 siblings, 0 replies; 54+ messages in thread
From: H. Peter Anvin @ 2008-07-12 23:07 UTC (permalink / raw)
  To: Rafael J. Wysocki, Andy Lutomirski
  Cc: LKML, ACPI Devel Maling List, Andi Kleen,
	public-kernel-testers-u79uwXL29TY76Z2rM5mHXA, Ingo Molnar,
	pm list

It seems like a reasonable guess at least.  I won't have a chance to dig into the details until late this evening or tomorrow, depending on when I get home tonight.

-- 
Sent from my mobile phone (pardon any lack of formatting)


-----Original Message-----
From: Rafael J. Wysocki <rjw@sisk.pl>
Sent: Saturday, July 12, 2008 13:53
To: Andy Lutomirski <luto@myrealbox.com>; H. Peter Anvin <hpa@zytor.com>
Cc: Andi Kleen <andi@firstfloor.org>; Ingo Molnar <mingo@elte.hu>; kernel-testers-u79uwXL29TY76Z2rM5mHXA@public.gmane.org; ACPI Devel Maling List <linux-acpi@vger.kernel.org>; LKML <linux-kernel@vger.kernel.org>; pm list <linux-pm@lists.linux-foundation.org>; Pavel Machek <pavel@ucw.cz>
Subject: Re: [RFT] x86 acpi: normalize segment descriptor register on resume

On Saturday, 12 of July 2008, Andy Lutomirski wrote:
> Rafael J. Wysocki wrote:
> > On Saturday, 12 of July 2008, Andy Lutomirski wrote:
> >> My Lenovo X61s fails to resume if I suspend it from within X, on both 
> >> 2.6.26-rc9 and recent wireless-testing.  2.6.26-rc8 is fine, as is 
> >> wireless-testing with 4b4f7280 reverted.  My in-progress bisect between 
> >> -rc8 and -rc9 is also consistent with this being the problem.
> >>
> >> The symptom is that, when I push the power button to resume, the hard 
> >> drive light turns on, the fan turns on, then the hard drive light turns 
> >> off, the sleep light stays on, and the fan keeps running.  Sometimes the 
> >> battery light will blink off very briefly (1/4 sec, maybe) every few 
> >> seconds.  The system is locked hard at this point.
> >>
> >> I'm using Ubuntu Hardy userspace.
> > 
> > Well, that's bad.
> > 
> > There is the bugzilla entry at http://bugzilla.kernel.org/show_bug.cgi?id=11064
> > for this bug and you've just confirmed my suspicion that this particular
> > commit is to blame.
> > 
> > Can you please see if the appended patch changes anything?
> 
> More correctly:
> 
> If I suspend by typing pm-suspend or echo mem >/sys/power/state, then it 
> resumes just fine.  If I log in to Gnome and push the suspend button, 
> then it does not resume.  This seems to be the case with or without your 
> patch.

Is there an Intel graphics in your box?

> -rc8 and -rc9 with the original patch 4b4f7280 resume fine no matter how 
> I suspend.

That's _really_ strange.

In fact I have only one explanation, which is that the Gnome suspend button
causes some user-space quirks to be applied, which are harmful and break the
resume.  Also, without commit 4b4f7280 those quirks might have not been really
executed.  Peter, does it sound reasonable?

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2008-07-16 14:24 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-30 23:48 [RFT] x86 acpi: normalize segment descriptor register on resume Rafael J. Wysocki
     [not found] ` <200807010148.02135.rjw-KKrjLPT3xs0@public.gmane.org>
2008-07-01  0:05   ` 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
2008-07-12 20:31                     ` Andy Lutomirski
2008-07-12 20:47                       ` Rafael J. Wysocki
2008-07-12 20:39                     ` Andy Lutomirski
2008-07-12 20:53                       ` Rafael J. Wysocki
2008-07-12 23:11                         ` Andy Lutomirski
2008-07-12 23:33                           ` Rafael J. Wysocki
2008-07-13  8:56                             ` Pavel Machek
2008-07-13 18:16                               ` H. Peter Anvin
2008-07-14  6:36                                 ` Pavel Machek
2008-07-13  9:15                             ` Ingo Molnar
2008-07-13 12:02                               ` Matthew Garrett
2008-07-13 15:50                                 ` Andy Lutomirski
2008-07-13 18:43                                   ` Andi Kleen
2008-07-13 19:15                                     ` Rafael J. Wysocki
2008-07-13 20:11                                       ` Andi Kleen
2008-07-13 20:29                                         ` Rafael J. Wysocki
2008-07-14  2:35                                           ` H. Peter Anvin
2008-07-14 20:10                                             ` Rafael J. Wysocki
2008-07-13 20:38                                         ` H. Peter Anvin
2008-07-14  1:31                                           ` Matthew Garrett
2008-07-14  4:18                                           ` H. Peter Anvin
2008-07-14  7:39                                             ` Pavel Machek
2008-07-14 20:09                                             ` Rafael J. Wysocki
2008-07-16 14:13                                             ` Andrew Lutomirski
2008-07-16 14:23                                               ` Ingo Molnar
2008-07-13 20:16                                     ` H. Peter Anvin
2008-07-13 20:21                                       ` Andi Kleen
2008-07-13 20:32                                         ` Rafael J. Wysocki
2008-07-14  1:22                                         ` Henrique de Moraes Holschuh
2008-07-14  6:14                                           ` Pavel Machek
2008-07-14 11:22                                             ` Henrique de Moraes Holschuh
2008-07-13 18:02                                 ` 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

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).