ChangeSet 1.1499, 2005/04/07 09:07:52-03:00, [EMAIL PROTECTED] [PATCH] x86_64: Fix reference counting bug in change_page_attr on i386/x86-64 Fix reference counting bug in change_page_attr on i386/x86-64 When not splitting a page the reference count must be increased too. Found by several people in 2.6, one of them was Andrea Arcangelli, other names I don't remember (sorry). Signed-off-by: Andi Kleen <[EMAIL PROTECTED]> Index: linux/arch/i386/mm/pageattr.c ===================================================================
i386/mm/pageattr.c | 8 ++------ x86_64/mm/pageattr.c | 9 +++------ 2 files changed, 5 insertions(+), 12 deletions(-) diff -Nru a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c --- a/arch/i386/mm/pageattr.c 2005-04-07 11:04:03 -07:00 +++ b/arch/i386/mm/pageattr.c 2005-04-07 11:04:03 -07:00 @@ -119,19 +119,15 @@ kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if ((pte_val(*kpte) & _PAGE_PSE) == 0) { - pte_t old = *kpte; - pte_t standard = mk_pte(page, PAGE_KERNEL); - set_pte_atomic(kpte, mk_pte(page, prot)); - if (pte_same(old,standard)) - atomic_inc(&kpte_page->count); } else { struct page *split = split_large_page(address, prot); if (!split) return -ENOMEM; - atomic_inc(&kpte_page->count); set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL)); + kpte_page = split; } + atomic_inc(&kpte_page->count); } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL)); atomic_dec(&kpte_page->count); diff -Nru a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c --- a/arch/x86_64/mm/pageattr.c 2005-04-07 11:04:03 -07:00 +++ b/arch/x86_64/mm/pageattr.c 2005-04-07 11:04:03 -07:00 @@ -101,18 +101,15 @@ kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) { if ((pte_val(*kpte) & _PAGE_PSE) == 0) { - pte_t old = *kpte; - pte_t standard = mk_pte(page, PAGE_KERNEL); - set_pte(kpte, mk_pte(page, prot)); - if (pte_same(old,standard)) - atomic_inc(&kpte_page->count); } else { struct page *split = split_large_page(address, prot); if (!split) return -ENOMEM; set_pte(kpte,mk_pte(split, PAGE_KERNEL)); - } + kpte_page = split; + } + atomic_inc(&kpte_page->count); } else if ((pte_val(*kpte) & _PAGE_PSE) == 0) { set_pte(kpte, mk_pte(page, PAGE_KERNEL)); atomic_dec(&kpte_page->count); - To unsubscribe from this list: send the line "unsubscribe bk-commits-24" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html