]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core: Document control subsystem
authorJan Kiszka <jan.kiszka@siemens.com>
Wed, 24 Sep 2014 08:01:53 +0000 (10:01 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Thu, 25 Sep 2014 13:49:30 +0000 (15:49 +0200)
This adds doxygen-style documentation for public parts of the control
subsystem.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
hypervisor/arch/x86/control.c
hypervisor/control.c
hypervisor/include/jailhouse/control.h
hypervisor/pci.c

index 438861f015fb3b2d74da598446783ddd972753eb..e0c0ec970a7aad28b557ece596c23c1431ae7f5b 100644 (file)
@@ -153,7 +153,6 @@ void arch_resume_cpu(unsigned int cpu_id)
        per_cpu(cpu_id)->stop_cpu = false;
 }
 
-/* target cpu has to be stopped */
 void arch_reset_cpu(unsigned int cpu_id)
 {
        per_cpu(cpu_id)->sipi_vector = APIC_BSP_PSEUDO_SIPI;
@@ -161,7 +160,6 @@ void arch_reset_cpu(unsigned int cpu_id)
        arch_resume_cpu(cpu_id);
 }
 
-/* target cpu has to be stopped */
 void arch_park_cpu(unsigned int cpu_id)
 {
        per_cpu(cpu_id)->init_signaled = true;
@@ -174,12 +172,6 @@ void arch_shutdown_cpu(unsigned int cpu_id)
        arch_suspend_cpu(cpu_id);
        per_cpu(cpu_id)->shutdown_cpu = true;
        arch_resume_cpu(cpu_id);
-       /*
-        * Note: The caller has to ensure that the target CPU has enough time
-        * to reach the shutdown position before destroying the code path it
-        * has to take to get there. This can be ensured by bringing the CPU
-        * online again under Linux before cleaning up the hypervisor.
-        */
 }
 
 void x86_send_init_sipi(unsigned int cpu_id, enum x86_init_sipi type,
index b723c877821417bec1f457e552a3835be02db299..97789d09364eca4869058ea85d9ca4c3515f99cf 100644 (file)
@@ -24,6 +24,7 @@ enum msg_type {MSG_REQUEST, MSG_INFORMATION};
 enum failure_mode {ABORT_ON_ERROR, WARN_ON_ERROR};
 enum management_task {CELL_START, CELL_SET_LOADABLE, CELL_DESTROY};
 
+/** System configuration as used while activating the hypervisor. */
 struct jailhouse_system *system_config;
 
 static DEFINE_SPINLOCK(shutdown_lock);
@@ -33,6 +34,17 @@ static unsigned int num_cells = 1;
 #define for_each_non_root_cell(c) \
        for ((c) = root_cell.next; (c); (c) = (c)->next)
 
+/**
+ * CPU set iterator.
+ * @param cpu          Previous CPU ID.
+ * @param cpu_set      CPU set to iterate over.
+ * @param exception    CPU ID to skip if it is contained.
+ *
+ * @return Next CPU ID in the set.
+ *
+ * @note For internal use only. Use for_each_cpu() or for_each_cpu_except()
+ * instead.
+ */
 unsigned int next_cpu(unsigned int cpu, struct cpu_set *cpu_set, int exception)
 {
        do
@@ -42,6 +54,13 @@ unsigned int next_cpu(unsigned int cpu, struct cpu_set *cpu_set, int exception)
        return cpu;
 }
 
+/**
+ * Check if a CPU ID is contained in the system's CPU set, i.e. the initial CPU
+ * set of the root cell.
+ * @param cpu_id       CPU ID to check.
+ *
+ * @return True if CPU ID is valid.
+ */
 bool cpu_id_valid(unsigned long cpu_id)
 {
        const unsigned long *system_cpu_set =
@@ -68,15 +87,16 @@ static void cell_resume(struct per_cpu *cpu_data)
 }
 
 /**
- * cell_send_message - Deliver a message to cell and wait for the reply
- * @cell: target cell
- * @message: message code to be sent (JAILHOUSE_MSG_*)
- * @type: message type, defines the valid replies
+ * Deliver a message to cell and wait for the reply.
+ * @param cell         Target cell.
+ * @param message      Message code to be sent (JAILHOUSE_MSG_*).
+ * @param type         Message type, defines the valid replies.
  *
- * Returns true if a request message was approved or reception of an
- * information message was acknowledged by the target cell. It also return true
- * of the target cell does not support a communication region, is shut down or
- * in failed state. Return false on request denial or invalid replies.
+ * @return True if a request message was approved or reception of an
+ *        informational message was acknowledged by the target cell. It also
+ *        returns true if the target cell does not support an active
+ *        communication region, is shut down or in failed state. Returns
+ *        false on request denial or invalid replies.
  */
 static bool cell_send_message(struct cell *cell, u32 message,
                              enum msg_type type)
@@ -143,7 +163,14 @@ retry:
        return id;
 }
 
