]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
core/inmates: Generalize message channel of comm region
authorJan Kiszka <jan.kiszka@siemens.com>
Thu, 3 Apr 2014 09:18:19 +0000 (11:18 +0200)
committerJan Kiszka <jan.kiszka@siemens.com>
Sat, 3 May 2014 12:56:57 +0000 (14:56 +0200)
Prepare the message channel for further message types by generalizing
the replies: requests can be denied or accepted, there is a specific
code to be sent back on reception of unknown messages, and messages can
also be for information only. This allows to factor out a reusable
cell_send_message service.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Documentation/hypervisor-interfaces.txt
hypervisor/control.c
hypervisor/include/jailhouse/hypercall.h
inmates/apic-demo.c

index abbae72886c29868eea35d27cdc441bfa3d8c4c8..2a6c9961e734d69b980bcf2192ca3b4a74c90f5d 100644 (file)
@@ -215,7 +215,8 @@ in order to receive the cell's answer.
 
 For answering a message, the cell first has to clear the "Message to Cell"
 field. It then has to write a non-zero reply code into the "Message from Cell"
-field.
+field. If a cell receives an unknown message code, it has to send the reply
+"Message unknown" (code 1).
 
 Write ordering of all updates has to be ensured by both the hypervisor
 and the cell according to the requirements of the hardware architecture.
@@ -228,18 +229,18 @@ message responds times may still affect the root cell negatively.
 
 The following messages and corresponding replies are defined:
 
- - Shutdown Requested (code 1):
+ - Shutdown Request (code 1):
         The cell is supposed to be shut down, either to destroy only the cell
         itself or to disable the hypervisor completely.
 
    Possible replies:
-        1 - Shutdown denied
-        2 - Shutdown OK
+        2 - Request denied
+        3 - Request approved
 
-Note: The hypervisor does not request shutdown permission from a cell if that
-      cell has the "Passive Communication Region" flag set in its configuration
-      (see also [2]) or if the cell state is set to "Shut Down" or "Failed"
-      (see below).
+   Note: The hypervisor does not request shutdown permission from a cell if
+         that cell has the "Passive Communication Region" flag set in its
+         configuration (see also [2]) or if the cell state is set to "Shut
+         Down" or "Failed" (see below).
 
 
 Logical Channel "Cell State"
index 081b0363c0d21df3783842220f2eebf56748fdd6..08ddbf79610a9794191f5615c6d4fa44936efe7e 100644 (file)
@@ -19,6 +19,8 @@
 #include <asm/bitops.h>
 #include <asm/spinlock.h>
 
+enum msg_type {MSG_REQUEST, MSG_INFORMATION};
+
 struct jailhouse_system *system_config;
 
 static DEFINE_SPINLOCK(shutdown_lock);
@@ -62,6 +64,46 @@ static void cell_resume(struct per_cpu *cpu_data)
                arch_resume_cpu(cpu);
 }
 
