All of lore.kernel.org
 help / color / mirror / Atom feed
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
To: kvm-ppc@vger.kernel.org
Subject: [PATCH 1/3] KVM: PPC: Implement kvmppc_copy_guest() to perform in place copy of guest memory
Date: Tue, 19 Mar 2019 04:04:33 +0000	[thread overview]
Message-ID: <20190319040435.10716-1-sjitindarsingh@gmail.com> (raw)

Implement the function kvmppc_copy_guest() to be used to perform a memory
copy from one guest physical address to another of a variable length.

This performs similar functionality as the kvm_read_guest() and
kvm_write_guest() functions, except both addresses point to guest memory.
This performs a copy in place using raw_copy_in_user() to avoid having to
buffer the data.

The guest memory can reside in different memslots and the copy length
can span memslots.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 arch/powerpc/kvm/book3s_hv.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index ec38576dc685..7179ea783f4f 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -814,6 +814,75 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags,
 	}
 }
 
+static int __kvmppc_copy_guest_page(struct kvm_memory_slot *to_memslot,
+				    gfn_t to_gfn, int to_offset,
+				    struct kvm_memory_slot *from_memslot,
+				    gfn_t from_gfn, int from_offset, int len)
+{
+	int r;
+	unsigned long to_addr, from_addr;
+
+	to_addr = gfn_to_hva_memslot(to_memslot, to_gfn);
+	if (kvm_is_error_hva(to_addr))
+		return -EFAULT;
+	from_addr = gfn_to_hva_memslot(from_memslot, from_gfn);
+	if (kvm_is_error_hva(from_addr))
+		return -EFAULT;
+	r = raw_copy_in_user((void __user *)to_addr + to_offset,
+			     (void __user *)from_addr + from_offset, len);
+	if (r)
+		return -EFAULT;
+	return 0;
+}
+
+static int next_segment_many(unsigned long len, int offset1, int offset2)
+{
+	int size = min(PAGE_SIZE - offset1, PAGE_SIZE - offset2);
+
+	if (len > size)
+		return size;
+	else
+		return len;
+}
+
+static int kvmppc_copy_guest(struct kvm *kvm, gpa_t to, gpa_t from,
+			     unsigned long len)
+{
+	struct kvm_memory_slot *to_memslot = NULL;
+	struct kvm_memory_slot *from_memslot = NULL;
+	gfn_t to_gfn = to >> PAGE_SHIFT;
+	gfn_t from_gfn = from >> PAGE_SHIFT;
+	int seg;
+	int to_offset = offset_in_page(to);
+	int from_offset = offset_in_page(from);
+	int ret;
+
+	while ((seg = next_segment_many(len, to_offset, from_offset)) != 0) {
+		if (!to_memslot || (to_gfn >= (to_memslot->base_gfn +
+					       to_memslot->npages)))
+			to_memslot = gfn_to_memslot(kvm, to_gfn);
+		if (!from_memslot || (from_gfn >= (from_memslot->base_gfn +
+						   from_memslot->npages)))
+			from_memslot = gfn_to_memslot(kvm, from_gfn);
+
+		ret = __kvmppc_copy_guest_page(to_memslot, to_gfn, to_offset,
+					       from_memslot, from_gfn,
+					       from_offset, seg);
+		if (ret < 0)
+			return ret;
+		mark_page_dirty(kvm, to_gfn);
+
+		to_offset = (to_offset + seg) & (PAGE_SIZE - 1);
+		from_offset = (from_offset + seg) & (PAGE_SIZE - 1);
+		len -= seg;
+		if (!to_offset)
+			to_gfn += 1;
+		if (!from_offset)
+			from_gfn += 1;
+	}
+	return 0;
+}
+
 static int kvm_arch_vcpu_yield_to(struct kvm_vcpu *target)
 {
 	struct kvmppc_vcore *vcore = target->arch.vcore;
-- 
2.13.6

             reply	other threads:[~2019-03-19  4:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-19  4:04 Suraj Jitindar Singh [this message]
2019-03-19  6:53 ` [PATCH 1/3] KVM: PPC: Implement kvmppc_copy_guest() to perform in place copy of guest memory Alexey Kardashevskiy
2019-03-22  4:23 ` Suraj Jitindar Singh

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=20190319040435.10716-1-sjitindarsingh@gmail.com \
    --to=sjitindarsingh@gmail.com \
    --cc=kvm-ppc@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.