[PATCH 09/50] KVM: Handle vma regions with no backing page



From: Anthony Liguori <aliguori@xxxxxxxxxx>

This patch allows VMAs that contain no backing page to be used for guest
memory. This is useful for assigning mmio regions to a guest.

Signed-off-by: Anthony Liguori <aliguori@xxxxxxxxxx>
Signed-off-by: Avi Kivity <avi@xxxxxxxxxxxx>
---
virt/kvm/kvm_main.c | 49 +++++++++++++++++++++++++++++++++++++------------
1 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 764d702..4d30ac5 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -532,6 +532,7 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
struct page *page[1];
unsigned long addr;
int npages;
+ pfn_t pfn;

might_sleep();

@@ -544,19 +545,38 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn)
npages = get_user_pages(current, current->mm, addr, 1, 1, 1, page,
NULL);

- if (npages != 1) {
- get_page(bad_page);
- return page_to_pfn(bad_page);
- }
+ if (unlikely(npages != 1)) {
+ struct vm_area_struct *vma;

- return page_to_pfn(page[0]);
+ vma = find_vma(current->mm, addr);
+ if (vma == NULL || addr < vma->vm_start ||
+ !(vma->vm_flags & VM_PFNMAP)) {
+ get_page(bad_page);
+ return page_to_pfn(bad_page);
+ }
+
+ pfn = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
+ BUG_ON(pfn_valid(pfn));
+ } else
+ pfn = page_to_pfn(page[0]);
+
+ return pfn;
}

EXPORT_SYMBOL_GPL(gfn_to_pfn);

struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
{
- return pfn_to_page(gfn_to_pfn(kvm, gfn));
+ pfn_t pfn;
+
+ pfn = gfn_to_pfn(kvm, gfn);
+ if (pfn_valid(pfn))
+ return pfn_to_page(pfn);
+
+ WARN_ON(!pfn_valid(pfn));
+
+ get_page(bad_page);
+ return bad_page;
}

EXPORT_SYMBOL_GPL(gfn_to_page);
@@ -569,7 +589,8 @@ EXPORT_SYMBOL_GPL(kvm_release_page_clean);

void kvm_release_pfn_clean(pfn_t pfn)
{
- put_page(pfn_to_page(pfn));
+ if (pfn_valid(pfn))
+ put_page(pfn_to_page(pfn));
}
EXPORT_SYMBOL_GPL(kvm_release_pfn_clean);

@@ -594,21 +615,25 @@ EXPORT_SYMBOL_GPL(kvm_set_page_dirty);

void kvm_set_pfn_dirty(pfn_t pfn)
{
- struct page *page = pfn_to_page(pfn);
- if (!PageReserved(page))
- SetPageDirty(page);
+ if (pfn_valid(pfn)) {
+ struct page *page = pfn_to_page(pfn);
+ if (!PageReserved(page))
+ SetPageDirty(page);
+ }
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_dirty);

void kvm_set_pfn_accessed(pfn_t pfn)
{
- mark_page_accessed(pfn_to_page(pfn));
+ if (pfn_valid(pfn))
+ mark_page_accessed(pfn_to_page(pfn));
}
EXPORT_SYMBOL_GPL(kvm_set_pfn_accessed);

void kvm_get_pfn(pfn_t pfn)
{
- get_page(pfn_to_page(pfn));
+ if (pfn_valid(pfn))
+ get_page(pfn_to_page(pfn));
}
EXPORT_SYMBOL_GPL(kvm_get_pfn);

--
1.5.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



Relevant Pages

  • Re: [9fans] THNX linux kernel
    ... That kernel must not have my patches, hmm, I will put my latest kernel ... /*P:100 This is the Launcher code, a simple program which lays out the ... then reads repeatedly from /dev/lguest to run the Guest. ... of the guest memory region. ...
    (comp.os.plan9)
  • Re: [RFC PATCH 0/4] (Take 2): transcendent memory ("tmem") for Linux
    ... Instead of getting an opaque handle from the hypervisor, I would force the guest to allocate it's own memory and to tell the hypervisor that it's a tmem pool. ... guest memory is that you don't introduce new challenges with respect to memory accounting. ...
    (Linux-Kernel)
  • RE: [RFC PATCH 0/4] (Take 2): transcendent memory ("tmem") for Linux
    ... the guest would have to be prepared to handle this. ... have more than 1GB of anonymous memory without swapping like mad. ... Swapping to tmem is fast but still a lot slower than having ... My worry is that tmem for kvm leaves a lot of niftiness on the table, ...
    (Linux-Kernel)
  • Re: [PATCHv5 3/3] vhost_net: a kernel-level virtio server
    ... Existing virtio net code is used in the guest without modification. ... structures can be moved around in memory at any time ... In this version I only support raw socket as a backend, ...
    (Linux-Kernel)
  • Re: [RFC][PATCH 2/7] RSS controller core
    ... and libraries) to allow for reduced memory ... the host system (but pages of over limit guests ... the guest, ... If you sum up the physpages values for all containers ...
    (Linux-Kernel)