-/* cell must be zero-initialized */
+/**
+ * Initialize a new cell.
+ * @param cell Cell to be initializes.
+ *
+ * @return 0 on success, negative error code otherwise.
+ *
+ * @note The cell data structure must be zero-initialized.
+ */
 int cell_init(struct cell *cell)
 {
        const unsigned long *config_cpu_set =
@@ -176,6 +203,16 @@ static void destroy_cpu_set(struct cell *cell)
                page_free(&mem_pool, cell->cpu_set, 1);
 }
 
+/**
+ * Perform basic validation of cell memory regions.
+ * @param config       Cell configuration description.
+ *
+ * @return 0 if the regions are valid, @c -EINVAL if the validation failed.
+ *
+ * Checks performed on the memory regions are:
+ * \li Page alignment of physical and virtual address and the size.
+ * \li Use of supported flags only.
+ */
 int check_mem_regions(const struct jailhouse_cell_desc *config)
 {
        const struct jailhouse_memory *mem =
@@ -719,6 +756,16 @@ static int cpu_get_info(struct per_cpu *cpu_data, unsigned long cpu_id,
                return -EINVAL;
 }
 
+/**
+ * Handle hypercall invoked by a cell.
+ * @param code         Hypercall code.
+ * @param arg1         First hypercall argument.
+ * @param arg2         Seconds hypercall argument.
+ *
+ * @return Value that shall be passed to the caller of the hypercall on return.
+ *
+ * @note If @c arg1 and @c arg2 are valid depends on the hypercall code.
+ */
 long hypercall(unsigned long code, unsigned long arg1, unsigned long arg2)
 {
        struct per_cpu *cpu_data = this_cpu_data();
@@ -747,6 +794,15 @@ long hypercall(unsigned long code, unsigned long arg1, unsigned long arg2)
        }
 }
 
