public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* RE: [patch] Fix GDT re-load on ACPI resume
@ 2004-11-16  5:37 Li, Shaohua
  2004-11-16 12:42 ` Maciej W. Rozycki
  2004-11-17 18:57 ` Pavel Machek
  0 siblings, 2 replies; 11+ messages in thread
From: Li, Shaohua @ 2004-11-16  5:37 UTC (permalink / raw)
  To: Nickolai Zeldovich, linux-kernel; +Cc: csapuntz, hiroit

[-- Attachment #1: Type: text/plain, Size: 1153 bytes --]

>The ACPI resume code currently uses a real-mode 16-bit lgdt instruction
to
>reload the GDT.  This only restores the lower 24 bits of the GDT base
>address.  In recent kernels, the GDT seems to have moved out of the
lower
>16 megs, thereby causing the ACPI resume to fail -- an invalid GDT was
>being loaded.
>
>This simple patch adds the 0x66 prefix to lgdt, which forces it to load
>all 32 bits of the GDT base address, thereby removing any restrictions
on
>where the GDT can be placed in memory.  This makes ACPI resume work for
me
>on a Thinkpad T40 laptop.
>
>-- kolya
>
>--- linux-2.6.9/arch/i386/kernel/acpi/wakeup.S	2004/11/15 09:00:34
1.1
>+++ linux-2.6.9/arch/i386/kernel/acpi/wakeup.S	2004/11/15 20:33:27
>@@ -67,6 +67,8 @@
> 	movw	$0x0e00 + 'i', %fs:(0x12)
>
> 	# need a gdt
>+	.byte	0x66			# force 32-bit operands in case
>+					# the GDT is past 16 megabytes
> 	lgdt	real_save_gdt - wakeup_code
>
> 	movl	real_save_cr0 - wakeup_code, %eax
There is a patch from hiroit@mcn.ne.jp to fix the GDT issue. You can try
it.
Please cc 'acpi-devel@lists.sourceforge.net' for suspend/resume issue.

Thanks,
Shaohua

[-- Attachment #2: wakeup_gdt2.patch --]
[-- Type: application/octet-stream, Size: 2214 bytes --]

diff -Nru a/arch/i386/kernel/acpi/sleep.c b/arch/i386/kernel/acpi/sleep.c
--- a/arch/i386/kernel/acpi/sleep.c	2004-10-15 11:29:15.000000000 +0900
+++ b/arch/i386/kernel/acpi/sleep.c	2004-10-19 00:59:32.000000000 +0900
@@ -17,7 +17,7 @@
 
 extern void zap_low_mappings(void);
 
-extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long));
+extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long,unsigned long));
 
 static void init_low_mapping(pgd_t *pgd, int pgd_limit)
 {
@@ -41,7 +41,8 @@
 		return 1;
 	init_low_mapping(swapper_pg_dir, USER_PTRS_PER_PGD);
 	memcpy((void *) acpi_wakeup_address, &wakeup_start, &wakeup_end - &wakeup_start);
-	acpi_copy_wakeup_routine(acpi_wakeup_address);
+	acpi_copy_wakeup_routine(acpi_wakeup_address,
+				 virt_to_phys((void *)acpi_wakeup_address));
 
 	return 0;
 }
diff -Nru a/arch/i386/kernel/acpi/wakeup.S b/arch/i386/kernel/acpi/wakeup.S
--- a/arch/i386/kernel/acpi/wakeup.S	2004-08-14 14:36:31.000000000 +0900
+++ b/arch/i386/kernel/acpi/wakeup.S	2004-10-19 05:24:42.000000000 +0900
@@ -89,6 +89,7 @@
 real_magic:	.long 0
 video_mode:	.long 0
 video_flags:	.long 0
+real_gdt_table: .fill GDT_ENTRIES, 8, 0
 
 bogus_real_magic:
 	movw	$0x0e00 + 'B', %fs:(0x12)
@@ -213,6 +214,7 @@
 #
 # Parameters:
 # %eax:	place to copy wakeup routine to
+# %edx: the second argument (physical address)
 #
 # Returned address is location of code in low memory (past data and stack)
 #
@@ -223,6 +225,9 @@
 	sldt	saved_ldt
 	str	saved_tss
 
+	# save wakeup_start physical address in ecx
+	movl	%edx, %ecx
+
 	movl    %cr3, %edx
 	movl    %edx, real_save_cr3 - wakeup_start (%eax)
 	movl    %cr4, %edx
