From 61c51bb9dab2efa7e763945cc1ea3c651bed6cc9 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 11 Feb 2008 09:49:58 +0000 Subject: [PATCH] xen/x86: fix and improve xen_limit_pages_to_max_mfn() - don't do multicall when nr_mcl is zero (and specifically don't access cr_mcl[nr_mcl - 1] in that case) - fix CONFIG_XEN_COMPAT <=3D 0x030002 handling - don't exchange pages already meeting the restriction (likely avoiding exchanging anything at all) - avoid calling kmap functions without CONFIG_XEN_SCRUB_PAGES - eliminate a few local variables Signed-off-by: Jan Beulich --- arch/i386/mm/hypervisor.c | 78 +++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/arch/i386/mm/hypervisor.c b/arch/i386/mm/hypervisor.c index 4d2e164b..45557d4d 100644 --- a/arch/i386/mm/hypervisor.c +++ b/arch/i386/mm/hypervisor.c @@ -434,19 +434,17 @@ int xen_limit_pages_to_max_mfn( { unsigned long flags, frame; unsigned long *in_frames = discontig_frames, *out_frames = limited_frames; - void *v; struct page *page; - unsigned int i, nr_mcl; + unsigned int i, n, nr_mcl; int rc, success; + DECLARE_BITMAP(limit_map, 1 << MAX_CONTIG_ORDER); struct xen_memory_exchange exchange = { .in = { - .nr_extents = 1UL << order, .extent_order = 0, .domid = DOMID_SELF }, .out = { - .nr_extents = 1UL << order, .extent_order = 0, .address_bits = address_bits, .domid = DOMID_SELF @@ -459,80 +457,98 @@ int xen_limit_pages_to_max_mfn( if (unlikely(order > MAX_CONTIG_ORDER)) return -ENOMEM; + bitmap_zero(limit_map, 1U << order); set_xen_guest_handle(exchange.in.extent_start, in_frames); set_xen_guest_handle(exchange.out.extent_start, out_frames); /* 0. Scrub the pages. */ - for ( i = 0 ; i < 1UL<> (address_bits - PAGE_SHIFT))) + continue; + __set_bit(i, limit_map); - if (!PageHighMem(page)) { - v = page_address(page); - scrub_pages(v, 1); - } else { - v = kmap(page); - scrub_pages(v, 1); + if (!PageHighMem(page)) + scrub_pages(page_address(page), 1); +#ifdef CONFIG_XEN_SCRUB_PAGES + else { + scrub_pages(kmap(page), 1); kunmap(page); + ++n; } +#endif } + if (bitmap_empty(limit_map, 1U << order)) + return 0; - kmap_flush_unused(); + if (n) + kmap_flush_unused(); balloon_lock(flags); /* 1. Zap current PTEs (if any), remembering MFNs. */ - for (i = 0, nr_mcl = 0; i < (1U<