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

On Tue, 2019-03-19 at 17:53 +1100, Alexey Kardashevskiy wrote:
> 
> On 19/03/2019 15:04, Suraj Jitindar Singh wrote:
> > 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)
> 
> 
> What is the "_many" suffix about?

It made sense in the context of virt/kvm/kvm_main.c, maybe less so now
I moved it to PPC code.

> 
> 
> > +{
> > +	int size = min(PAGE_SIZE - offset1, PAGE_SIZE - offset2);
> 
> Nitpicking :) Here it is min()...
> 
> > +
> > +	if (len > size)
> > +		return size;
> > +	else
> > +		return len;
> 
> ...but here it is if() when it could also be min() (or may be
> min_t()).

Very true

> 
> 
> > +}
> > +
> > +static int kvmppc_copy_guest(struct kvm *kvm, gpa_t to, gpa_t
> > from,
> > +			     unsigned long len)
> 
> 
> This does not compile (most comments are made just because I had to
> reply anyway):
> 
> /home/aik/p/kernel/arch/powerpc/kvm/book3s_hv.c:835:12: error:
> ‘kvmppc_copy_guest’ defined but not used [-Werror=unused-function]
>  static int kvmppc_copy_guest(struct kvm *kvm, gpa_t to, gpa_t from,
>             ^~~~~~~~~~~~~~~~~
> 
> imho 1/3 and 2/3 should be one patch.
> 
> A general comment is that the H_PAGE_INIT hcall description says "The
> logical addresses ... must both point to the start of a 4 K system
> memory page" so the loop will never have to execute more than once,
> cannot span memslots  => it could be lot simpler then, or I missed
> something here (unlikely, after reading 3/3).

Yeah I think I'll roll 1/3 and 2/3 into one and only handle 4K pages
for now.

> 
> 
> > +{
> > +	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);
> 
> 
> Nit: if you made mark_page_dirty_in_slot() public (yeah it is in the
> common code), you could save here one search through memslots.

Yeah, given we store the most recent memslot and check it first, I
think the overhead is negligible. You are correct though.

> 
> 
> > +
> > +		to_offset = (to_offset + seg) & (PAGE_SIZE - 1);
> 
> 
> s/(PAGE_SIZE - 1)/~PAGE_MASK/ ? Or even use again that
> offset_in_page()
> as you did above?
> 
> 
> > +		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;
> > 
> 
> 

      parent reply	other threads:[~2019-03-22  4:23 UTC|newest]

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