]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Changes to common header files not applicable to open-vm-tools.
authorJohn Wolfe <jwolfe@vmware.com>
Fri, 9 Jul 2021 03:10:23 +0000 (20:10 -0700)
committerJohn Wolfe <jwolfe@vmware.com>
Fri, 9 Jul 2021 03:10:23 +0000 (20:10 -0700)
open-vm-tools/lib/include/vm_basic_asm.h
open-vm-tools/lib/include/vm_basic_asm_arm64.h
open-vm-tools/lib/include/vm_basic_asm_x86_common.h

index 23af5ef7c9f786c1f0867402b281368a2f0bbdca..bd651d2fc8f9a8e210f1bc8f7459b6212dfde38c 100644 (file)
@@ -1259,6 +1259,79 @@ PopCount64(uint64 value)
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * INTR_R_BARRIER_R --
+ * INTR_R_BARRIER_W --
+ * INTR_R_BARRIER_RW --
+ * INTR_W_BARRIER_R --
+ * INTR_W_BARRIER_W --
+ * INTR_W_BARRIER_RW --
+ * INTR_RW_BARRIER_R --
+ * INTR_RW_BARRIER_W --
+ * INTR_RW_BARRIER_RW --
+ *
+ *      Enforce ordering on memory operations witnessed by and
+ *      affected by interrupt handlers.
+ *
+ *      This should be used to replace the legacy COMPILER_*_BARRIER
+ *      for code that has been audited to determine it only needs
+ *      ordering with respect to interrupt handlers, and not to other
+ *      CPUs (SMP_*), memory-mapped I/O (MMIO_*), or DMA (DMA_*).
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#ifdef __GNUC__
+
+static INLINE void
+INTR_RW_BARRIER_RW(void)
+{
+   __asm__ __volatile__("" ::: "memory");
+}
+
+#define INTR_R_BARRIER_R INTR_RW_BARRIER_RW
+#define INTR_R_BARRIER_W INTR_RW_BARRIER_RW
+#define INTR_R_BARRIER_RW INTR_RW_BARRIER_RW
+#define INTR_W_BARRIER_R INTR_RW_BARRIER_RW
+#define INTR_W_BARRIER_W INTR_RW_BARRIER_RW
+#define INTR_W_BARRIER_RW INTR_RW_BARRIER_RW
+#define INTR_RW_BARRIER_R INTR_RW_BARRIER_RW
+#define INTR_RW_BARRIER_W INTR_RW_BARRIER_RW
+
+#elif defined _MSC_VER
+
+static INLINE void
+INTR_R_BARRIER_R(void)
+{
+   _ReadBarrier();
+}
+
+static INLINE void
+INTR_W_BARRIER_W(void)
+{
+   _WriteBarrier();
+}
+
+static INLINE void
+INTR_RW_BARRIER_RW(void)
+{
+   _ReadWriteBarrier();
+}
+
+#define INTR_R_BARRIER_W INTR_RW_BARRIER_RW
+#define INTR_R_BARRIER_RW INTR_RW_BARRIER_RW
+#define INTR_W_BARRIER_R INTR_RW_BARRIER_RW
+#define INTR_W_BARRIER_RW INTR_RW_BARRIER_RW
+#define INTR_RW_BARRIER_R INTR_RW_BARRIER_RW
+#define INTR_RW_BARRIER_W INTR_RW_BARRIER_RW
+
+#else
+#error No compiler defined for INTR_*_BARRIER_*
+#endif
+
+
 #if defined __cplusplus
 } // extern "C"
 #endif
index 4a3ecb68073e65ce5e77bd43d9d31ffcf7493400..ae59511d454a750a5fc1ef6308bc70cc1cb6fedc 100644 (file)
@@ -181,12 +181,22 @@ ESB(void)
  * accesses accross the barrier. It is not a CPU instruction, it is a compiler
  * directive (i.e. it does not emit any code).
  *
+ * => A compiler memory barrier on its own is useful for coordinating
+ *    with an interrupt handler (or preemption logic in the scheduler)
+ *    on the same CPU, so that the order of read and write
+ *    instructions in code that might be interrupted is consistent
+ *    with the barriers. But when there are other CPUs involved, or
+ *    other types of devices like memory-mapped I/O and DMA
+ *    controllers, a compiler memory barrier is not enough.
+ *
  * A CPU memory barrier prevents the CPU from re-ordering memory accesses
  * accross the barrier. It is a CPU instruction.
  *
+ * => On its own the CPU instruction isn't useful because the compiler
+ *    may reorder loads and stores around the CPU instruction.  It is
+ *    useful only when combined with a compiler memory barrier.
+ *
  * A memory barrier is the union of a compiler memory barrier and a CPU memory
- * barrier. A compiler memory barrier is a useless construct by itself. It is
- * only useful when combined with a CPU memory barrier, to implement a memory
  * barrier.
  *
  *    Semantics
@@ -228,7 +238,7 @@ ESB(void)
  * <mem_type/purpose>_<before_access_type>_BARRIER_<after_access_type>
  *
  * where:
- *   <mem_type/purpose> is either SMP, DMA, or MMIO.
+ *   <mem_type/purpose> is either INTR, SMP, DMA, or MMIO.
  *   <*_access type> is either R(load), W(store) or RW(any).
  *
  * Above every use of these memory barriers in the code, there _must_ be a
index 590b1ce3fa1657807d599c811bded2da9f73a4f5..ed64082167b5aa47d14935122bc508a7418a2b6d 100644 (file)
@@ -410,12 +410,22 @@ LOCKED_INSN_BARRIER(void)
  * accesses accross the barrier. It is not a CPU instruction, it is a compiler
  * directive (i.e. it does not emit any code).
  *
+ * => A compiler memory barrier on its own is useful for coordinating
+ *    with an interrupt handler (or preemption logic in the scheduler)
+ *    on the same CPU, so that the order of read and write
+ *    instructions in code that might be interrupted is consistent
+ *    with the barriers. But when there are other CPUs involved, or
+ *    other types of devices like memory-mapped I/O and DMA
+ *    controllers, a compiler memory barrier is not enough.
+ *
  * A CPU memory barrier prevents the CPU from re-ordering memory accesses
  * accross the barrier. It is a CPU instruction.
  *
+ * => On its own the CPU instruction isn't useful because the compiler
+ *    may reorder loads and stores around the CPU instruction.  It is
+ *    useful only when combined with a compiler memory barrier.
+ *
  * A memory barrier is the union of a compiler memory barrier and a CPU memory
- * barrier. A compiler memory barrier is a useless construct by itself. It is
- * only useful when combined with a CPU memory barrier, to implement a memory
  * barrier.
  *
  *    Semantics
@@ -463,12 +473,11 @@ LOCKED_INSN_BARRIER(void)
  * <mem_type/purpose>_<before_access_type>_BARRIER_<after_access_type>
  *
  * where:
- *   <mem_type/purpose> is either SMP, DMA, or MMIO.
+ *   <mem_type/purpose> is either INTR, SMP, DMA, or MMIO.
  *   <*_access type> is either R(load), W(store) or RW(any).
  *
  * Above every use of these memory barriers in the code, there _must_ be a
  * comment to justify the use, i.e. a comment which:
- *
  * 1) Precisely identifies which memory accesses must not be re-ordered across
  *    the memory barrier.
  * 2) Explains why it is important that the memory accesses not be re-ordered.