From: Shaohua Li flush_tlb_all uses on_each_cpu, which will disable/enable interrupt. In suspend/resume time, this will make interrupt wrongly enabled. Signed-off-by: Shaohua Li Cc: Pavel Machek Signed-off-by: Andrew Morton --- arch/i386/kernel/acpi/sleep.c | 19 ++----------------- arch/i386/kernel/acpi/wakeup.S | 2 +- arch/i386/mm/init.c | 3 ++- arch/x86_64/kernel/acpi/sleep.c | 7 +++++-- 4 files changed, 10 insertions(+), 21 deletions(-) diff -puN arch/i386/kernel/acpi/sleep.c~dont-use-flush_tlb_all-in-suspend-time arch/i386/kernel/acpi/sleep.c --- 25/arch/i386/kernel/acpi/sleep.c~dont-use-flush_tlb_all-in-suspend-time Fri May 26 16:05:07 2006 +++ 25-akpm/arch/i386/kernel/acpi/sleep.c Fri May 26 16:05:09 2006 @@ -8,30 +8,17 @@ #include #include #include +#include + #include -#include /* address in low memory of the wakeup routine. */ unsigned long acpi_wakeup_address = 0; unsigned long acpi_video_flags; extern char wakeup_start, wakeup_end; -extern void zap_low_mappings(void); - extern unsigned long FASTCALL(acpi_copy_wakeup_routine(unsigned long)); -static void init_low_mapping(pgd_t * pgd, int pgd_limit) -{ - int pgd_ofs = 0; - - while ((pgd_ofs < pgd_limit) - && (pgd_ofs + USER_PTRS_PER_PGD < PTRS_PER_PGD)) { - set_pgd(pgd, *(pgd + USER_PTRS_PER_PGD)); - pgd_ofs++, pgd++; - } - flush_tlb_all(); -} - /** * acpi_save_state_mem - save kernel state * @@ -42,7 +29,6 @@ int acpi_save_state_mem(void) { if (!acpi_wakeup_address) 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); @@ -55,7 +41,6 @@ int acpi_save_state_mem(void) */ void acpi_restore_state_mem(void) { - zap_low_mappings(); } /** diff -puN arch/i386/mm/init.c~dont-use-flush_tlb_all-in-suspend-time arch/i386/mm/init.c --- 25/arch/i386/mm/init.c~dont-use-flush_tlb_all-in-suspend-time Fri May 26 16:05:07 2006 +++ 25-akpm/arch/i386/mm/init.c Fri May 26 16:05:09 2006 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -384,7 +385,7 @@ static void __init pagetable_init (void) #endif } -#ifdef CONFIG_SOFTWARE_SUSPEND +#if defined(CONFIG_SOFTWARE_SUSPEND) || defined(CONFIG_ACPI_SLEEP) /* * Swap suspend & friends need this for resume because things like the intel-agp * driver might have split up a kernel 4MB mapping. diff -puN arch/x86_64/kernel/acpi/sleep.c~dont-use-flush_tlb_all-in-suspend-time arch/x86_64/kernel/acpi/sleep.c --- 25/arch/x86_64/kernel/acpi/sleep.c~dont-use-flush_tlb_all-in-suspend-time Fri May 26 16:05:07 2006 +++ 25-akpm/arch/x86_64/kernel/acpi/sleep.c Fri May 26 16:05:08 2006 @@ -35,6 +35,8 @@ #include #include #include +#include + #include #include #include @@ -66,7 +68,8 @@ static void init_low_mapping(void) pgd_t *slot0 = pgd_offset(current->mm, 0UL); low_ptr = *slot0; set_pgd(slot0, *pgd_offset(current->mm, PAGE_OFFSET)); - flush_tlb_all(); + WARN_ON(num_online_cpus() != 1); + local_flush_tlb(); } /** @@ -92,7 +95,7 @@ int acpi_save_state_mem(void) void acpi_restore_state_mem(void) { set_pgd(pgd_offset(current->mm, 0UL), low_ptr); - flush_tlb_all(); + local_flush_tlb(); } /** diff -puN arch/i386/kernel/acpi/wakeup.S~dont-use-flush_tlb_all-in-suspend-time arch/i386/kernel/acpi/wakeup.S --- 25/arch/i386/kernel/acpi/wakeup.S~dont-use-flush_tlb_all-in-suspend-time Fri May 26 16:05:09 2006 +++ 25-akpm/arch/i386/kernel/acpi/wakeup.S Fri May 26 16:05:09 2006 @@ -56,7 +56,7 @@ wakeup_code: 1: # set up page table - movl $swapper_pg_dir-__PAGE_OFFSET, %eax + movl $swsusp_pg_dir-__PAGE_OFFSET, %eax movl %eax, %cr3 testl $1, real_efer_save_restore - wakeup_code _