+/**
+ * Stops the current CPU on panic and prevents any execution on it until the
+ * system is rebooted.
+ *
+ * @note This service should be used when facing an unrecoverable error of the
+ * hypervisor.
+ *
+ * @see panic_park
+ */
 void panic_stop(void)
 {
        panic_printk("Stopping CPU %d (Cell: \"%s\")\n", this_cpu_id(),
@@ -759,6 +815,15 @@ void panic_stop(void)
        arch_panic_stop();
 }
 
+/**
+ * Parks the current CPU on panic, allowing to restart it by resetting the
+ * cell's CPU state.
+ *
+ * @note This service should be used when facing an error of a cell CPU, e.g. a
+ * cell boundary violation.
+ *
+ * @see panic_stop
+ */
 void panic_park(void)
 {
        struct cell *cell = this_cell();
index 268bec50991e69e2ca5c87dc2e9b9e5cad3ead82..3a2362dfa0c25df28203d68ff0db0559fc6b1156 100644 (file)
 #define SHUTDOWN_NONE                  0
 #define SHUTDOWN_STARTED               1
 
+/**
+ * @defgroup Control Control Subsystem
+ *
+ * The control subsystem provides services for managing cells and the
+ * hypervisor during runtime. It implements the hypercall interface and
+ * performs the required access control and parameter validation for it.
+ *
+ * @{
+ */
+
 extern struct jailhouse_system *system_config;
 
 unsigned int next_cpu(unsigned int cpu, struct cpu_set *cpu_set,
                      int exception);
 
+/**
+ * Loop-generating macro for iterating over all CPUs in a set.
+ * @param cpu          Iteration variable holding the current CPU ID
+ *                     (unsigned int).
+ * @param set          CPU set to iterate over (struct cpu_set).
+ *
+ * @see for_each_cpu_except
+ */
 #define for_each_cpu(cpu, set)                                 \
        for ((cpu) = -1;                                        \
             (cpu) = next_cpu((cpu), (set), -1),                \
             (cpu) <= (set)->max_cpu_id;                        \
            )
 
+/**
+ * Loop-generating macro for iterating over all CPUs in a set, except the
+ * specified one.
+ * @param cpu          Iteration variable holding the current CPU ID
+ *                     (unsigned int).
+ * @param set          CPU set to iterate over (struct cpu_set).
+ * @param exception    CPU to skip if it is part of the set.
+ *
+* @see for_each_cpu
+ */
 #define for_each_cpu_except(cpu, set, exception)               \
        for ((cpu) = -1;                                        \
             (cpu) = next_cpu((cpu), (set), (exception)),       \
             (cpu) <= (set)->max_cpu_id;                        \
            )
 
+/**
+ * Check if the CPU is assigned to the specified cell.
+ * @param cell         Cell the CPU may belong to.
+ * @param cpu_id       ID of the CPU.
+ *
+ * @return True if the CPU is assigned to the cell.
+ */
 static inline bool cell_owns_cpu(struct cell *cell, unsigned int cpu_id)
 {
        return (cpu_id <= cell->cpu_set->max_cpu_id &&
@@ -50,23 +85,160 @@ long hypercall(unsigned long code, unsigned long arg1, unsigned long arg2);
 void __attribute__((noreturn)) panic_stop(void);
 void panic_park(void);
 
+/**
+ * Suspend a remote CPU.
+ * @param cpu_id       ID of the target CPU.
+ *
+ * Suspension means that the target CPU is no longer executing cell code or
+ * arbitrary hypervisor code. It may actively wait in the hypervisor context,
+ * so the suspension time should be kept short.
+ *
+ * The function waits for the target CPU to enter suspended state.
+ *
+ * This service can be used to synchronize with other CPUs before performing
+ * management tasks.
+ *
+ * @note This function must not be invoked for the caller's CPU.
+ *
+ * @see arch_resume_cpu
+ * @see arch_reset_cpu
+ * @see arch_park_cpu
+ */
 void arch_suspend_cpu(unsigned int cpu_id);
+
+/**
+ * Resume a suspended remote CPU.
+ * @param cpu_id       ID of the target CPU.
+ *
+ * @note This function must not be invoked for the caller's CPU.
+ *
+ * @see arch_suspend_cpu
+ */
 void arch_resume_cpu(unsigned int cpu_id);
+
+/**
+ * Reset a suspended remote CPU and resumes its execution.
+ * @param cpu_id       ID of the target CPU.
+ *
+ * Sets the target CPU into the architecture-specific reset set and resumes its
+ * execution.
+ *
+ * @note This function must not be invoked for the caller's CPU or if the
+ * target CPU is not in suspend state.
+ *
+ * @see arch_suspend_cpu
+ */
 void arch_reset_cpu(unsigned int cpu_id);
+
+/**
+ * Park a suspended remote CPU.
+ * @param cpu_id       ID of the target CPU.
+ *
+ * Parking means that the target CPU does not execute cell code but can handle
+ * asynchronous events again. Parking is not implemented as busy-waiting and
+ * may set the CPU into an appropriate power-saving mode. The CPU can therefore
+ * be left in this state for an undefined time.
+ *
+ * Parking may destroy the cell-visible CPU state and cannot be used to resume
+ * cell execution in the previous state without additional measures.
+ *
+ * @note This function must not be invoked for the caller's CPU or if the
+ * target CPU is not in suspend state.
+ *
+ * @see arch_suspend_cpu
+ */
 void arch_park_cpu(unsigned int cpu_id);
+
+/**
+ * Releases hypervisor control over the target CPU.
+ * @param cpu_id       ID of the target CPU.
+ *
+ * @note This function must not be invoked for the caller's CPU.
+ *
+ * @note The target CPU need not be suspended before calling the function.
+ *
+ * @note The caller has to ensure that the target CPU has enough time to reach
+ * the shutdown position before destroying the code path it has to take to get
+ * there. This can be ensured by bringing the CPU online again under Linux
+ * before cleaning up the hypervisor.
+ */
 void arch_shutdown_cpu(unsigned int cpu_id);
 
+/**
+ * Performs the architecture-specific steps for mapping a memory region into a
+ * cell's address space.
+ * @param cell         Cell for which the mapping shall be done.
+ * @param mem          Memory region to map.
+ *
+ * @return 0 on success, negative error code otherwise.
+ *
+ * @see arch_unmap_memory_region
+ */
 int arch_map_memory_region(struct cell *cell,
                           const struct jailhouse_memory *mem);
+
+/**
+ * Performs the architecture-specific steps for unmapping a memory region from
+ * a cell's address space.
+ * @param cell         Cell for which the unmapping shall be done.
+ * @param mem          Memory region to unmap.
+ *
+ * @return 0 on success, negative error code otherwise.
+ *
+ * @see arch_map_memory_region
+ */
 int arch_unmap_memory_region(struct cell *cell,
                             const struct jailhouse_memory *mem);
 
+/**
+ * Performs the architecture-specific steps for creating a new cell.
+ * @param cell         Data structure of the new cell.
+ *
+ * @return 0 on success, negative error code otherwise.
+ *
+ * @see arch_cell_destroy
+ */
 int arch_cell_create(struct cell *cell);
+
+/**
+ * Performs the architecture-specific steps for destroying a cell.
+ * @param cell         Cell to be destroyed.
+ *
+ * @see arch_cell_create
+ */
 void arch_cell_destroy(struct cell *cell);
 
+/**
+ * Performs the architecture-specific steps for applying configuration changes.
+ * @param cell_added_removed   Cell that was added or removed to/from the
+ *                             system or NULL.
+ *
+ * @see pci_config_commit
+ */
 void arch_config_commit(struct cell *cell_added_removed);
 
+/**
+ * Shutdown architecture-specific subsystems while disabling the hypervisor.
+ */
 void arch_shutdown(void);
 
+/**
+ * Performs the architecture-specifc steps to stop the current CPU on panic.
+ *
+ * @note This function never returns.
+ *
+ * @see panic_stop
+ */
 void __attribute__((noreturn)) arch_panic_stop(void);
+
+/**
+ * Performs the architecture-specific steps to park the current CPU on panic.
+ *
+ * @note This function only marks the CPU as parked and then returns to the
+ * caller.
+ *
+ * @see panic_park
+ */
 void arch_panic_park(void);
+
+/** @} */
index 86b0ad9a1de677135e47f8b98fe48a66b3c67d47..aa8a0379e2267a3b3bbe35f2dceccbbf2ef3ed1e 100644 (file)
@@ -699,6 +699,8 @@ void pci_cell_exit(struct cell *cell)
  * Apply PCI-specific configuration changes.
  * @param cell_added_removed   Cell that was added or removed to/from the
  *                             system or NULL.
+ *
+ * @see arch_config_commit
  */
 void pci_config_commit(struct cell *cell_added_removed)
 {