]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
x86: Document per-CPU data subsystem
authorJan Kiszka <jan.kiszka@siemens.com>
Wed, 24 Sep 2014 21:59:39 +0000 (23:59 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 25 Sep 2014 13:51:33 +0000 (15:51 +0200)
Document the x86-specific per-CPU data structure and accessors. This is
a temporary solution until we factored out generic bits.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/include/asm/percpu.h

index 2b78509831e100869f7f61c602d00d446dfae673..dc15ea538febc354218d29bd76745d2473416d14 100644 (file)
 #include <asm/spinlock.h>
 #include <asm/vmx.h>
 
+/**
+ * @defgroup Per-CPU Per-CPU Subsystem
+ *
+ * The per-CPU subsystem provides a CPU-local state structure and accessors.
+ *
+ * @{
+ */
+
+/** Per-CPU states. */
 struct per_cpu {
        /* Keep these two in sync with defines above! */
+       /** Stack used while in hypervisor mode. */
        u8 stack[PAGE_SIZE];
+       /** Linux stack pointer, used for handover to hypervisor. */
        unsigned long linux_sp;
 
+       /** Self reference, required for this_cpu_data(). */
        struct per_cpu *cpu_data;
+       /** Logical CPU ID (same as Linux). */
        unsigned int cpu_id;
+       /** Physical APIC ID. */
        u32 apic_id;
+       /** Owning cell. */
        struct cell *cell;
 
+       /** Statistic counters. */
        u32 stats[JAILHOUSE_NUM_CPU_STATS];
 
+       /** Linux states, used for handover to/from hypervisor. @{ */
        struct desc_table_reg linux_gdtr;
        struct desc_table_reg linux_idtr;
        unsigned long linux_reg[NUM_ENTRY_REGS];
@@ -59,36 +76,66 @@ struct per_cpu {
        unsigned long linux_sysenter_cs;
        unsigned long linux_sysenter_eip;
        unsigned long linux_sysenter_esp;
+       /** @} */
+       /** True when CPU is initialized by hypervisor. */
        bool initialized;
+       /** VMX initialization state. */
        enum vmx_state vmx_state;
 
-       /*
-        * protects the following per_cpu fields (unless CPU is stopped):
-        *  - suspend_cpu
-        *  - cpu_suspended (except for spinning on it to become true)
-        *  - wait_for_sipi
-        *  - init_signaled
-        *  - sipi_vector
-        *  - flush_caches
+       /**
+        * Lock protecting CPU state changes done for control tasks.
+        *
+        * The lock protects the following fields (unless CPU is suspended):
+        * @li per_cpu::suspend_cpu
+        * @li per_cpu::cpu_suspended (except for spinning on it to become
+        *                             true)
+        * @li per_cpu::wait_for_sipi
+        * @li per_cpu::init_signaled
+        * @li per_cpu::sipi_vector
+        * @li per_cpu::flush_virt_caches
         */
        spinlock_t control_lock;
 
+       /** Set to true for instructing the CPU to suspend. */
        volatile bool suspend_cpu;
+       /** True if CPU is waiting for SIPI. */
        volatile bool wait_for_sipi;
+       /** True if CPU is suspended. */
        volatile bool cpu_suspended;
+       /** Set to true for pending an INIT signal. */
        bool init_signaled;
+       /** Pending SIPI vector; -1 if none is pending. */
        int sipi_vector;
+       /** Set to true for pending a flush of guest-related CPU caches. */
        bool flush_virt_caches;
+       /** Set to true for instructing the CPU to disable hypervisor mode. */
        bool shutdown_cpu;
+       /** State of the shutdown process. Possible values:
+        * @li SHUTDOWN_NONE: no shutdown in progress
+        * @li SHUTDOWN_STARTED: shutdown in progress
+        * @li negative error code: shutdown failed
+        */
        int shutdown_state;
+       /** True if CPU violated a cell boundary or cause some other failure in
+        * guest mode. */
        bool failed;
 
+       /** Number of iterations to clear pending APIC IRQs. */
        unsigned int num_clear_apic_irqs;
 
+       /** VMXON region, required by VMX. */
        struct vmcs vmxon_region __attribute__((aligned(PAGE_SIZE)));
+       /** VMCS of this CPU, required by VMX. */
        struct vmcs vmcs __attribute__((aligned(PAGE_SIZE)));
 } __attribute__((aligned(PAGE_SIZE)));
 
+/**
+ * Define CPU-local accessor for a per-CPU field.
+ * @param field                Field name.
+ *
+ * The accessor will have the form of a function, returning the correspondingly
+ * typed field value: @c this_field().
+ */
 #define DEFINE_PER_CPU_ACCESSOR(field)                                     \
 static inline typeof(((struct per_cpu *)0)->field) this_##field(void)      \
 {                                                                          \
@@ -101,10 +148,36 @@ static inline typeof(((struct per_cpu *)0)->field) this_##field(void)         \
        return tmp;                                                         \
 }
 
+/**
+ * Retrieve the data structure of the current CPU.
+ *
+ * @return Pointer to per-CPU data structure.
+ */
+static inline struct per_cpu *this_cpu_data(void);
 DEFINE_PER_CPU_ACCESSOR(cpu_data)
+
+/**
+ * Retrieve the ID of the current CPU.
+ *
+ * @return CPU ID.
+ */
+static inline unsigned int this_cpu_id(void);
 DEFINE_PER_CPU_ACCESSOR(cpu_id)
+
+/**
+ * Retrieve the cell owning the current CPU.
+ *
+ * @return Pointer to cell.
+ */
+static inline struct cell *this_cell(void);
 DEFINE_PER_CPU_ACCESSOR(cell)
 
+/**
+ * Retrieve the data structure of the specified CPU.
+ * @param cpu  ID of the target CPU.
+ *
+ * @return Pointer to per-CPU data structure.
+ */
 static inline struct per_cpu *per_cpu(unsigned int cpu)
 {
        struct per_cpu *cpu_data;
@@ -117,6 +190,8 @@ static inline struct per_cpu *per_cpu(unsigned int cpu)
        return cpu_data;
 }
 
+/** @} **/
+
 /* Validate defines */
 #define CHECK_ASSUMPTION(assume)       ((void)sizeof(char[1 - 2*!(assume)]))