+/**
+ * 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
+ *
+ * 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.
+ */
+static bool cell_send_message(struct cell *cell, u32 message,
+                             enum msg_type type)
+{
+       if (cell->config->flags & JAILHOUSE_CELL_PASSIVE_COMMREG)
+               return true;
+
+       jailhouse_send_msg_to_cell(&cell->comm_page.comm_region, message);
+
+       while (1) {
+               u32 reply = cell->comm_page.comm_region.reply_from_cell;
+               u32 cell_state = cell->comm_page.comm_region.cell_state;
+
+               if (cell_state == JAILHOUSE_CELL_SHUT_DOWN ||
+                   cell_state == JAILHOUSE_CELL_FAILED)
+                       return true;
+
+               if ((type == MSG_REQUEST &&
+                    reply == JAILHOUSE_MSG_REQUEST_APPROVED) ||
+                   (type == MSG_INFORMATION &&
+                    reply == JAILHOUSE_MSG_RECEIVED))
+                       return true;
+
+               if (reply != JAILHOUSE_MSG_NONE)
+                       return false;
+
+               cpu_relax();
+       }
+}
+
 static unsigned int get_free_cell_id(void)
 {
        unsigned int id = 0;
@@ -328,23 +370,8 @@ err_resume:
 
 static bool cell_shutdown_ok(struct cell *cell)
 {
-       volatile u32 *reply = &cell->comm_page.comm_region.reply_from_cell;
-       volatile u32 *cell_state = &cell->comm_page.comm_region.cell_state;
-
-       if (cell->config->flags & JAILHOUSE_CELL_PASSIVE_COMMREG)
-               return true;
-
-       jailhouse_send_msg_to_cell(&cell->comm_page.comm_region,
-                                  JAILHOUSE_MSG_SHUTDOWN_REQUESTED);
-
-       while (*reply != JAILHOUSE_MSG_SHUTDOWN_DENIED) {
-               if (*reply == JAILHOUSE_MSG_SHUTDOWN_OK ||
-                   *cell_state == JAILHOUSE_CELL_SHUT_DOWN ||
-                   *cell_state == JAILHOUSE_CELL_FAILED)
-                       return true;
-               cpu_relax();
-       }
-       return false;
+       return cell_send_message(cell, JAILHOUSE_MSG_SHUTDOWN_REQUEST,
+                                MSG_REQUEST);
 }
 
 static int cell_management_prologue(struct per_cpu *cpu_data, unsigned long id,
index 19ff4a099629c46ec8a863e1630c34f25601397c..9eb05a8d2b9dd44701c7ef0ffd1b4972d7985c72 100644 (file)
 #define JAILHOUSE_MSG_NONE                     0
 
 /* messages to cell */
-#define JAILHOUSE_MSG_SHUTDOWN_REQUESTED       1
+#define JAILHOUSE_MSG_SHUTDOWN_REQUEST         1
 
 /* replies from cell */
-#define JAILHOUSE_MSG_SHUTDOWN_DENIED          1
-#define JAILHOUSE_MSG_SHUTDOWN_OK              2
+#define JAILHOUSE_MSG_UNKNOWN                  1
+#define JAILHOUSE_MSG_REQUEST_DENIED           2
+#define JAILHOUSE_MSG_REQUEST_APPROVED         3
+#define JAILHOUSE_MSG_RECEIVED                 4
 
 /* cell state, initialized by hypervisor, updated by cell */
 #define JAILHOUSE_CELL_RUNNING                 0
index 71c307a9ca24c8d00b37bb2290f0b68afb71006a..8a529e1f9d2f605d19e3c7e4de659d20376fe853 100644 (file)
@@ -132,6 +132,7 @@ static void init_apic(void)
 
 void inmate_main(void)
 {
+       bool terminate = false;
        unsigned int n;
 
        printk_uart_base = UART_BASE;
@@ -144,12 +145,23 @@ void inmate_main(void)
        if (init_pm_timer())
                init_apic();
 
-       while (comm_region->msg_to_cell != JAILHOUSE_MSG_SHUTDOWN_REQUESTED)
+       while (!terminate) {
                asm volatile("hlt");
 
-       printk("Rejecting first shutdown - try again!\n");
-       jailhouse_send_reply_from_cell(comm_region,
-                                      JAILHOUSE_MSG_SHUTDOWN_DENIED);
+               switch (comm_region->msg_to_cell) {
+               case JAILHOUSE_MSG_SHUTDOWN_REQUEST:
+                       printk("Rejecting first shutdown request - "
+                              "try again!\n");
+                       jailhouse_send_reply_from_cell(comm_region,
+                                       JAILHOUSE_MSG_REQUEST_DENIED);
+                       terminate = true;
+                       break;
+               default:
+                       jailhouse_send_reply_from_cell(comm_region,
+                                       JAILHOUSE_MSG_UNKNOWN);
+                       break;
+               }
+       }
 
        for (n = 0; n < 10; n++)
                asm volatile("hlt");