Merge branches 'pm-cpufreq', 'pm-sleep' and 'pm-em'
[linux-2.6-microblaze.git] / arch / arm64 / kvm / hyp / include / nvhe / spinlock.h
index 76b537f..4652fd0 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <asm/alternative.h>
 #include <asm/lse.h>
+#include <asm/rwonce.h>
 
 typedef union hyp_spinlock {
        u32     __val;
@@ -89,4 +90,28 @@ static inline void hyp_spin_unlock(hyp_spinlock_t *lock)
        : "memory");
 }
 
+static inline bool hyp_spin_is_locked(hyp_spinlock_t *lock)
+{
+       hyp_spinlock_t lockval = READ_ONCE(*lock);
+
+       return lockval.owner != lockval.next;
+}
+
+#ifdef CONFIG_NVHE_EL2_DEBUG
+static inline void hyp_assert_lock_held(hyp_spinlock_t *lock)
+{
+       /*
+        * The __pkvm_init() path accesses protected data-structures without
+        * holding locks as the other CPUs are guaranteed to not enter EL2
+        * concurrently at this point in time. The point by which EL2 is
+        * initialized on all CPUs is reflected in the pkvm static key, so
+        * wait until it is set before checking the lock state.
+        */
+       if (static_branch_likely(&kvm_protected_mode_initialized))
+               BUG_ON(!hyp_spin_is_locked(lock));
+}
+#else
+static inline void hyp_assert_lock_held(hyp_spinlock_t *lock) { }
+#endif
+
 #endif /* __ARM64_KVM_NVHE_SPINLOCK_H__ */