@@ -231,6 +236,16 @@
 	movl	%edx, real_save_cr0 - wakeup_start (%eax)
 	sgdt    real_save_gdt - wakeup_start (%eax)
 
+	# gdt body must be addressable from real mode by
+	# copying it to the lower mem
+	lea     real_gdt_table - wakeup_start (%ecx), %ecx
+	movl    %ecx, real_save_gdt + 2 - wakeup_start (%eax)
+	xor     %ecx, %ecx
+	movw    saved_gdt, %cx
+	movl    saved_gdt + 2, %esi
+	lea     real_gdt_table - wakeup_start (%eax), %edi
+	rep movsb
+
 	movl	saved_videomode, %edx
 	movl	%edx, video_mode - wakeup_start (%eax)
 	movl	acpi_video_flags, %edx

^ permalink raw reply	[flat|nested] 11+ messages in thread
* RE: [patch] Fix GDT re-load on ACPI resume
@ 2004-11-18  1:59 Li, Shaohua
  0 siblings, 0 replies; 11+ messages in thread
From: Li, Shaohua @ 2004-11-18  1:59 UTC (permalink / raw)
  To: Pavel Machek; +Cc: Nickolai Zeldovich, linux-kernel, csapuntz, hiroit

>> > 	movw	_0x0e00 + 'i', %fs:(0x12)
>> >
>> > 	# need a gdt
>> >+	.byte	0x66			# force 32-bit operands in case
>> >+					# the GDT is past 16 megabytes
>> > 	lgdt	real_save_gdt - wakeup_code
>> >
>> > 	movl	real_save_cr0 - wakeup_code, %eax
>> There is a patch from hiroit@mcn.ne.jp to fix the GDT issue. You can
try
>> it.
>
>Well, replacing lgdt with lgdtl (above) seems like nicer solution than
>attachment...
Copy GDT to low mem seems safer. Now the GDT table is in per-cpu region,
possibly it's not in low memory. Or am I missing anything?

Shaohua

^ permalink raw reply	[flat|nested] 11+ messages in thread
* [patch] Fix GDT re-load on ACPI resume
@ 2004-11-15 20:35 Nickolai Zeldovich
  2004-11-15 23:02 ` David Weinehall
  2004-11-15 23:26 ` Maciej W. Rozycki
  0 siblings, 2 replies; 11+ messages in thread
From: Nickolai Zeldovich @ 2004-11-15 20:35 UTC (permalink / raw)
  To: linux-kernel; +Cc: csapuntz

The ACPI resume code currently uses a real-mode 16-bit lgdt instruction to
reload the GDT.  This only restores the lower 24 bits of the GDT base
address.  In recent kernels, the GDT seems to have moved out of the lower
16 megs, thereby causing the ACPI resume to fail -- an invalid GDT was
being loaded.

This simple patch adds the 0x66 prefix to lgdt, which forces it to load
all 32 bits of the GDT base address, thereby removing any restrictions on
where the GDT can be placed in memory.  This makes ACPI resume work for me
on a Thinkpad T40 laptop.

-- kolya

--- linux-2.6.9/arch/i386/kernel/acpi/wakeup.S	2004/11/15 09:00:34	1.1
+++ linux-2.6.9/arch/i386/kernel/acpi/wakeup.S	2004/11/15 20:33:27
@@ -67,6 +67,8 @@
 	movw	$0x0e00 + 'i', %fs:(0x12)

 	# need a gdt
+	.byte	0x66			# force 32-bit operands in case
+					# the GDT is past 16 megabytes
 	lgdt	real_save_gdt - wakeup_code

 	movl	real_save_cr0 - wakeup_code, %eax

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

end of thread, other threads:[~2004-11-18  2:29 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-16  5:37 [patch] Fix GDT re-load on ACPI resume Li, Shaohua
2004-11-16 12:42 ` Maciej W. Rozycki
2004-11-16 17:46   ` Hiroshi Itoh
2004-11-17  1:02     ` Maciej W. Rozycki
2004-11-17 18:57 ` Pavel Machek
  -- strict thread matches above, loose matches on Subject: below --
2004-11-18  1:59 Li, Shaohua
2004-11-15 20:35 Nickolai Zeldovich
2004-11-15 23:02 ` David Weinehall
2004-11-15 23:13   ` Nickolai Zeldovich
2004-11-15 23:26 ` Maciej W. Rozycki
2004-11-15 23:52   ` Nickolai Zeldovich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox