]> git.ipfire.org Git - thirdparty/kernel/linux.git/blobdiff - arch/powerpc/kvm/book3s_hv.c
Merge tag 'powerpc-5.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[thirdparty/kernel/linux.git] / arch / powerpc / kvm / book3s_hv.c
index 33be4d93248af9e1b7dd7f071779c3049219048d..93493f0cbfe8e94b81d1f06b00f1218dfb8d6d73 100644 (file)
@@ -72,7 +72,6 @@
 #include <asm/xics.h>
 #include <asm/xive.h>
 #include <asm/hw_breakpoint.h>
-#include <asm/kvm_host.h>
 #include <asm/kvm_book3s_uvmem.h>
 #include <asm/ultravisor.h>
 
@@ -1074,25 +1073,35 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu)
                                         kvmppc_get_gpr(vcpu, 6));
                break;
        case H_SVM_PAGE_IN:
-               ret = kvmppc_h_svm_page_in(vcpu->kvm,
-                                          kvmppc_get_gpr(vcpu, 4),
-                                          kvmppc_get_gpr(vcpu, 5),
-                                          kvmppc_get_gpr(vcpu, 6));
+               ret = H_UNSUPPORTED;
+               if (kvmppc_get_srr1(vcpu) & MSR_S)
+                       ret = kvmppc_h_svm_page_in(vcpu->kvm,
+                                                  kvmppc_get_gpr(vcpu, 4),
+                                                  kvmppc_get_gpr(vcpu, 5),
+                                                  kvmppc_get_gpr(vcpu, 6));
                break;
        case H_SVM_PAGE_OUT:
-               ret = kvmppc_h_svm_page_out(vcpu->kvm,
-                                           kvmppc_get_gpr(vcpu, 4),
-                                           kvmppc_get_gpr(vcpu, 5),
-                                           kvmppc_get_gpr(vcpu, 6));
+               ret = H_UNSUPPORTED;
+               if (kvmppc_get_srr1(vcpu) & MSR_S)
+                       ret = kvmppc_h_svm_page_out(vcpu->kvm,
+                                                   kvmppc_get_gpr(vcpu, 4),
+                                                   kvmppc_get_gpr(vcpu, 5),
+                                                   kvmppc_get_gpr(vcpu, 6));
                break;
        case H_SVM_INIT_START:
-               ret = kvmppc_h_svm_init_start(vcpu->kvm);
+               ret = H_UNSUPPORTED;
+               if (kvmppc_get_srr1(vcpu) & MSR_S)
+                       ret = kvmppc_h_svm_init_start(vcpu->kvm);
                break;
        case H_SVM_INIT_DONE:
-               ret = kvmppc_h_svm_init_done(vcpu->kvm);
+               ret = H_UNSUPPORTED;
+               if (kvmppc_get_srr1(vcpu) & MSR_S)
+                       ret = kvmppc_h_svm_init_done(vcpu->kvm);
                break;
        case H_SVM_INIT_ABORT:
-               ret = kvmppc_h_svm_init_abort(vcpu->kvm);
+               ret = H_UNSUPPORTED;
+               if (kvmppc_get_srr1(vcpu) & MSR_S)
+                       ret = kvmppc_h_svm_init_abort(vcpu->kvm);
                break;
 
        default:
