KVM: PPC: Add load_from_eaddr and store_to_eaddr to the kvmppc_ops struct
authorSuraj Jitindar Singh <sjitindarsingh@gmail.com>
Fri, 14 Dec 2018 05:29:06 +0000 (16:29 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Mon, 17 Dec 2018 00:33:50 +0000 (11:33 +1100)
The kvmppc_ops struct is used to store function pointers to kvm
implementation specific functions.

Introduce two new functions load_from_eaddr and store_to_eaddr to be
used to load from and store to a guest effective address respectively.

Also implement these for the kvm-hv module. If we are using the radix
mmu then we can call the functions to access quadrant 1 and 2.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/kvm/book3s_hv.c

index 04c5b84df83dc9bbac1e7bb95cc7b131a4a0c371..eb0d79f0ca45784fdbf1c8ef126cd432b8a9f551 100644 (file)
@@ -328,6 +328,10 @@ struct kvmppc_ops {
                            unsigned long flags);
        void (*giveup_ext)(struct kvm_vcpu *vcpu, ulong msr);
        int (*enable_nested)(struct kvm *kvm);
+       int (*load_from_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
+                              int size);
+       int (*store_to_eaddr)(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
+                             int size);
 };
 
 extern struct kvmppc_ops *kvmppc_hv_ops;
index 074ff5b314c9e9ec314710e3b018b9d8f3dd7d9d..cef57b68dda1862603f9821fc021ca13638e8ea2 100644 (file)
@@ -5237,6 +5237,44 @@ static int kvmhv_enable_nested(struct kvm *kvm)
        return 0;
 }
 
+static int kvmhv_load_from_eaddr(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
+                                int size)
+{
+       int rc = -EINVAL;
+
+       if (kvmhv_vcpu_is_radix(vcpu)) {
+               rc = kvmhv_copy_from_guest_radix(vcpu, *eaddr, ptr, size);
+
+               if (rc > 0)
+                       rc = -EINVAL;
+       }
+
+       /* For now quadrants are the only way to access nested guest memory */
+       if (rc && vcpu->arch.nested)
+               rc = -EAGAIN;
+
+       return rc;
+}
+
+static int kvmhv_store_to_eaddr(struct kvm_vcpu *vcpu, ulong *eaddr, void *ptr,
+                               int size)
+{
+       int rc = -EINVAL;
+
+       if (kvmhv_vcpu_is_radix(vcpu)) {
+               rc = kvmhv_copy_to_guest_radix(vcpu, *eaddr, ptr, size);
+
+               if (rc > 0)
+                       rc = -EINVAL;
+       }
+
+       /* For now quadrants are the only way to access nested guest memory */
+       if (rc && vcpu->arch.nested)
+               rc = -EAGAIN;
+
+       return rc;
+}
+
 static struct kvmppc_ops kvm_ops_hv = {
        .get_sregs = kvm_arch_vcpu_ioctl_get_sregs_hv,
        .set_sregs = kvm_arch_vcpu_ioctl_set_sregs_hv,
@@ -5277,6 +5315,8 @@ static struct kvmppc_ops kvm_ops_hv = {
        .get_rmmu_info = kvmhv_get_rmmu_info,
        .set_smt_mode = kvmhv_set_smt_mode,
        .enable_nested = kvmhv_enable_nested,
+       .load_from_eaddr = kvmhv_load_from_eaddr,
+       .store_to_eaddr = kvmhv_store_to_eaddr,
 };
 
 static int kvm_init_subcore_bitmap(void)