From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
To: kvm-ppc@vger.kernel.org
Subject: Re: [PATCH 1/2] KVM: Implement kvm_copy_guest() to perform copy of guest memory in place
Date: Fri, 22 Mar 2019 02:33:39 +0000 [thread overview]
Message-ID: <1553222019.21249.0.camel@gmail.com> (raw)
In-Reply-To: <20190306060016.18733-1-sjitindarsingh@gmail.com>
On Thu, 2019-03-21 at 07:34 -0700, Sean Christopherson wrote:
> On Thu, Mar 07, 2019 at 10:18:05AM +1100, Suraj Jitindar Singh wrote:
> > On Wed, 2019-03-06 at 09:21 -0800, Sean Christopherson wrote:
> > > On Wed, Mar 06, 2019 at 05:00:15PM +1100, Suraj Jitindar Singh
> > > wrote:
> > > > Implement the function kvm_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>
> > > >
> > > > ---
> > > >
> > > > I suspect additional checking may be required around the
> > > > raw_copy_in_user()
> > > > call.
> > > >
> > > > ---
> > > > include/linux/kvm_host.h | 1 +
> > > > virt/kvm/kvm_main.c | 69
> > > > ++++++++++++++++++++++++++++++++++++++++++++++++
> > > > 2 files changed, 70 insertions(+)
> > > >
> > >
> > > ...
> > >
> > > > +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;
> > > > +}
> > > > +
> > > > +int kvm_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_memslo
> > > > t-
> > > > > npages)))
> > > >
> > > > + from_memslot = gfn_to_memslot(kvm,
> > > > from_gfn);
> > > > +
> > > > + ret = __kvm_copy_guest_page(to_memslot,
> > > > to_gfn,
> > > > to_offset,
> > > > + from_memslot,
> > > > from_gfn, from_offset,
> > > > + seg);
> > > > + if (ret < 0)
> > > > + return ret;
> > > > +
> > > > + 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;
> > > > +}
> > > > +EXPORT_SYMBOL_GPL(kvm_copy_guest);
> > >
> > > Is there a need to support spanning multiple pages at this
> > > time? Your use
> > > case always accesses exactly a page and requires both dst and src
> > > to
> > > be
> > > page aligned. I.e. provide just kvm_copy_guest_page() for
> > > simplicity.
> >
> > There is no need for multiple pages at this stage. However I wanted
> > to
> > match kvm_[read/write]_guest which allow multiple pages and there
> > didn't seem any reason to not just implement it this way from the
> > start.
>
> From a correctness standpoint, the multi-page version is quite
> difficult
> to comprehend and review, e.g. no matter how long I stare at this
> code
> I doubt I'll ever be 100% certain that it correctly handles every
> corner
> case (not saying it doesn't :-) ).
Sure, I'll drop this patch
prev parent reply other threads:[~2019-03-22 2:33 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-06 6:00 [PATCH 1/2] KVM: Implement kvm_copy_guest() to perform copy of guest memory in place Suraj Jitindar Singh
2019-03-06 14:12 ` kbuild test robot
2019-03-06 17:21 ` Sean Christopherson
2019-03-06 18:28 ` kbuild test robot
2019-03-06 23:18 ` Suraj Jitindar Singh
2019-03-21 14:34 ` Sean Christopherson
2019-03-22 2:33 ` Suraj Jitindar Singh [this message]
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=1553222019.21249.0.camel@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.