KVM: arm64: Add ioctl to fetch/store tags in a guest
[linux-2.6-microblaze.git] / arch / arm64 / kvm / arm.c
index 1cb39c0..511f371 100644 (file)
@@ -93,6 +93,12 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
                r = 0;
                kvm->arch.return_nisv_io_abort_to_user = true;
                break;
+       case KVM_CAP_ARM_MTE:
+               if (!system_supports_mte() || kvm->created_vcpus)
+                       return -EINVAL;
+               r = 0;
+               kvm->arch.mte_enabled = true;
+               break;
        default:
                r = -EINVAL;
                break;
@@ -237,6 +243,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
                 */
                r = 1;
                break;
+       case KVM_CAP_ARM_MTE:
+               r = system_supports_mte();
+               break;
        case KVM_CAP_STEAL_TIME:
                r = kvm_arm_pvtime_supported();
                break;
@@ -720,11 +729,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
                        return ret;
        }
 
-       if (run->immediate_exit)
-               return -EINTR;
-
        vcpu_load(vcpu);
 
+       if (run->immediate_exit) {
+               ret = -EINTR;
+               goto out;
+       }
+
        kvm_sigset_activate(vcpu);
 
        ret = 1;
@@ -897,6 +908,18 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 
        kvm_sigset_deactivate(vcpu);
 
+out:
+       /*
+        * In the unlikely event that we are returning to userspace
+        * with pending exceptions or PC adjustment, commit these
+        * adjustments in order to give userspace a consistent view of
+        * the vcpu state. Note that this relies on __kvm_adjust_pc()
+        * being preempt-safe on VHE.
+        */
+       if (unlikely(vcpu->arch.flags & (KVM_ARM64_PENDING_EXCEPTION |
+                                        KVM_ARM64_INCREMENT_PC)))
+               kvm_call_hyp(__kvm_adjust_pc, vcpu);
+
        vcpu_put(vcpu);
        return ret;
 }
@@ -1336,6 +1359,13 @@ long kvm_arch_vm_ioctl(struct file *filp,
 
                return 0;
        }
+       case KVM_ARM_MTE_COPY_TAGS: {
+               struct kvm_arm_copy_mte_tags copy_tags;
+
+               if (copy_from_user(&copy_tags, argp, sizeof(copy_tags)))
+                       return -EFAULT;
+               return kvm_vm_ioctl_mte_copy_tags(kvm, &copy_tags);
+       }
        default:
                return -EINVAL;
        }