dm: add allow_trigger_s5 mode to pm_notify_channel uart

A user can use "--pm_notify_channel uart,allow_trigger_s5" to indicate
the User VM is allowed to trigger system S5.

"--pm_notify_channel uart" means a vuart channel will be created in the
User VM to allow communication with the VM's life_mngr. The Service VM
can then initiate S5 in the guest via its dm's monitor interface. The
additional option, "allow_trigger_s5", will create a socket connection
with the Service VM's life_mngr, allowing this VM to initiate system S5.

v1 -> v2:
- rename pm_notify_channel type to PWR_EVENT_NOTIFY_UART_TRIG_PLAT_S5

Tracked-On: #6034
Signed-off-by: Peter Fang <peter.fang@intel.com>
Acked-by: Wang, Yu1 <yu1.wang@intel.com>
This commit is contained in:
Peter Fang 2021-05-07 00:47:35 -07:00 committed by wenlingz
parent 2ab70f43e5
commit 66b92f3f4e
4 changed files with 36 additions and 20 deletions

View File

@ -149,7 +149,7 @@ usage(int code)
" %*s [--vtpm2 sock_path] [--virtio_poll interval] [--mac_seed seed_string]\n"
" %*s [--cpu_affinity pCPUs] [--lapic_pt] [--rtvm] [--windows]\n"
" %*s [--debugexit] [--logger_setting param_setting]\n"
" %*s [--pm_notify_channel] [--pm_by_vuart vuart_node]\n"
" %*s [--pm_notify_channel channel] [--pm_by_vuart vuart_node]\n"
" %*s [--ssram] <vm>\n"
" -A: create ACPI tables\n"
" -B: bootargs for kernel\n"
@ -433,8 +433,10 @@ guest_pm_notify_init(struct vmctx *ctx)
ioc_init(ctx);
else if (PWR_EVENT_NOTIFY_PWR_BT == pm_notify_channel)
power_button_init(ctx);
else if (PWR_EVENT_NOTIFY_UART == pm_notify_channel)
ret = pm_by_vuart_init(ctx);
else if (PWR_EVENT_NOTIFY_UART == pm_notify_channel ||
PWR_EVENT_NOTIFY_UART_TRIG_PLAT_S5 == pm_notify_channel)
ret = pm_by_vuart_init(ctx,
(PWR_EVENT_NOTIFY_UART_TRIG_PLAT_S5 == pm_notify_channel));
else
pr_info("No pm notify channel given\n");
@ -448,7 +450,8 @@ guest_pm_notify_deinit(struct vmctx *ctx)
ioc_deinit(ctx);
else if (PWR_EVENT_NOTIFY_PWR_BT == pm_notify_channel)
power_button_deinit(ctx);
else if (PWR_EVENT_NOTIFY_UART == pm_notify_channel)
else if (PWR_EVENT_NOTIFY_UART == pm_notify_channel ||
PWR_EVENT_NOTIFY_UART_TRIG_PLAT_S5 == pm_notify_channel)
pm_by_vuart_deinit(ctx);
else
pr_err("No correct pm notify channel given\n");
@ -968,13 +971,20 @@ main(int argc, char *argv[])
errx(EX_USAGE, "invalid logger setting params %s", optarg);
break;
case CMD_OPT_PM_NOTIFY_CHANNEL:
if (strncmp("ioc", optarg, 3) == 0)
if (strncmp("ioc", optarg, sizeof("ioc")) == 0)
pm_notify_channel = PWR_EVENT_NOTIFY_IOC;
else if (strncmp("power_button", optarg, 12) == 0)
else if (strncmp("power_button", optarg, sizeof("power_button")) == 0)
pm_notify_channel = PWR_EVENT_NOTIFY_PWR_BT;
else if (strncmp("uart", optarg, 4) == 0)
pm_notify_channel = PWR_EVENT_NOTIFY_UART;
else if (strncmp("uart", optarg, sizeof("uart") - 1) == 0) {
if (optarg[sizeof("uart") - 1] == '\0')
pm_notify_channel = PWR_EVENT_NOTIFY_UART;
else if (strncmp(",allow_trigger_s5", optarg + sizeof("uart") - 1,
sizeof(",allow_trigger_s5")) == 0)
pm_notify_channel = PWR_EVENT_NOTIFY_UART_TRIG_PLAT_S5;
else
errx(EX_USAGE, "invalid pm_notify_channel: %s", optarg);
} else
errx(EX_USAGE, "invalid pm_notify_channel: %s", optarg);
break;
case CMD_OPT_PM_BY_VUART:
if (parse_pm_by_vuart(optarg) != 0)

View File

@ -46,6 +46,7 @@ enum node_type_t {
MAX_NODE_CNT,
};
static bool allow_trigger_s5;
static uint8_t node_index = MAX_NODE_CNT;
static char node_path[MAX_NODE_PATH];
static int node_fd = -1;
@ -265,11 +266,13 @@ static int set_tty_attr(int fd, int speed)
return 0;
}
int pm_by_vuart_init(struct vmctx *ctx)
int pm_by_vuart_init(struct vmctx *ctx, bool trigger_s5)
{
assert(node_index < MAX_NODE_CNT);
pr_info("%s idx: %d, path: %s\r\n", __func__, node_index, node_path);
allow_trigger_s5 = trigger_s5;
pr_info("%s: allow_trigger_s5: %u, idx: %u, path: %s\r\n",
__func__, trigger_s5, node_index, node_path);
if (node_index == PTY_NODE)
node_fd = pty_open_virtual_uart(node_path);
@ -290,7 +293,7 @@ int pm_by_vuart_init(struct vmctx *ctx)
return -1;
}
if (start_pm_monitor_thread()) {
if (trigger_s5 && start_pm_monitor_thread()) {
close(node_fd);
node_fd = -1;
return -1;
@ -301,12 +304,14 @@ int pm_by_vuart_init(struct vmctx *ctx)
void pm_by_vuart_deinit(struct vmctx *ctx)
{
pthread_cancel(pm_monitor_thread);
pthread_join(pm_monitor_thread, NULL);
if (allow_trigger_s5) {
pthread_cancel(pm_monitor_thread);
pthread_join(pm_monitor_thread, NULL);
close(socket_fd);
socket_fd = -1;
}
close(node_fd);
node_fd = -1;
close(socket_fd);
socket_fd = -1;
}
/* called when acrn-dm receive stop command */

View File

@ -5,9 +5,10 @@
#ifndef _DM_INCLUDE_PM_
#define _DM_INCLUDE_PM_
#define PWR_EVENT_NOTIFY_IOC 0x1
#define PWR_EVENT_NOTIFY_PWR_BT 0x2
#define PWR_EVENT_NOTIFY_UART 0x3
#define PWR_EVENT_NOTIFY_IOC 0x1
#define PWR_EVENT_NOTIFY_PWR_BT 0x2
#define PWR_EVENT_NOTIFY_UART 0x3
#define PWR_EVENT_NOTIFY_UART_TRIG_PLAT_S5 0x4
int wait_for_resume(struct vmctx *ctx);
int vm_resume(struct vmctx *ctx);

View File

@ -12,7 +12,7 @@
#define __PM_VUART__
int parse_pm_by_vuart(const char *opts);
int pm_by_vuart_init(struct vmctx *ctx);
int pm_by_vuart_init(struct vmctx *ctx, bool trigger_s5);
void pm_by_vuart_deinit(struct vmctx *ctx);
#endif