public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Tosatti <mtosatti@redhat.com>
To: kvm@vger.kernel.org
Cc: avi@redhat.com, jan.kiszka@web.de, Marcelo Tosatti <mtosatti@redhat.com>
Subject: [patch 1/6] remove alias support
Date: Mon, 03 May 2010 19:48:20 -0300	[thread overview]
Message-ID: <20100503224905.127715840@amt.cnet> (raw)
In-Reply-To: 20100503224819.773169076@amt.cnet

[-- Attachment #1: remove-alias-support --]
[-- Type: text/plain, Size: 10605 bytes --]

Aliases were added to workaround kvm's inability to destroy
memory regions. This was fixed in 2.6.29, and advertised via
KVM_CAP_DESTROY_MEMORY_REGION_WORKS.

Also, alias support will be removed from the kernel in July 2010.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

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



  reply	other threads:[~2010-05-03 22:56 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-03 22:48 [patch 0/6] qemu-kvm: use upstream memslot code Marcelo Tosatti
2010-05-03 22:48 ` Marcelo Tosatti [this message]
2010-05-03 22:48 ` [patch 2/6] remove support for !KVM_CAP_SET_TSS_ADDR Marcelo Tosatti
2010-05-03 22:48 ` [patch 3/6] remove unused kvm_get_dirty_pages Marcelo Tosatti
2010-05-03 22:48 ` [patch 4/6] remove unused kvm_dirty_bitmap array Marcelo Tosatti
2010-05-03 22:48 ` [patch 5/6] introduce qemu_ram_map Marcelo Tosatti
2010-05-03 22:48 ` [patch 6/6] use upstream memslot management code Marcelo Tosatti
2010-05-05  8:49 ` [patch 0/6] qemu-kvm: use upstream memslot code Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100503224905.127715840@amt.cnet \
    --to=mtosatti@redhat.com \
    --cc=avi@redhat.com \
    --cc=jan.kiszka@web.de \
    --cc=kvm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox