From: Andrew Morton This causes my dual-pIII to hang after "write protecting kernel memory". config: http://userweb.kernel.org/~akpm/config-vmm.txt Cc: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/mm/pageattr.c | 7 ++----- arch/x86_64/mm/pageattr.c | 7 +++---- 2 files changed, 5 insertions(+), 9 deletions(-) diff -puN arch/i386/mm/pageattr.c~revert-x86_64-mm-cpa-cache-flush arch/i386/mm/pageattr.c --- a/arch/i386/mm/pageattr.c~revert-x86_64-mm-cpa-cache-flush +++ a/arch/i386/mm/pageattr.c @@ -170,11 +170,11 @@ __change_page_attr(struct page *page, pg * time (not via split_large_page) and in turn we must not * replace it with a largepage. */ - - list_add(&kpte_page->lru, &df_list); if (!PageReserved(kpte_page)) { if (cpu_has_pse && (page_private(kpte_page) == 0)) { + ClearPagePrivate(kpte_page); paravirt_release_pt(page_to_pfn(kpte_page)); + list_add(&kpte_page->lru, &df_list); revert_page(kpte_page, address); } } @@ -230,9 +230,6 @@ void global_flush_tlb(void) list_for_each_entry_safe(pg, next, &l, lru) { if (cpu_has_clflush) flush_map(page_address(pg)); - if (page_private(pg) != 0) - continue; - ClearPagePrivate(pg); __free_page(pg); } } diff -puN arch/x86_64/mm/pageattr.c~revert-x86_64-mm-cpa-cache-flush arch/x86_64/mm/pageattr.c --- a/arch/x86_64/mm/pageattr.c~revert-x86_64-mm-cpa-cache-flush +++ a/arch/x86_64/mm/pageattr.c @@ -158,9 +158,10 @@ __change_page_attr(unsigned long address /* on x86-64 the direct mapping set at boot is not using 4k pages */ BUG_ON(PageReserved(kpte_page)); - save_page(kpte_page); - if (page_private(kpte_page) == 0) + if (page_private(kpte_page) == 0) { + save_page(kpte_page); revert_page(address, ref_prot); + } return 0; } @@ -232,8 +233,6 @@ void global_flush_tlb(void) flush_map(&l); list_for_each_entry_safe(pg, next, &l, lru) { - if (page_private(pg) != 0) - continue; ClearPagePrivate(pg); __free_page(pg); } _