device-dax: Avoid an unnecessary check in alloc_dev_dax_range()
[linux-2.6-microblaze.git] / kernel / time / vsyscall.c
index 54ce6eb..88e6b8e 100644 (file)
@@ -13,6 +13,8 @@
 #include <vdso/helpers.h>
 #include <vdso/vsyscall.h>
 
+#include "timekeeping_internal.h"
+
 static inline void update_vdso_data(struct vdso_data *vdata,
                                    struct timekeeper *tk)
 {
@@ -127,3 +129,42 @@ void update_vsyscall_tz(void)
 
        __arch_sync_vdso_data(vdata);
 }
+
+/**
+ * vdso_update_begin - Start of a VDSO update section
+ *
+ * Allows architecture code to safely update the architecture specific VDSO
+ * data. Disables interrupts, acquires timekeeper lock to serialize against
+ * concurrent updates from timekeeping and invalidates the VDSO data
+ * sequence counter to prevent concurrent readers from accessing
+ * inconsistent data.
+ *
+ * Returns: Saved interrupt flags which need to be handed in to
+ * vdso_update_end().
+ */
+unsigned long vdso_update_begin(void)
+{
+       struct vdso_data *vdata = __arch_get_k_vdso_data();
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&timekeeper_lock, flags);
+       vdso_write_begin(vdata);
+       return flags;
+}
+
+/**
+ * vdso_update_end - End of a VDSO update section
+ * @flags:     Interrupt flags as returned from vdso_update_begin()
+ *
+ * Pairs with vdso_update_begin(). Marks vdso data consistent, invokes data
+ * synchronization if the architecture requires it, drops timekeeper lock
+ * and restores interrupt flags.
+ */
+void vdso_update_end(unsigned long flags)
+{
+       struct vdso_data *vdata = __arch_get_k_vdso_data();
+
+       vdso_write_end(vdata);
+       __arch_sync_vdso_data(vdata);
+       raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
+}