* [PATCH v2 1/2] KVM: PPC: Book3S HV: Implement virtual mode H_PAGE_INIT handler
@ 2019-03-22 6:05 Suraj Jitindar Singh
2019-04-30 9:59 ` Paul Mackerras
0 siblings, 1 reply; 3+ messages in thread
From: Suraj Jitindar Singh @ 2019-03-22 6:05 UTC (permalink / raw)
To: kvm-ppc
Implement a virtual mode handler for the H_CALL H_PAGE_INIT which can be
used to zero or copy a guest page. The page is defined to be 4k and must
be 4k aligned.
The in-kernel handler halves the time to handle this H_CALL compared to
handling it in userspace for a radix guest.
Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
V1 -> V2:
- Rolled the patch to introduce kvmppc_copy_guest() into this one
- kvmppc_copy_guest() can only copy within a memslot
- Use SZ_4K for page size
- Use long for hcall return params
- Only perform copy or zero not both, and reorder so copy done if both set
---
arch/powerpc/kvm/book3s_hv.c | 80 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index ec38576dc685..0e17b255ee30 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -814,6 +814,80 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags,
}
}
+/* Copy guest memory in place - must reside within a single memslot */
+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;
+ unsigned long to_addr, from_addr;
+ int r;
+
+ /* Get HPA for from address */
+ from_memslot = gfn_to_memslot(kvm, from >> PAGE_SHIFT);
+ if (!from_memslot)
+ return -EFAULT;
+ if ((from + len) >= ((from_memslot->base_gfn + from_memslot->npages)
+ << PAGE_SHIFT))
+ return -EINVAL;
+ from_addr = gfn_to_hva_memslot(from_memslot, from >> PAGE_SHIFT);
+ if (kvm_is_error_hva(from_addr))
+ return -EFAULT;
+ from_addr |= (from & (PAGE_SIZE - 1));
+
+ /* Get HPA for to address */
+ to_memslot = gfn_to_memslot(kvm, to >> PAGE_SHIFT);
+ if (!to_memslot)
+ return -EFAULT;
+ if ((to + len) >= ((to_memslot->base_gfn + to_memslot->npages)
+ << PAGE_SHIFT))
+ return -EINVAL;
+ to_addr = gfn_to_hva_memslot(to_memslot, to >> PAGE_SHIFT);
+ if (kvm_is_error_hva(to_addr))
+ return -EFAULT;
+ to_addr |= (to & (PAGE_SIZE - 1));
+
+ /* Perform copy */
+ r = raw_copy_in_user((void __user *)to_addr, (void __user *)from_addr,
+ len);
+ if (r)
+ return -EFAULT;
+ mark_page_dirty(kvm, to >> PAGE_SHIFT);
+ return 0;
+}
+
+static long kvmppc_h_page_init(struct kvm_vcpu *vcpu, unsigned long flags,
+ unsigned long dest, unsigned long src)
+{
+ u64 pg_sz = SZ_4K; /* 4K page size */
+ u64 pg_mask = SZ_4K - 1;
+ int ret;
+
+ /* Check for invalid flags (H_PAGE_SET_LOANED covers all CMO flags) */
+ if (flags & ~(H_ICACHE_INVALIDATE | H_ICACHE_SYNCHRONIZE |
+ H_ZERO_PAGE | H_COPY_PAGE | H_PAGE_SET_LOANED))
+ return H_PARAMETER;
+
+ /* dest (and src if copy_page flag set) must be page aligned */
+ if ((dest & pg_mask) || ((flags & H_COPY_PAGE) && (src & pg_mask)))
+ return H_PARAMETER;
+
+ /* zero and/or copy the page as determined by the flags */
+ if (flags & H_COPY_PAGE) {
+ ret = kvmppc_copy_guest(vcpu->kvm, dest, src, pg_sz);
+ if (ret < 0)
+ return H_PARAMETER;
+ } else if (flags & H_ZERO_PAGE) {
+ ret = kvm_clear_guest(vcpu->kvm, dest, pg_sz);
+ if (ret < 0)
+ return H_PARAMETER;
+ }
+
+ /* We can ignore the remaining flags */
+
+ return H_SUCCESS;
+}
+
static int kvm_arch_vcpu_yield_to(struct kvm_vcpu *target)
{
struct kvmppc_vcore *vcore = target->arch.vcore;
@@ -1014,6 +1088,11 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
if (nesting_enabled(vcpu->kvm))
ret = kvmhv_copy_tofrom_guest_nested(vcpu);
break;
+ case H_PAGE_INIT:
+ ret = kvmppc_h_page_init(vcpu, kvmppc_get_gpr(vcpu, 4),
+ kvmppc_get_gpr(vcpu, 5),
+ kvmppc_get_gpr(vcpu, 6));
+ break;
default:
return RESUME_HOST;
}
@@ -1058,6 +1137,7 @@ static int kvmppc_hcall_impl_hv(unsigned long cmd)
case H_IPOLL:
case H_XIRR_X:
#endif
+ case H_PAGE_INIT:
return 1;
}
--
2.13.6
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH v2 1/2] KVM: PPC: Book3S HV: Implement virtual mode H_PAGE_INIT handler
2019-03-22 6:05 [PATCH v2 1/2] KVM: PPC: Book3S HV: Implement virtual mode H_PAGE_INIT handler Suraj Jitindar Singh
@ 2019-04-30 9:59 ` Paul Mackerras
0 siblings, 0 replies; 3+ messages in thread
From: Paul Mackerras @ 2019-04-30 9:59 UTC (permalink / raw)
To: Suraj Jitindar Singh; +Cc: kvm-ppc, kvm
On Fri, Mar 22, 2019 at 05:05:44PM +1100, Suraj Jitindar Singh wrote:
> Implement a virtual mode handler for the H_CALL H_PAGE_INIT which can be
> used to zero or copy a guest page. The page is defined to be 4k and must
> be 4k aligned.
>
> The in-kernel handler halves the time to handle this H_CALL compared to
> handling it in userspace for a radix guest.
>
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Thanks, both patches applied to my kvm-ppc-next tree.
Paul.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH v2 1/2] KVM: PPC: Book3S HV: Implement virtual mode H_PAGE_INIT handler
@ 2019-04-30 9:59 ` Paul Mackerras
0 siblings, 0 replies; 3+ messages in thread
From: Paul Mackerras @ 2019-04-30 9:59 UTC (permalink / raw)
To: Suraj Jitindar Singh; +Cc: kvm-ppc, kvm
On Fri, Mar 22, 2019 at 05:05:44PM +1100, Suraj Jitindar Singh wrote:
> Implement a virtual mode handler for the H_CALL H_PAGE_INIT which can be
> used to zero or copy a guest page. The page is defined to be 4k and must
> be 4k aligned.
>
> The in-kernel handler halves the time to handle this H_CALL compared to
> handling it in userspace for a radix guest.
>
> Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Thanks, both patches applied to my kvm-ppc-next tree.
Paul.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2019-04-30 10:12 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-22 6:05 [PATCH v2 1/2] KVM: PPC: Book3S HV: Implement virtual mode H_PAGE_INIT handler Suraj Jitindar Singh
2019-04-30 9:59 ` Paul Mackerras
2019-04-30 9:59 ` Paul Mackerras
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.