From: Uri Lublin <[EMAIL PROTECTED]>

There was a mix up between memory-slots and alias-slots.
There was a high probability that two independent aliases will
override one another.

Fixed by keeping the alias slots separate from the memory slots, and
by removing phys_addr from parameter list.

Signed-off-by: Uri Lublin <[EMAIL PROTECTED]>
Signed-off-by: Avi Kivity <[EMAIL PROTECTED]>

diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
index 2fa8146..4bd0e2f 100644
--- a/libkvm/libkvm-x86.c
+++ b/libkvm/libkvm-x86.c
@@ -240,8 +240,38 @@ void *kvm_create_kernel_phys_mem(kvm_context_t kvm, 
unsigned long phys_start,
        return ptr;
 }
 
+#define MAX_ALIAS_SLOTS 4
+static struct {
+       uint64_t start;
+       uint64_t len;
+} kvm_aliases[MAX_ALIAS_SLOTS];
+
+static int get_alias_slot(uint64_t start)
+{
+       int i;
+
+       for (i=0; i<MAX_ALIAS_SLOTS; i++)
+               if (kvm_aliases[i].start == start)
+                       return i;
+       return -1;
+}
+static int get_free_alias_slot(void)
+{
+        int i;
+
+        for (i=0; i<MAX_ALIAS_SLOTS; i++)
+                if (kvm_aliases[i].len == 0)
+                        return i;
+        return -1;
+}
+
+static void register_alias(int slot, uint64_t start, uint64_t len)
+{
+       kvm_aliases[slot].start = start;
+       kvm_aliases[slot].len   = len;
+}
+
 int kvm_create_memory_alias(kvm_context_t kvm,
-                           uint64_t phys_addr,
                            uint64_t phys_start,
                            uint64_t len,
                            uint64_t target_phys)
@@ -254,19 +284,26 @@ int kvm_create_memory_alias(kvm_context_t kvm,
        };
        int fd = kvm->vm_fd;
        int r;
+       int slot;
 
-       alias.slot = get_slot(phys_addr);
+       slot = get_alias_slot(phys_start);
+       if (slot < 0)
+               slot = get_free_alias_slot();
+       if (slot < 0)
+               return -EBUSY;
+       alias.slot = slot;
 
        r = ioctl(fd, KVM_SET_MEMORY_ALIAS, &alias);
        if (r == -1)
            return -errno;
 
+       register_alias(slot, phys_start, len);
        return 0;
 }
 
-int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_addr)
+int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_start)
 {
-       return kvm_create_memory_alias(kvm, phys_addr, 0, 0, 0);
+       return kvm_create_memory_alias(kvm, phys_start, 0, 0);
 }
 
 #ifdef KVM_CAP_IRQCHIP
diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
index 34d188b..395434c 100644
--- a/libkvm/libkvm.h
+++ b/libkvm/libkvm.h
@@ -430,7 +430,7 @@ int kvm_get_dirty_pages_range(kvm_context_t kvm, unsigned 
long phys_addr,
  * accesses the alias region, it will behave exactly as if it accessed
  * the target memory.
  */
-int kvm_create_memory_alias(kvm_context_t, uint64_t phys_addr,
+int kvm_create_memory_alias(kvm_context_t,
                            uint64_t phys_start, uint64_t len,
                            uint64_t target_phys);
 
@@ -439,7 +439,7 @@ int kvm_create_memory_alias(kvm_context_t, uint64_t 
phys_addr,
  *
  * Removes an alias created with kvm_create_memory_alias().
  */
-int kvm_destroy_memory_alias(kvm_context_t, uint64_t phys_addr);
+int kvm_destroy_memory_alias(kvm_context_t, uint64_t phys_start);
 
 /*!
  * \brief Get a bitmap of guest ram pages which are allocated to the guest.
diff --git a/qemu/hw/cirrus_vga.c b/qemu/hw/cirrus_vga.c
index 1915c73..43307d8 100644
--- a/qemu/hw/cirrus_vga.c
+++ b/qemu/hw/cirrus_vga.c
@@ -2635,8 +2635,7 @@ int unset_vram_mapping(unsigned long begin, unsigned long 
end)
     return 0;
 }
 #ifdef CONFIG_X86
-static void kvm_update_vga_alias(CirrusVGAState *s, int ok, int bank,
-                                 unsigned long phys_addr)
+static void kvm_update_vga_alias(CirrusVGAState *s, int ok, int bank)
 {
     unsigned limit, base;
 
@@ -2650,22 +2649,22 @@ static void kvm_update_vga_alias(CirrusVGAState *s, int 
ok, int bank,
        if (!s->aliases_enabled
            || base != s->aliased_bank_base[bank]
            || limit != s->aliased_bank_limit[bank]) {
-           kvm_create_memory_alias(kvm_context, phys_addr,
+           kvm_create_memory_alias(kvm_context,
                                    0xa0000 + bank * 0x8000,
                                    limit, base);
            s->aliased_bank_base[bank] = base;
            s->aliased_bank_limit[bank] = limit;
        }
     } else {
-       kvm_destroy_memory_alias(kvm_context, phys_addr);
+       kvm_destroy_memory_alias(kvm_context, 0xa0000 + bank * 0x8000);
     }
 }
 
 static void kvm_update_vga_aliases(CirrusVGAState *s, int ok)
 {
     if (kvm_enabled()) {
-       kvm_update_vga_alias(s, ok, 0, 0xc0000);
-       kvm_update_vga_alias(s, ok, 1, s->map_addr);
+       kvm_update_vga_alias(s, ok, 0);
+       kvm_update_vga_alias(s, ok, 1);
     }
     s->aliases_enabled = ok;
 }

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-commits mailing list
kvm-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-commits

Reply via email to