Index: qemu-kvm/qemu-kvm.c
===================================================================
--- qemu-kvm.orig/qemu-kvm.c
+++ qemu-kvm/qemu-kvm.c
@@ -1076,20 +1076,6 @@ int kvm_deassign_pci_device(kvm_context_
 }
 #endif
 
-int kvm_destroy_memory_region_works(kvm_context_t kvm)
-{
-    int ret = 0;
-
-#ifdef KVM_CAP_DESTROY_MEMORY_REGION_WORKS
-    ret =
-        kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION,
-                  KVM_CAP_DESTROY_MEMORY_REGION_WORKS);
-    if (ret <= 0)
-        ret = 0;
-#endif
-    return ret;
-}
-
 int kvm_reinject_control(kvm_context_t kvm, int pit_reinject)
 {
 #ifdef KVM_CAP_REINJECT_CONTROL
@@ -2055,11 +2041,6 @@ int kvm_main_loop(void)
     return 0;
 }
 
-#ifdef TARGET_I386
-static int destroy_region_works = 0;
-#endif
-
-
 #if !defined(TARGET_I386)
 int kvm_arch_init_irq_routing(void)
 {
@@ -2071,6 +2052,10 @@ extern int no_hpet;
 
 static int kvm_create_context(void)
 {
+    static const char upgrade_note[] =
+    "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"
+    "(see http://sourceforge.net/projects/kvm).\n";
+
     int r;
 
     if (!kvm_irqchip) {
@@ -2094,9 +2079,16 @@ static int kvm_create_context(void)
             return -1;
         }
     }
-#ifdef TARGET_I386
-    destroy_region_works = kvm_destroy_memory_region_works(kvm_context);
-#endif
+
+    /* There was a nasty bug in < kvm-80 that prevents memory slots from being
+     * destroyed properly.  Since we rely on this capability, refuse to work
+     * with any kernel without this capability. */
+    if (!kvm_check_extension(kvm_state, KVM_CAP_DESTROY_MEMORY_REGION_WORKS)) {
+        fprintf(stderr,
+                "KVM kernel module broken (DESTROY_MEMORY_REGION).\n%s",
+                upgrade_note);
+        return -EINVAL;
+    }
 
     r = kvm_arch_init_irq_routing();
     if (r < 0) {
@@ -2134,73 +2126,11 @@ static int kvm_create_context(void)
     return 0;
 }
 
-#ifdef TARGET_I386
-static int must_use_aliases_source(target_phys_addr_t addr)
-{
-    if (destroy_region_works)
-        return false;
-    if (addr == 0xa0000 || addr == 0xa8000)
-        return true;
-    return false;
-}
-
-static int must_use_aliases_target(target_phys_addr_t addr)
-{
-    if (destroy_region_works)
-        return false;
-    if (addr >= 0xe0000000 && addr < 0x100000000ull)
-        return true;
-    return false;
-}
-
-static struct mapping {
-    target_phys_addr_t phys;
-    ram_addr_t ram;
-    ram_addr_t len;
-} mappings[50];
-static int nr_mappings;
-
-static struct mapping *find_ram_mapping(ram_addr_t ram_addr)
-{
-    struct mapping *p;
-
-    for (p = mappings; p < mappings + nr_mappings; ++p) {
-        if (p->ram <= ram_addr && ram_addr < p->ram + p->len) {
-            return p;
-        }
-    }
-    return NULL;
-}
-
-static struct mapping *find_mapping(target_phys_addr_t start_addr)
-{
-    struct mapping *p;
-
-    for (p = mappings; p < mappings + nr_mappings; ++p) {
-        if (p->phys <= start_addr && start_addr < p->phys + p->len) {
-            return p;
-        }
-    }
-    return NULL;
-}
-
-static void drop_mapping(target_phys_addr_t start_addr)
-{
-    struct mapping *p = find_mapping(start_addr);
-
-    if (p)
-        *p = mappings[--nr_mappings];
-}
-#endif
-
 void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
                       ram_addr_t phys_offset)
 {
     int r = 0;
     unsigned long area_flags;
-#ifdef TARGET_I386
-    struct mapping *p;
-#endif
 
     if (start_addr + size > phys_ram_size) {
         phys_ram_size = start_addr + size;
@@ -2210,19 +2140,13 @@ void kvm_set_phys_mem(target_phys_addr_t
     area_flags = phys_offset & ~TARGET_PAGE_MASK;
 
     if (area_flags != IO_MEM_RAM) {
-#ifdef TARGET_I386
-        if (must_use_aliases_source(start_addr)) {
-            kvm_destroy_memory_alias(kvm_context, start_addr);
-            return;
-        }
-        if (must_use_aliases_target(start_addr))
-            return;
-#endif
         while (size > 0) {
-            p = find_mapping(start_addr);
-            if (p) {
-                kvm_unregister_memory_area(kvm_context, p->phys, p->len);
-                drop_mapping(p->phys);
+            int slot;
+
+            slot = get_slot(start_addr);
+            if (slot != -1) {
+                kvm_unregister_memory_area(kvm_context, slots[slot].phys_addr,
+                                           slots[slot].len);
             }
             start_addr += TARGET_PAGE_SIZE;
             if (size > TARGET_PAGE_SIZE) {
@@ -2241,30 +2165,12 @@ void kvm_set_phys_mem(target_phys_addr_t
     if (area_flags >= TLB_MMIO)
         return;
 
-#ifdef TARGET_I386
-    if (must_use_aliases_source(start_addr)) {
-        p = find_ram_mapping(phys_offset);
-        if (p) {
-            kvm_create_memory_alias(kvm_context, start_addr, size,
-                                    p->phys + (phys_offset - p->ram));
-        }
-        return;
-    }
-#endif
-
     r = kvm_register_phys_mem(kvm_context, start_addr,
                               qemu_get_ram_ptr(phys_offset), size, 0);
     if (r < 0) {
         printf("kvm_cpu_register_physical_memory: failed\n");
         exit(1);
     }
-#ifdef TARGET_I386
-    drop_mapping(start_addr);
-    p = &mappings[nr_mappings++];
-    p->phys = start_addr;
-    p->ram = phys_offset;
-    p->len = size;
-#endif
 
     return;
 }
@@ -2342,10 +2248,6 @@ void kvm_qemu_log_memory(target_phys_add
     if (log)
         kvm_dirty_pages_log_enable_slot(kvm_context, start, size);
     else {
-#ifdef TARGET_I386
-        if (must_use_aliases_target(start))
-            return;
-#endif
         kvm_dirty_pages_log_disable_slot(kvm_context, start, size);
     }
 }
@@ -2418,12 +2320,6 @@ int kvm_physical_sync_dirty_bitmap(targe
                                    target_phys_addr_t end_addr)
 {
 #ifndef TARGET_IA64
-
-#ifdef TARGET_I386
-    if (must_use_aliases_source(start_addr))
-        return 0;
-#endif
-
     kvm_get_dirty_pages_range(kvm_context, start_addr,
                               end_addr - start_addr, NULL,
                               kvm_get_dirty_bitmap_cb);
@@ -2433,11 +2329,6 @@ int kvm_physical_sync_dirty_bitmap(targe
 
 int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t len)
 {
-#ifdef TARGET_I386
-    if (must_use_aliases_source(phys_addr))
-        return 0;
-#endif
-
 #ifndef TARGET_IA64
     kvm_qemu_log_memory(phys_addr, len, 1);
 #endif
@@ -2446,11 +2337,6 @@ int kvm_log_start(target_phys_addr_t phy
 
 int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t len)
 {
-#ifdef TARGET_I386
-    if (must_use_aliases_source(phys_addr))
-        return 0;
-#endif
-
 #ifndef TARGET_IA64
     kvm_qemu_log_memory(phys_addr, len, 0);
 #endif
Index: qemu-kvm/qemu-kvm-x86.c
===================================================================
--- qemu-kvm.orig/qemu-kvm-x86.c
+++ qemu-kvm/qemu-kvm-x86.c
@@ -214,71 +214,6 @@ int kvm_arch_run(CPUState *env)
 	return r;
 }
 
-#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_start,
-			    uint64_t len,
-			    uint64_t target_phys)
-{
-	struct kvm_memory_alias alias = {
-		.flags = 0,
-		.guest_phys_addr = phys_start,
-		.memory_size = len,
-		.target_phys_addr = target_phys,
-	};
-	int r;
-	int slot;
-
-	slot = get_alias_slot(phys_start);
-	if (slot < 0)
-		slot = get_free_alias_slot();
-	if (slot < 0)
-		return -EBUSY;
-	alias.slot = slot;
-
-	r = kvm_vm_ioctl(kvm_state, 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_start)
-{
-	return kvm_create_memory_alias(kvm, phys_start, 0, 0);
-}
-
 #ifdef KVM_CAP_IRQCHIP
 
 int kvm_get_lapic(CPUState *env, struct kvm_lapic_state *s)
@@ -616,18 +551,6 @@ static int kvm_enable_tpr_access_reporti
 }
 #endif
 
-int kvm_qemu_create_memory_alias(uint64_t phys_start,
-                                 uint64_t len,
-                                 uint64_t target_phys)
-{
-    return kvm_create_memory_alias(kvm_context, phys_start, len, target_phys);
-}
-
-int kvm_qemu_destroy_memory_alias(uint64_t phys_start)
-{
-	return kvm_destroy_memory_alias(kvm_context, phys_start);
-}
-
 #ifdef KVM_CAP_ADJUST_CLOCK
 static struct kvm_clock_data kvmclock_data;
 
Index: qemu-kvm/qemu-kvm.h
===================================================================
--- qemu-kvm.orig/qemu-kvm.h
+++ qemu-kvm/qemu-kvm.h
@@ -400,23 +400,6 @@ int kvm_unregister_coalesced_mmio(kvm_co
                                   uint32_t size);
 
 /*!
- * \brief Create a memory alias
- *
- * Aliases a portion of physical memory to another portion.  If the guest
- * 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_start, uint64_t len,
-                            uint64_t target_phys);
-
-/*!
- * \brief Destroy a memory alias
- *
- * Removes an alias created with kvm_create_memory_alias().
- */
-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.
  *
  * \param kvm Pointer to the current kvm_context
@@ -651,15 +634,6 @@ int kvm_deassign_irq(kvm_context_t kvm, 
 #endif
 #endif
 
-/*!
- * \brief Determines whether destroying memory regions is allowed
- *
- * KVM before 2.6.29 had a bug when destroying memory regions.
- *
- * \param kvm Pointer to the current kvm_context
- */
-int kvm_destroy_memory_region_works(kvm_context_t kvm);
-
 #ifdef KVM_CAP_DEVICE_DEASSIGNMENT
 /*!
  * \brief Notifies host kernel about a PCI device to be deassigned from a guest
