From: Glauber Costa <glommer@redhat.com>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, avi@redhat.com
Subject: Re: [PATCH] always assign userspace_addr
Date: Wed, 19 Nov 2008 18:53:32 -0200 [thread overview]
Message-ID: <20081119205332.GA27378@poweredge.glommer> (raw)
In-Reply-To: <49246014.5000001@codemonkey.ws>
[-- Attachment #1: Type: text/plain, Size: 496 bytes --]
On Wed, Nov 19, 2008 at 12:51:00PM -0600, Anthony Liguori wrote:
>
> But the problem still exists even with this code. I checked.
>
> So if you have something working without modifying the kernel, can you
> post it?
>
> Regards,
>
> Anthony Liguori
Ok, how do you feel about this one?
My proposal is to always delete a memslot before reusing the space,
but controlling this behaviour by a flag, so we can maintain backwards
compatibility with people using older versions of the interface.
[-- Attachment #2: interface.patch --]
[-- Type: text/plain, Size: 3147 bytes --]
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index f18b86f..66ee286 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -39,6 +39,7 @@ struct kvm_userspace_memory_region {
/* for kvm_memory_region::flags */
#define KVM_MEM_LOG_DIRTY_PAGES 1UL
+#define KVM_MEM_FREE_BEFORE_ALLOC 2UL
/* for KVM_IRQ_LINE */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 4c39d4f..41f5666 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -735,24 +735,31 @@ int __kvm_set_memory_region(struct kvm *kvm,
base_gfn = mem->guest_phys_addr >> PAGE_SHIFT;
npages = mem->memory_size >> PAGE_SHIFT;
- if (!npages)
- mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
+
+ r = kvm_check_overlap(kvm, base_gfn, npages, memslot);
+ if (r)
+ goto out_free;
+
new = old = *memslot;
- new.base_gfn = base_gfn;
- new.npages = npages;
- new.flags = mem->flags;
+ if (!npages)
+ mem->flags &= ~KVM_MEM_LOG_DIRTY_PAGES;
- /* Disallow changing a memory slot's size. */
- r = -EINVAL;
- if (npages && old.npages && npages != old.npages)
- goto out_free;
- r = kvm_check_overlap(kvm, base_gfn, npages, memslot);
- if (r)
+ if (mem->flags & KVM_MEM_FREE_BEFORE_ALLOC)
+ kvm_free_physmem_slot(&new, NULL);
+
+ else {
+ /* Disallow changing a memory slot's size. */
+ r = -EINVAL;
+ if (npages && old.npages && npages != old.npages)
goto out_free;
+ }
+ new.base_gfn = base_gfn;
+ new.flags = mem->flags;
+ new.npages = npages;
/* Free page dirty bitmap if unneeded */
if (!(new.flags & KVM_MEM_LOG_DIRTY_PAGES))
@@ -771,6 +778,15 @@ int __kvm_set_memory_region(struct kvm *kvm,
memset(new.rmap, 0, npages * sizeof(*new.rmap));
new.user_alloc = user_alloc;
+ /*
+ * hva_to_rmmap() serialzies with the mmu_lock and to be
+ * safe it has to ignore memslots with !user_alloc &&
+ * !userspace_addr.
+ */
+ if (user_alloc)
+ new.userspace_addr = mem->userspace_addr;
+ else
+ new.userspace_addr = 0;
}
if (npages && !new.lpage_info) {
int largepages = npages / KVM_PAGES_PER_HPAGE;
@@ -791,15 +807,6 @@ int __kvm_set_memory_region(struct kvm *kvm,
if ((base_gfn+npages) % KVM_PAGES_PER_HPAGE)
new.lpage_info[largepages-1].write_count = 1;
}
- /*
- * hva_to_rmmap() serialzies with the mmu_lock and to be
- * safe it has to ignore memslots with !user_alloc &&
- * !userspace_addr.
- */
- if (npages && user_alloc)
- new.userspace_addr = mem->userspace_addr;
- else
- new.userspace_addr = 0;
/* Allocate page dirty bitmap if needed */
if ((new.flags & KVM_MEM_LOG_DIRTY_PAGES) && !new.dirty_bitmap) {
@@ -830,7 +837,9 @@ int __kvm_set_memory_region(struct kvm *kvm,
goto out_free;
}
- kvm_free_physmem_slot(&old, &new);
+
+ if (!(mem->flags & KVM_MEM_FREE_BEFORE_ALLOC))
+ kvm_free_physmem_slot(&old, &new);
#ifdef CONFIG_DMAR
/* map the pages in iommu page table */
r = kvm_iommu_map_pages(kvm, base_gfn, npages);
@@ -840,7 +849,9 @@ int __kvm_set_memory_region(struct kvm *kvm,
return 0;
out_free:
- kvm_free_physmem_slot(&new, &old);
+
+ if (!(mem->flags & KVM_MEM_FREE_BEFORE_ALLOC))
+ kvm_free_physmem_slot(&new, &old);
out:
return r;
next prev parent reply other threads:[~2008-11-19 20:51 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-18 3:04 [PATCH] always assign userspace_addr Glauber Costa
2008-11-19 15:55 ` Anthony Liguori
2008-11-19 18:43 ` Glauber Costa
2008-11-19 18:51 ` Anthony Liguori
2008-11-19 20:53 ` Glauber Costa [this message]
2008-11-19 20:59 ` Anthony Liguori
2008-11-20 11:01 ` Avi Kivity
2008-11-20 11:02 ` Avi Kivity
2008-11-21 18:11 ` Glauber Costa
2008-11-24 13:08 ` Glauber Costa
2008-11-25 14:04 ` 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=20081119205332.GA27378@poweredge.glommer \
--to=glommer@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@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