From b36d80ea0cf3b2d0199f60a937b317e99195bf82 Mon Sep 17 00:00:00 2001 From: Yin Fengwei Date: Thu, 5 Sep 2019 15:30:46 +0800 Subject: [PATCH] dm: pm: add dm option to select guest notify method Now, we have two ways to notify guest about power managment event: - ioc on MRB platforms - ACPI power button on other platforms And we hardcode which one is used now. In coming change, we will add UART based guest notify method. We add dm command option to select which method will be used when launch UOS. Tracked-On: #3564 Signed-off-by: Yin Fengwei Reviewed-by: Yuan Liu Acked-by: Wang Yu --- devicemodel/core/main.c | 53 +++++++++++++++++++++++++++++++++------- devicemodel/include/pm.h | 4 +++ 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/devicemodel/core/main.c b/devicemodel/core/main.c index 639fb7a48..417dc1d7f 100644 --- a/devicemodel/core/main.c +++ b/devicemodel/core/main.c @@ -92,6 +92,7 @@ bool skip_pci_mem64bar_workaround = false; static int virtio_msix = 1; static bool debugexit_enabled; static char mac_seed_str[50]; +static int pm_notify_channel; static int acpi; @@ -137,7 +138,7 @@ usage(int code) " %*s [--part_info part_info_name] [--enable_trusty] [--intr_monitor param_setting]\n" " %*s [--vtpm2 sock_path] [--virtio_poll interval] [--mac_seed seed_string]\n" " %*s [--vmcfg sub_options] [--dump vm_idx] [--ptdev_no_reset] [--debugexit] \n" - " %*s [--logger-setting param_setting] \n" + " %*s [--logger-setting param_setting] [--pm_notify_channel] \n" " -A: create ACPI tables\n" " -B: bootargs for kernel\n" " -c: # cpus (default 1)\n" @@ -171,7 +172,8 @@ usage(int code) " --vtpm2: Virtual TPM2 args: sock_path=$PATH_OF_SWTPM_SOCKET\n" " --lapic_pt: enable local apic passthrough\n" " --rtvm: indicate that the guest is rtvm\n" - " --logger_setting: params like console,level=4;kmsg,level=3\n", + " --logger_setting: params like console,level=4;kmsg,level=3\n" + " --pm_notify_channel: define the channel used to notify guest about power event\n", progname, (int)strnlen(progname, PATH_MAX), "", (int)strnlen(progname, PATH_MAX), "", (int)strnlen(progname, PATH_MAX), "", (int)strnlen(progname, PATH_MAX), "", (int)strnlen(progname, PATH_MAX), "", (int)strnlen(progname, PATH_MAX), "", @@ -408,6 +410,32 @@ handle_vmexit(struct vmctx *ctx, struct vhm_request *vhm_req, int vcpu) vm_notify_request_done(ctx, vcpu); } +static void +guest_pm_notify_init(struct vmctx *ctx) +{ + /* + * We don't care ioc_init return value so far. + * Will add return value check once ioc is full function. + */ + if (PWR_EVENT_NOTIFY_IOC == pm_notify_channel) + ioc_init(ctx); + else if (PWR_EVENT_NOTIFY_PWR_BT == pm_notify_channel) + power_button_init(ctx); + else + pr_err("No correct pm notify channel given\n"); +} + +static void +guest_pm_notify_deinit(struct vmctx *ctx) +{ + if (PWR_EVENT_NOTIFY_IOC == pm_notify_channel) + ioc_deinit(ctx); + else if (PWR_EVENT_NOTIFY_PWR_BT == pm_notify_channel) + power_button_deinit(ctx); + else + pr_err("No correct pm notify channel given\n"); +} + static int vm_init_vdevs(struct vmctx *ctx) { @@ -419,11 +447,7 @@ vm_init_vdevs(struct vmctx *ctx) atkbdc_init(ctx); ioapic_init(ctx); - /* - * We don't care ioc_init return value so far. - * Will add return value check once ioc is full function. - */ - ret = ioc_init(ctx); + guest_pm_notify_init(ctx); ret = vrtc_init(ctx); if (ret < 0) @@ -466,7 +490,7 @@ vhpet_fail: vpit_fail: vrtc_deinit(ctx); vrtc_fail: - ioc_deinit(ctx); + guest_pm_notify_deinit(ctx); atkbdc_deinit(ctx); pci_irq_deinit(ctx); ioapic_deinit(); @@ -491,7 +515,7 @@ vm_deinit_vdevs(struct vmctx *ctx) vhpet_deinit(ctx); vpit_deinit(ctx); vrtc_deinit(ctx); - ioc_deinit(ctx); + guest_pm_notify_deinit(ctx); atkbdc_deinit(ctx); pci_irq_deinit(ctx); ioapic_deinit(); @@ -699,6 +723,7 @@ enum { CMD_OPT_LAPIC_PT, CMD_OPT_RTVM, CMD_OPT_LOGGER_SETTING, + CMD_OPT_PM_NOTIFY_CHANNEL, }; static struct option long_options[] = { @@ -737,6 +762,7 @@ static struct option long_options[] = { {"lapic_pt", no_argument, 0, CMD_OPT_LAPIC_PT}, {"rtvm", no_argument, 0, CMD_OPT_RTVM}, {"logger_setting", required_argument, 0, CMD_OPT_LOGGER_SETTING}, + {"pm_notify_channel", required_argument, 0, CMD_OPT_PM_NOTIFY_CHANNEL}, {0, 0, 0, 0 }, }; @@ -889,6 +915,15 @@ main(int argc, char *argv[]) if (init_logger_setting(optarg) != 0) errx(EX_USAGE, "invalid logger setting params %s", optarg); break; + case CMD_OPT_PM_NOTIFY_CHANNEL: + if (strncmp("ioc", optarg, 3) == 0) + pm_notify_channel = PWR_EVENT_NOTIFY_IOC; + else if (strncmp("power_button", optarg, 12) == 0) + pm_notify_channel = PWR_EVENT_NOTIFY_PWR_BT; + else if (strncmp("uart", optarg, 4) == 0) + pm_notify_channel = PWR_EVENT_NOTIFY_UART; + + break; case 'h': usage(0); default: diff --git a/devicemodel/include/pm.h b/devicemodel/include/pm.h index 72a139241..ad9903494 100644 --- a/devicemodel/include/pm.h +++ b/devicemodel/include/pm.h @@ -5,6 +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 + int wait_for_resume(struct vmctx *ctx); int vm_resume(struct vmctx *ctx); int vm_monitor_resume(void *arg);