From: Andrew Jones <drjones@redhat.com>
To: kvmarm@lists.cs.columbia.edu, qemu-devel@nongnu.org,
ard.biesheuvel@linaro.org, christoffer.dall@linaro.org,
marc.zyngier@arm.com, peter.maydell@linaro.org
Cc: pbonzini@redhat.com, lersek@redhat.com, agraf@suse.de,
catalin.marinas@arm.com
Subject: [Qemu-devel] [RFC PATCH 5/6] KVM: ARM: implement kvm_*_incoherent_memory_regions
Date: Fri, 6 Mar 2015 13:52:32 -0500 [thread overview]
Message-ID: <1425667953-3566-6-git-send-email-drjones@redhat.com> (raw)
In-Reply-To: <1425667953-3566-1-git-send-email-drjones@redhat.com>
Add the kvm_*_incoherent_memory_regions calls to arm's
kvm_arch_vcpu_ioctl_run and implement the corresponding
arch flush/invalidate functions.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
arch/arm/include/uapi/asm/kvm.h | 1 +
arch/arm/kvm/arm.c | 4 +++
arch/arm/kvm/mmu.c | 54 +++++++++++++++++++++++++++++++++++++++
arch/arm64/include/uapi/asm/kvm.h | 1 +
4 files changed, 60 insertions(+)
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 09ee408c1a676..cb0898a995c4f 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -26,6 +26,7 @@
#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_INCOHERENT_MEM
#define KVM_REG_SIZE(id) \
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index c9e6ef1f7403a..789c03c84e7c0 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -486,6 +486,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
return ret;
}
+ kvm_flush_incoherent_memory_regions(vcpu->kvm);
+
if (vcpu->sigset_active)
sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
@@ -556,6 +558,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
ret = handle_exit(vcpu, run, ret);
}
+ kvm_invalidate_incoherent_memory_regions(vcpu->kvm);
+
if (vcpu->sigset_active)
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
return ret;
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 2f3a6581b9200..2f45db9cd436a 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1161,6 +1161,24 @@ static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
__coherent_cache_guest_page(pfn, size, need_flush, false);
}
+static void coherent_cache_memslot(struct kvm_memory_slot *slot, bool flush)
+{
+ gfn_t gfn, end = slot->base_gfn + slot->npages;
+ pfn_t pfn;
+
+ for (gfn = slot->base_gfn; gfn < end; ++gfn) {
+ pfn = gfn_to_pfn_memslot(slot, gfn);
+ if (is_error_pfn(pfn)) {
+ pr_err("%s: Bad pfn: gfn=%llx, pfn=%llx, "
+ "userspace_addr=%lx\n", __func__,
+ gfn, pfn, slot->userspace_addr);
+ continue;
+ }
+ __coherent_cache_guest_page(pfn, PAGE_SIZE, flush, !flush);
+ kvm_release_pfn_clean(pfn);
+ }
+}
+
static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
struct kvm_memory_slot *memslot, unsigned long hva,
unsigned long fault_status)
@@ -1802,6 +1820,42 @@ int kvm_arch_create_memslot(struct kvm *kvm, struct kvm_memory_slot *slot,
return 0;
}
+void kvm_arch_flush_incoherent(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+ if (slot->flags & KVM_MEM_READONLY) {
+ /*
+ * Readonly memory shouldn't be changing, and we do a
+ * clean+invalidate for KVM_MEM_INCOHERENT memory when
+ * faulting it in. So, there's nothing to do now.
+ */
+ return;
+ }
+
+ /*
+ * Ideally, we would further filter out all pages not touched by
+ * userspace on the last exit. No way to know those though, unless
+ * we force userspace to fault on all pages in the incoherent
+ * memory regions, but even then, I don't see any sane way for
+ * do_wp_page to handle the faults without modification. So, sigh...
+ */
+
+ coherent_cache_memslot(slot, true);
+}
+
+void kvm_arch_invalidate_incoherent(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+ if (slot->flags & KVM_MEM_LOG_DIRTY_PAGES) {
+ /*
+ * We fault each write when logging is enabled, and do a
+ * clean+invalidate on KVM_MEM_INCOHERENT memory while
+ * handling the fault. So, there's nothing to do now.
+ */
+ return;
+ }
+
+ coherent_cache_memslot(slot, false);
+}
+
void kvm_arch_memslots_updated(struct kvm *kvm)
{
}
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index 8e38878c87c61..29ddf77958c2a 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -38,6 +38,7 @@
#define __KVM_HAVE_GUEST_DEBUG
#define __KVM_HAVE_IRQ_LINE
#define __KVM_HAVE_READONLY_MEM
+#define __KVM_HAVE_INCOHERENT_MEM
#define KVM_REG_SIZE(id) \
(1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
--
1.8.3.1
next prev parent reply other threads:[~2015-03-06 18:52 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-06 18:49 [Qemu-devel] the arm cache coherency cluster Andrew Jones
2015-03-06 18:52 ` [Qemu-devel] [RFC PATCH 0/6] flush/invalidate on entry/exit Andrew Jones
2015-03-06 18:52 ` [Qemu-devel] [RFC PATCH 1/6] kvm: promote KVM_MEMSLOT_INCOHERENT to uapi Andrew Jones
2015-03-06 18:52 ` [Qemu-devel] [RFC PATCH 2/6] KVM: Introduce incoherent cache maintenance API Andrew Jones
2015-03-06 18:52 ` [Qemu-devel] [RFC PATCH 3/6] KVM: ARM: change __coherent_cache_guest_page interface Andrew Jones
2015-03-06 18:52 ` [Qemu-devel] [RFC PATCH 4/6] KVM: ARM: extend __coherent_cache_guest_page Andrew Jones
2015-03-06 18:52 ` Andrew Jones [this message]
2015-03-06 18:52 ` [Qemu-devel] [RFC PATCH 6/6] KVM: ARM: no need for kvm_arch_flush_incoherent Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [RFC PATCH 0/6] support KVM_MEM_INCOHERENT Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [RFC PATCH 1/6] memory: add incoherent cache flag Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [RFC PATCH 2/6] HACK: linux header update Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [PATCH 3/6] kvm-all: put kvm_mem_flags to more work Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [RFC PATCH 4/6] kvm-all: set KVM_MEM_INCOHERENT Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [RFC PATCH 5/6] vga: flag vram as incoherent Andrew Jones
2015-03-06 18:53 ` [Qemu-devel] [RFC/WIP PATCH 6/6] memory: add clear_cache_to_poc Andrew Jones
2015-03-11 19:21 ` Andrew Jones
2015-03-18 19:00 ` [Qemu-devel] the arm cache coherency cluster Andrew Jones
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=1425667953-3566-6-git-send-email-drjones@redhat.com \
--to=drjones@redhat.com \
--cc=agraf@suse.de \
--cc=ard.biesheuvel@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=christoffer.dall@linaro.org \
--cc=kvmarm@lists.cs.columbia.edu \
--cc=lersek@redhat.com \
--cc=marc.zyngier@arm.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.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;
as well as URLs for NNTP newsgroup(s).