[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86: fix map_domain_page() last resort fallback



commit 61c6dfce3296da2643c4c4f90eaab6fa3c1cf8b3
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Jun 13 10:49:01 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Jun 13 10:49:01 2013 +0200

    x86: fix map_domain_page() last resort fallback
    
    Guests with vCPU count not divisible by 4 have unused bits in the last
    word of their inuse bitmap, and the garbage collection code therefore
    would get mislead believing that some entries were actually recoverable
    for use.
    
    Also use an earlier established local variable in mapcache_vcpu_init()
    instead of re-calculating the value (noticed while investigating the
    generally better option of setting those overhanging bits once during
    setup - this didn't work out in a simple enough fashion because the
    mapping getting established there isn't in the current address space,
    and hence the bitmap isn't directly accessible there).
    
    Reported-by: Konrad Wilk <konrad.wilk@xxxxxxxxxx>
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
---
 xen/arch/x86/domain_page.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
index efda6af..9297ea0 100644
--- a/xen/arch/x86/domain_page.c
+++ b/xen/arch/x86/domain_page.c
@@ -110,16 +110,17 @@ void *map_domain_page(unsigned long mfn)
     idx = find_next_zero_bit(dcache->inuse, dcache->entries, dcache->cursor);
     if ( unlikely(idx >= dcache->entries) )
     {
-        unsigned long accum = 0;
+        unsigned long accum = 0, prev = 0;
 
         /* /First/, clean the garbage map and update the inuse list. */
         for ( i = 0; i < BITS_TO_LONGS(dcache->entries); i++ )
         {
+            accum |= prev;
             dcache->inuse[i] &= ~xchg(&dcache->garbage[i], 0);
-            accum |= ~dcache->inuse[i];
+            prev = ~dcache->inuse[i];
         }
 
-        if ( accum )
+        if ( accum | (prev & BITMAP_LAST_WORD_MASK(dcache->entries)) )
             idx = find_first_zero_bit(dcache->inuse, dcache->entries);
         else
         {
@@ -279,8 +280,7 @@ int mapcache_vcpu_init(struct vcpu *v)
     if ( ents > dcache->entries )
     {
         /* Populate page tables. */
-        int rc = create_perdomain_mapping(d, MAPCACHE_VIRT_START,
-                                          d->max_vcpus * MAPCACHE_VCPU_ENTRIES,
+        int rc = create_perdomain_mapping(d, MAPCACHE_VIRT_START, ents,
                                           NIL(l1_pgentry_t *), NULL);
 
         /* Populate bit maps. */
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.