Skip to content

Instantly share code, notes, and snippets.

@ricarkol
Created May 3, 2019 20:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricarkol/bc9395bb43d18c22e20249dcaca488d8 to your computer and use it in GitHub Desktop.
Save ricarkol/bc9395bb43d18c22e20249dcaca488d8 to your computer and use it in GitHub Desktop.
diff --git a/bindings/cpu_aarch64.h b/bindings/cpu_aarch64.h
index f1514aa..4afd5dd 100644
--- a/bindings/cpu_aarch64.h
+++ b/bindings/cpu_aarch64.h
@@ -69,7 +69,7 @@ static inline uint64_t mul64_32(uint64_t a, uint32_t b, uint8_t s)
}
#endif /* !ASM_FILE */
-static inline void cpu_set_tls_base(uint64_t base)
+__attribute__((always_inline)) static inline void cpu_set_tls_base(uint64_t base)
{
__asm__ __volatile("msr tpidr_el0, %0" :: "r"(base));
}
diff --git a/bindings/cpu_x86_64.h b/bindings/cpu_x86_64.h
index 4d13829..0924169 100644
--- a/bindings/cpu_x86_64.h
+++ b/bindings/cpu_x86_64.h
@@ -225,7 +225,7 @@ static inline uint64_t inq(uint16_t port_lo)
return ((uint64_t)lo) | ((uint64_t)hi << 32);
}
-static inline void cpu_set_tls_base(uint64_t base)
+__attribute__((always_inline)) static inline void cpu_set_tls_base(uint64_t base)
{
__asm__ __volatile("wrmsr" ::
"c" (0xc0000100), /* IA32_FS_BASE */
diff --git a/bindings/crt_init.h b/bindings/crt_init.h
index 425490a..9e58bdd 100644
--- a/bindings/crt_init.h
+++ b/bindings/crt_init.h
@@ -28,50 +28,6 @@ extern uintptr_t SSP_GUARD;
#error Unsupported architecture
#endif
-/*
- * These functions are responsible for performing early initialisation required
- * by the "C runtime". They must be inlined as early as possible once in C
- * code, before calling any other functions. The calling function must not
- * return.
- *
- * As crt_init_tls() currently requires that the bindings are running in CPU
- * Ring 0 or equivalent, this is split into a separate function so that
- * bindings such as "spt" can omit the call.
- */
-
-__attribute__((always_inline)) static inline void crt_init_tls(void)
-{
- /*
- * Explicitly disable any accidental use of TLS by zeroing the relevant
- * CPU registers, thus causing TLS access to point to the zero page.
- *
- * On x86_64 these MSRs "should" technically be zero on hvt VM entry, but
- * this is not actually specified anywhere. For virtio the bootloader
- * and/or platform may have likewise clobbered the values.
- *
- * On aarch64 the defaults seen in practice on KVM appear to be garbage
- * values. Note that we are running at EL1, but based on practical
- * investigation TPIDR_EL0 is the register that the compiler would use to
- * point to TLS.
- */
-#if defined(__x86_64__)
- __asm__ __volatile("wrmsr" ::
- "c" (0xc0000100), /* IA32_FS_BASE */
- "a" (0x0),
- "d" (0x0)
- );
- __asm__ __volatile("wrmsr" ::
- "c" (0xc0000101), /* IA32_GS_BASE */
- "a" (0x0),
- "d" (0x0)
- );
-#elif defined(__aarch64__)
- __asm__ __volatile("msr tpidr_el0, xzr");
-#else
-#error Unsupported architecture
-#endif
-}
-
__attribute__((always_inline)) static inline void crt_init_ssp(void)
{
/*
diff --git a/bindings/hvt/bindings.h b/bindings/hvt/bindings.h
index 08624bf..613bb57 100644
--- a/bindings/hvt/bindings.h
+++ b/bindings/hvt/bindings.h
@@ -42,4 +42,9 @@ uint64_t tscclock_epochoffset(void);
void process_bootinfo(void *arg);
+__attribute__((always_inline)) static inline void crt_init_tls(void)
+{
+ cpu_set_tls_base(0);
+}
+
#endif /* __HVT_BINDINGS_H__ */
diff --git a/bindings/spt/bindings.c b/bindings/spt/bindings.c
index 318f2cb..181dbb5 100644
--- a/bindings/spt/bindings.c
+++ b/bindings/spt/bindings.c
@@ -49,6 +49,6 @@ solo5_time_t solo5_clock_wall(void)
solo5_result_t solo5_set_tls_base(uintptr_t base)
{
- int rc = platform_set_arch_tls_base(base);
+ int rc = platform_set_tls_base(base);
return (rc == 0) ? SOLO5_R_OK : SOLO5_R_EINVAL;
}
diff --git a/bindings/spt/bindings.h b/bindings/spt/bindings.h
index 323ed3c..25b54be 100644
--- a/bindings/spt/bindings.h
+++ b/bindings/spt/bindings.h
@@ -69,7 +69,7 @@ long sys_arch_prctl(long code, long addr);
void block_init(struct spt_boot_info *arg);
void net_init(struct spt_boot_info *arg);
-int platform_set_arch_tls_base(uint64_t base);
-void platform_init_tls(void);
+int platform_set_tls_base(uint64_t base);
+void crt_init_tls(void);
#endif /* __SPT_BINDINGS_H__ */
diff --git a/bindings/spt/platform.c b/bindings/spt/platform.c
index d46ff27..d300715 100644
--- a/bindings/spt/platform.c
+++ b/bindings/spt/platform.c
@@ -52,7 +52,7 @@ int platform_puts(const char *buf, int n)
return n;
}
-int platform_set_arch_tls_base(uint64_t base)
+int platform_set_tls_base(uint64_t base)
{
#if defined(__x86_64__)
/* In x86 we need to ask the host kernel to change %fs for us. */
@@ -65,8 +65,8 @@ int platform_set_arch_tls_base(uint64_t base)
#endif
}
-void platform_init_tls(void)
+void crt_init_tls(void)
{
- int rc = platform_set_arch_tls_base(0);
+ int rc = platform_set_tls_base(0);
assert(rc == 0);
}
diff --git a/bindings/spt/start.c b/bindings/spt/start.c
index bb0b94b..86136b7 100644
--- a/bindings/spt/start.c
+++ b/bindings/spt/start.c
@@ -23,7 +23,7 @@
void _start(void *arg)
{
- platform_init_tls();
+ crt_init_tls();
crt_init_ssp();
static struct solo5_start_info si;
diff --git a/bindings/virtio/bindings.h b/bindings/virtio/bindings.h
index 3c51e2c..09b8e66 100644
--- a/bindings/virtio/bindings.h
+++ b/bindings/virtio/bindings.h
@@ -69,4 +69,9 @@ void virtio_net_pkt_put(void); /* we're done with recv'd data */
int virtio_net_xmit_packet(const void *data, size_t len);
int virtio_net_pkt_poll(void); /* test if packet(s) are available */
+__attribute__((always_inline)) static inline void crt_init_tls(void)
+{
+ cpu_set_tls_base(0);
+}
+
#endif /* __VIRTIO_BINDINGS_H__ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment