summaryrefslogtreecommitdiff
path: root/arch/x86/machine/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/machine/cpu.h')
-rw-r--r--arch/x86/machine/cpu.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/arch/x86/machine/cpu.h b/arch/x86/machine/cpu.h
index 14ed73cb..4413c61f 100644
--- a/arch/x86/machine/cpu.h
+++ b/arch/x86/machine/cpu.h
@@ -204,6 +204,11 @@ struct cpu_tss {
} __packed;
/*
+ * Forward declaration.
+ */
+struct tcb;
+
+/*
* CPU states.
*/
#define CPU_STATE_OFF 0
@@ -217,6 +222,7 @@ struct cpu_tss {
struct cpu {
struct cpu *self;
+ struct tcb *tcb;
unsigned int id;
unsigned int apic_id;
char vendor_id[CPU_VENDOR_ID_SIZE];
@@ -419,6 +425,28 @@ cpu_current(void)
return cpu;
}
+/*
+ * The current TCB must be obtained and updated in a migration-safe way.
+ */
+static __always_inline struct tcb *
+cpu_tcb(void)
+{
+ struct tcb *tcb;
+
+ asm volatile("mov %%fs:%1, %0"
+ : "=r" (tcb)
+ : "m" (*(char *)offsetof(struct cpu, tcb)));
+
+ return tcb;
+}
+
+static __always_inline void
+cpu_set_tcb(struct tcb *tcb)
+{
+ asm volatile("mov %0, %%fs:%1"
+ : : "r" (tcb), "m" (*(char *)offsetof(struct cpu, tcb)));
+}
+
static __always_inline unsigned int
cpu_id(void)
{