diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-03-05 10:26:45 +0000 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2007-03-05 10:26:45 +0000 |
commit | 738c5625acb78b160ee94ae9225fec6fc33c8771 (patch) | |
tree | bdb059997d37d60462d44ce4d7f8dc394d0eba65 /linux-2.6-xen-sparse | |
parent | 87832ae66197011aa1da7b756aee2d9edbb5e7d1 (diff) | |
download | xen-738c5625acb78b160ee94ae9225fec6fc33c8771.tar.gz xen-738c5625acb78b160ee94ae9225fec6fc33c8771.tar.bz2 xen-738c5625acb78b160ee94ae9225fec6fc33c8771.zip |
linux: Clean up mm_pin/unpin.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'linux-2.6-xen-sparse')
-rw-r--r-- | linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c | 52 | ||||
-rw-r--r-- | linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c | 9 |
2 files changed, 33 insertions, 28 deletions
diff --git a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c index 2cac785e50..4f72489800 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c @@ -573,64 +573,67 @@ void make_pages_writable(void *va, unsigned int nr, unsigned int feature) } } -static inline int pgd_walk_set_prot(struct page *page, pgprot_t flags) +static inline void pgd_walk_set_prot(struct page *page, pgprot_t flags) { unsigned long pfn = page_to_pfn(page); + int rc; - if (PageHighMem(page)) - return pgprot_val(flags) & _PAGE_RW - ? test_and_clear_bit(PG_pinned, &page->flags) - : !test_and_set_bit(PG_pinned, &page->flags); - - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - pfn_pte(pfn, flags), 0)); - - return 0; + if (PageHighMem(page)) { + if (pgprot_val(flags) & _PAGE_RW) + clear_bit(PG_pinned, &page->flags); + else + set_bit(PG_pinned, &page->flags); + } else { + rc = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + pfn_pte(pfn, flags), 0); + if (rc) + BUG(); + } } -static int pgd_walk(pgd_t *pgd_base, pgprot_t flags) +static void pgd_walk(pgd_t *pgd_base, pgprot_t flags) { pgd_t *pgd = pgd_base; pud_t *pud; pmd_t *pmd; - int g, u, m, flush; + int g, u, m, rc; if (xen_feature(XENFEAT_auto_translated_physmap)) return 0; - for (g = 0, flush = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { + for (g = 0; g < USER_PTRS_PER_PGD; g++, pgd++) { if (pgd_none(*pgd)) continue; pud = pud_offset(pgd, 0); if (PTRS_PER_PUD > 1) /* not folded */ - flush |= pgd_walk_set_prot(virt_to_page(pud),flags); + pgd_walk_set_prot(virt_to_page(pud),flags); for (u = 0; u < PTRS_PER_PUD; u++, pud++) { if (pud_none(*pud)) continue; pmd = pmd_offset(pud, 0); if (PTRS_PER_PMD > 1) /* not folded */ - flush |= pgd_walk_set_prot(virt_to_page(pmd),flags); + pgd_walk_set_prot(virt_to_page(pmd),flags); for (m = 0; m < PTRS_PER_PMD; m++, pmd++) { if (pmd_none(*pmd)) continue; - flush |= pgd_walk_set_prot(pmd_page(*pmd),flags); + pgd_walk_set_prot(pmd_page(*pmd),flags); } } } - BUG_ON(HYPERVISOR_update_va_mapping( + rc = HYPERVISOR_update_va_mapping( (unsigned long)pgd_base, pfn_pte(virt_to_phys(pgd_base)>>PAGE_SHIFT, flags), - UVMF_TLB_FLUSH)); - - return flush; + UVMF_TLB_FLUSH); + if (rc) + BUG(); } static void __pgd_pin(pgd_t *pgd) { - if (pgd_walk(pgd, PAGE_KERNEL_RO)) - kmap_flush_unused(); + pgd_walk(pgd, PAGE_KERNEL_RO); + kmap_flush_unused(); xen_pgd_pin(__pa(pgd)); set_bit(PG_pinned, &virt_to_page(pgd)->flags); } @@ -638,8 +641,7 @@ static void __pgd_pin(pgd_t *pgd) static void __pgd_unpin(pgd_t *pgd) { xen_pgd_unpin(__pa(pgd)); - if (pgd_walk(pgd, PAGE_KERNEL)) - kmap_flush_unused(); + pgd_walk(pgd, PAGE_KERNEL); clear_bit(PG_pinned, &virt_to_page(pgd)->flags); } diff --git a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c index a0f1d0535d..ae434e6be4 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c @@ -24,10 +24,13 @@ static inline void mm_walk_set_prot(void *pt, pgprot_t flags) { struct page *page = virt_to_page(pt); unsigned long pfn = page_to_pfn(page); + int rc; - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)__va(pfn << PAGE_SHIFT), - pfn_pte(pfn, flags), 0)); + rc = HYPERVISOR_update_va_mapping( + (unsigned long)__va(pfn << PAGE_SHIFT), + pfn_pte(pfn, flags), 0); + if (rc) + BUG(); } static void mm_walk(struct mm_struct *mm, pgprot_t flags) |