[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT/UNIKRAFT PATCH 2/2] Temporary workaround to have atomic operations working on ARM64 baremetal





On 15/01/2020 10:58, Santiago Pagani wrote:
At the moment atomic operations are working on ARM64 for KVM, however,
they are not working on baremetal on ARM64 (i.e., on the Raspberry Pi 3B+).
This can be most likely be solved by enabling the
caches and setting up a compatible memory configuration.

Hold on, how do you use Unikraft on RPI at the moment? Don't you have MMU enabled and therefore cache setup?

In the mean time, this compile guard allows us to have functionally-equivalent
non-atomic implementations of the gcc builtins working on baremetal on ARM64.
Once the issue is fixed, then this workaround can be removed.

Setting up the cache is not that difficult to do. The more the code should be exactly the same (aside memory addresses) as for the KVM port here.

I would strongly recommend to consider whether this is wise to try to rush a port for RPI in Unikraft.

Cheers,


Signed-off-by: Santiago Pagani <santiagopagani@xxxxxxxxx>
---
  include/uk/arch/atomic.h | 47 ++++++++++++++++++++++++++++++++++++++++
  1 file changed, 47 insertions(+)

diff --git a/include/uk/arch/atomic.h b/include/uk/arch/atomic.h
index 6fae1762..0c76b33a 100644
--- a/include/uk/arch/atomic.h
+++ b/include/uk/arch/atomic.h
@@ -41,20 +41,37 @@ extern "C" {
  /**
   * Perform a atomic load operation.
   */
+// #TODO: This (and the other compile guards in this file for 
CONFIG_PLAT_RASPI) is a workaround until we get proper
+// atomic operations working on ARM64 baremetal.
+// Mainly, whenever we try to execute a ldaxr or stlxr instruction on 
baremetal with the current memory configuration,
+// the CPU simply hangs. This should be fixed by enabling the caches and/or 
setting up a compatible memory configuration.
+#if CONFIG_PLAT_RASPI
+#define ukarch_load_n(src)             (*(src))
+#else
  #define ukarch_load_n(src) \
        __atomic_load_n(src, __ATOMIC_SEQ_CST)
+#endif
+
/**
   * Perform a atomic store operation.
   */
+#if CONFIG_PLAT_RASPI
+#define ukarch_store_n(src, value)     ((*(src)) = value)
+#else
  #define ukarch_store_n(src, value) \
        __atomic_store_n(src, value, __ATOMIC_SEQ_CST)
+#endif
/**
   * Perform a atomic fetch and add operation.
   */
+#if CONFIG_PLAT_RASPI
+#define ukarch_fetch_add(src, value)   ((*(src))++)
+#else
  #define ukarch_fetch_add(src, value) \
        __atomic_fetch_add(src, value, __ATOMIC_SEQ_CST)
+#endif
/**
   * Perform a atomic increment/decrement operation and return the
@@ -62,20 +79,49 @@ extern "C" {
   */
  #define ukarch_inc(src) \
        ukarch_fetch_add(src, 1)
+#if CONFIG_PLAT_RASPI
+#define ukarch_dec(src)                ((*(src))--)
+#else
  #define ukarch_dec(src) \
        __atomic_fetch_sub(src, 1, __ATOMIC_SEQ_CST)
+#endif
+
  /**
   * Writes *src into *dst, and returns the previous contents of *dst.
   */
+#if CONFIG_PLAT_RASPI
+#define ukarch_exchange(dst, src)              \
+       ({                                                                      
\
+               __typeof__(*dst) prev = *dst;   \
+               *dst = *src;                                    \
+               prev;                                                   \
+       })
+#else
  #define ukarch_exchange(dst, src) \
        __atomic_exchange(dst, src, __ATOMIC_SEQ_CST)
+#endif
/**
   * Writes v into *dst, and returns the previous contents of *dst.
   */
+#if CONFIG_PLAT_RASPI
+#define ukarch_exchange_n(dst, v)              \
+       ({                                                                      
\
+               __typeof__(*dst) prev = *dst;   \
+               *dst = v;                                               \
+               prev;                                                   \
+       })
+#else
  #define ukarch_exchange_n(dst, v) \
        __atomic_exchange_n(dst, v, __ATOMIC_SEQ_CST)
+#endif
+#if CONFIG_PLAT_RASPI
+#define ukarch_compare_exchange_sync(ptr, old, new)                            
                \
+       ({                                                                      
                                                                \
+               (*ptr == old) ? (*ptr = new) : old;                             
                                \
+       })
+#else
  #define ukarch_compare_exchange_sync(ptr, old, new)                           
 \
        ({                                                                     \
                __typeof__(*ptr) stored = old;                                 \
@@ -84,6 +130,7 @@ extern "C" {
                    ? new                                                      \
                    : old;                                                     \
        })
+#endif
#ifdef __cplusplus
  }


--
Julien Grall

_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.