@@ -3611,6 +3620,7 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit,
                if (trap == BOOK3S_INTERRUPT_SYSCALL && !vcpu->arch.nested &&
                    kvmppc_get_gpr(vcpu, 3) == H_CEDE) {
                        kvmppc_nested_cede(vcpu);
+                       kvmppc_set_gpr(vcpu, 3, 0);
                        trap = 0;
                }
        } else {
@@ -4395,7 +4405,7 @@ static int kvm_vm_ioctl_get_dirty_log_hv(struct kvm *kvm,
        slots = kvm_memslots(kvm);
        memslot = id_to_memslot(slots, log->slot);
        r = -ENOENT;
-       if (!memslot->dirty_bitmap)
+       if (!memslot || !memslot->dirty_bitmap)
                goto out;
 
        /*
@@ -4442,29 +4452,26 @@ out:
        return r;
 }
 
-static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *free,
-                                       struct kvm_memory_slot *dont)
+static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *slot)
 {
-       if (!dont || free->arch.rmap != dont->arch.rmap) {
-               vfree(free->arch.rmap);
-               free->arch.rmap = NULL;
-       }
+       vfree(slot->arch.rmap);
+       slot->arch.rmap = NULL;
 }
 
-static int kvmppc_core_create_memslot_hv(struct kvm_memory_slot *slot,
-                                        unsigned long npages)
+static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
+                                       struct kvm_memory_slot *slot,
+                                       const struct kvm_userspace_memory_region *mem,
+                                       enum kvm_mr_change change)
 {
-       slot->arch.rmap = vzalloc(array_size(npages, sizeof(*slot->arch.rmap)));
-       if (!slot->arch.rmap)
-               return -ENOMEM;
+       unsigned long npages = mem->memory_size >> PAGE_SHIFT;
 
-       return 0;
-}
+       if (change == KVM_MR_CREATE) {
+               slot->arch.rmap = vzalloc(array_size(npages,
+                                         sizeof(*slot->arch.rmap)));
+               if (!slot->arch.rmap)
+                       return -ENOMEM;
+       }
 
-static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm,
-                                       struct kvm_memory_slot *memslot,
-                                       const struct kvm_userspace_memory_region *mem)
-{
        return 0;
 }
 
@@ -4553,11 +4560,6 @@ void kvmppc_update_lpcr(struct kvm *kvm, unsigned long lpcr, unsigned long mask)
        }
 }
 
-static void kvmppc_mmu_destroy_hv(struct kvm_vcpu *vcpu)
-{
-       return;
-}
-
 void kvmppc_setup_partition_table(struct kvm *kvm)
 {
        unsigned long dw0, dw1;
@@ -5421,6 +5423,21 @@ static void unpin_vpa_reset(struct kvm *kvm, struct kvmppc_vpa *vpa)
        vpa->update_pending = 0;
 }
 
+/*
+ * Enable a guest to become a secure VM, or test whether
+ * that could be enabled.
+ * Called when the KVM_CAP_PPC_SECURE_GUEST capability is
+ * tested (kvm == NULL) or enabled (kvm != NULL).
+ */
+static int kvmhv_enable_svm(struct kvm *kvm)
+{
+       if (!kvmppc_uvmem_available())
+               return -EINVAL;
+       if (kvm)
+               kvm->arch.svm_enabled = 1;
+       return 0;
+}
+
 /*
  *  IOCTL handler to turn off secure mode of guest
  *
@@ -5521,9 +5538,7 @@ static struct kvmppc_ops kvm_ops_hv = {
        .age_hva  = kvm_age_hva_hv,
        .test_age_hva = kvm_test_age_hva_hv,
        .set_spte_hva = kvm_set_spte_hva_hv,
-       .mmu_destroy  = kvmppc_mmu_destroy_hv,
        .free_memslot = kvmppc_core_free_memslot_hv,
-       .create_memslot = kvmppc_core_create_memslot_hv,
        .init_vm =  kvmppc_core_init_vm_hv,
        .destroy_vm = kvmppc_core_destroy_vm_hv,
        .get_smmu_info = kvm_vm_ioctl_get_smmu_info_hv,
@@ -5543,6 +5558,7 @@ static struct kvmppc_ops kvm_ops_hv = {
        .enable_nested = kvmhv_enable_nested,
        .load_from_eaddr = kvmhv_load_from_eaddr,
        .store_to_eaddr = kvmhv_store_to_eaddr,
+       .enable_svm = kvmhv_enable_svm,
        .svm_off = kvmhv_svm_off,
 };