From e4bfabfc98f5f1714664e969bba214eda0e7acbb Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 3 Apr 2014 11:18:19 +0200 Subject: [PATCH] core/inmates: Generalize message channel of comm region 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 --- Documentation/hypervisor-interfaces.txt | 17 +++---- hypervisor/control.c | 61 +++++++++++++++++------- hypervisor/include/jailhouse/hypercall.h | 8 ++-- inmates/apic-demo.c | 20 ++++++-- 4 files changed, 74 insertions(+), 32 deletions(-) diff --git a/Documentation/hypervisor-interfaces.txt b/Documentation/hypervisor-interfaces.txt index abbae72..2a6c996 100644 --- a/Documentation/hypervisor-interfaces.txt +++ b/Documentation/hypervisor-interfaces.txt @@ -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" diff --git a/hypervisor/control.c b/hypervisor/control.c index 081b036..08ddbf7 100644 --- a/hypervisor/control.c +++ b/hypervisor/control.c @@ -19,6 +19,8 @@ #include #include +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, diff --git a/hypervisor/include/jailhouse/hypercall.h b/hypervisor/include/jailhouse/hypercall.h index 19ff4a0..9eb05a8 100644 --- a/hypervisor/include/jailhouse/hypercall.h +++ b/hypervisor/include/jailhouse/hypercall.h @@ -35,11 +35,13 @@ #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 diff --git a/inmates/apic-demo.c b/inmates/apic-demo.c index 71c307a..8a529e1 100644 --- a/inmates/apic-demo.c +++ b/inmates/apic-demo.c @@ -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"); -- 2.39.2