mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-01 17:52:26 +00:00
IOC mediator: Implement VM monitor operations
This patch implements VM monitor operations including stop/suspend/resume. For other VM monitor operations(pause/unpause/query), IOC mediator would not register callbacks for them since there is no requirements from VM Manager. Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Reviewed-by: Yu Wang <yu1.wang@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
This commit is contained in:
parent
32fccb2f43
commit
48067b1cab
@ -67,6 +67,7 @@
|
||||
|
||||
#include "ioc.h"
|
||||
#include "vmmapi.h"
|
||||
#include "monitor.h"
|
||||
|
||||
/* For debugging log to a file */
|
||||
static int ioc_debug;
|
||||
@ -126,6 +127,38 @@ static int dummy1_sfd = -1;
|
||||
static int dummy2_sfd = -1;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VM Manager interfaces description.
|
||||
*
|
||||
* +---------+ +---------+ +---------+
|
||||
* |IOC | VM stop |VM | |SOS |
|
||||
* |Mediator |<----------------+Manager | |Lifecycle|
|
||||
* | | | | | |
|
||||
* | | VM suspend | | | |
|
||||
* | |<----------------+ | | |
|
||||
* | | | | | |
|
||||
* | | VM resume | | | |
|
||||
* | |<----------------+ | | |
|
||||
* | |get_wakeup_reason| |get wakeup reason| |
|
||||
* | |for resume flow | |via unix socket | |
|
||||
* | +---------------->| +---------------->| |
|
||||
* +---------+ +---------+ +---------+
|
||||
*
|
||||
* Only support stop/resume/suspend in IOC mediator currently.
|
||||
* For resume request, IOC mediator will get the wakeup reason from SOS
|
||||
* lifecycle service, then pass to UOS once received HB INIT from UOS.
|
||||
* For stop and suspend requests, they are implemented as wakeup reason of
|
||||
* ignition button.
|
||||
*/
|
||||
static int vm_stop_handler(void *arg);
|
||||
static int vm_resume_handler(void *arg);
|
||||
static int vm_suspend_handler(void *arg);
|
||||
static struct monitor_vm_ops vm_ops = {
|
||||
.stop = vm_stop_handler,
|
||||
.resume = vm_resume_handler,
|
||||
.suspend = vm_suspend_handler,
|
||||
};
|
||||
|
||||
/*
|
||||
* IOC State Transfer
|
||||
*
|
||||
@ -1301,6 +1334,72 @@ ioc_is_platform_supported(void)
|
||||
return stat(IOC_NP_ESIG, &st);
|
||||
}
|
||||
|
||||
/*
|
||||
* The callback to handle with VM stop request.
|
||||
* To emulate ignition off wakeup reason including set force S5 bit.
|
||||
*/
|
||||
static int
|
||||
vm_stop_handler(void *arg)
|
||||
{
|
||||
struct ioc_dev *ioc = arg;
|
||||
|
||||
if (!ioc) {
|
||||
DPRINTF("%s", "ioc vm stop gets NULL pointer\r\n");
|
||||
return -1;
|
||||
}
|
||||
ioc->vm_req = VM_REQ_STOP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The callback to handle with VM suspend.
|
||||
* To emulate ignition off wakeup reason.
|
||||
*/
|
||||
static int
|
||||
vm_suspend_handler(void *arg)
|
||||
{
|
||||
struct ioc_dev *ioc = arg;
|
||||
|
||||
if (!ioc) {
|
||||
DPRINTF("%s", "ioc vm suspend gets NULL pointer\r\n");
|
||||
return -1;
|
||||
}
|
||||
ioc->vm_req = VM_REQ_SUSPEND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The callback to handle with VM resume.
|
||||
* To get wakeup reason and trigger IOC_E_RESUME event.
|
||||
*/
|
||||
static int
|
||||
vm_resume_handler(void *arg)
|
||||
{
|
||||
struct ioc_dev *ioc = arg;
|
||||
uint32_t reason;
|
||||
|
||||
if (!ioc) {
|
||||
DPRINTF("%s", "ioc vm resume gets NULL pointer\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
reason = get_wakeup_reason();
|
||||
if (!reason) {
|
||||
DPRINTF("%s", "ioc vm resume gets invalid wakeup reason \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Change VM request to resume for stopping the emulation of suspend
|
||||
* and shutdown wakeup reasons.
|
||||
*/
|
||||
ioc->vm_req = VM_REQ_RESUME;
|
||||
|
||||
ioc->boot_reason = reason;
|
||||
ioc_update_event(ioc->evt_fd, IOC_E_RESUME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* To get IOC bootup reason and virtual UART path for communication
|
||||
* between IOC mediator and virtual UART.
|
||||
@ -1367,6 +1466,14 @@ ioc_init(struct vmctx *ctx)
|
||||
if (ioc->epfd < 0)
|
||||
goto alloc_err;
|
||||
|
||||
/*
|
||||
* Register IOC mediator VM ops for stop/suspend/resume.
|
||||
*/
|
||||
if (monitor_register_vm_ops(&vm_ops, ioc, "ioc_dm") < 0) {
|
||||
DPRINTF("%s", "ioc register to VM monitor failed\r\n");
|
||||
goto alloc_err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put all buffered CBC requests on the free queue, the free queue is
|
||||
* used to be a cbc_request buffer.
|
||||
|
@ -601,7 +601,7 @@ cbc_update_wakeup_reason(struct cbc_pkt *pkt, uint32_t reason)
|
||||
|
||||
/*
|
||||
* Mask the bits of wakeup reason that are not allowed by IOC mediator.
|
||||
* Only allow Ignition button, cardoor, RTC and SoC currently.
|
||||
* Only allow Ignition button, cardoor, RTC, SOC and force S5 currently.
|
||||
*/
|
||||
reason &= CBC_WK_RSN_ALL;
|
||||
|
||||
@ -814,6 +814,45 @@ cbc_rx_handler(struct cbc_pkt *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert VM request to the wakeup reason.
|
||||
*/
|
||||
static bool
|
||||
send_wakeup_reason_of_vm_request(struct cbc_pkt *pkt)
|
||||
{
|
||||
uint32_t reason;
|
||||
|
||||
switch (pkt->ioc->vm_req) {
|
||||
case VM_REQ_STOP:
|
||||
/*
|
||||
* Force S5 and SoC bits are set for emulating
|
||||
* shutdown wakeup reason that VM initiates stop
|
||||
*/
|
||||
reason = CBC_WK_RSN_FS5 | CBC_WK_RSN_SOC;
|
||||
break;
|
||||
case VM_REQ_SUSPEND:
|
||||
/*
|
||||
* Only SoC bit is set for emulating suspend
|
||||
* wakeup reason that VM initiates suspend.
|
||||
*/
|
||||
reason = CBC_WK_RSN_SOC;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* There is no need to emulate wakeup reasons for VM_REQ_RESUME
|
||||
* and VM_REQ_NONE VM requests since VM manager just only asks
|
||||
* IOC mediator to emulate ignition off wakeup reason for
|
||||
* VM_REQ_STOP and VM_REQ_SUSPEND, otherwise call primary
|
||||
* periodic wakeup reason.
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
cbc_update_wakeup_reason(pkt, reason);
|
||||
cbc_send_pkt(pkt);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tx handler mainly processes tx direction data flow,
|
||||
* the tx direction is that native CBC cdevs -> virtual UART.
|
||||
@ -824,7 +863,12 @@ cbc_tx_handler(struct cbc_pkt *pkt)
|
||||
if (pkt->req->rtype == CBC_REQ_T_PROT && pkt->ioc->cbc_enable) {
|
||||
switch (pkt->req->id) {
|
||||
case IOC_NATIVE_LFCC:
|
||||
cbc_process_wakeup_reason(pkt);
|
||||
/* Check VM request firstly */
|
||||
if (send_wakeup_reason_of_vm_request(pkt) == false) {
|
||||
|
||||
/* Primary periodic wakeup reason */
|
||||
cbc_process_wakeup_reason(pkt);
|
||||
}
|
||||
break;
|
||||
case IOC_NATIVE_SIGNAL:
|
||||
cbc_process_signal(pkt);
|
||||
|
@ -77,17 +77,19 @@
|
||||
#define CBC_WK_RSN_BTN (1 << 5) /* CBC wakeup reason field button */
|
||||
#define CBC_WK_RSN_RTC (1 << 9) /* CBC wakeup reason field rtc */
|
||||
#define CBC_WK_RSN_DOR (1 << 11) /* CBC wakeup reason field cardoor */
|
||||
#define CBC_WK_RSN_FS5 (1 << 22) /* CBC wakeup reason field force S5 */
|
||||
#define CBC_WK_RSN_SOC (1 << 23) /* CBC wakeup reason field soc */
|
||||
|
||||
/* CBC wakeup reason filed suspend or shutdown */
|
||||
#define CBC_WK_RSN_SHUTDOWN (0)
|
||||
|
||||
/*
|
||||
* IOC mediator permits button, rtc and cardoor wakeup reasons which comes from
|
||||
* IOC firmware, others will be masked.
|
||||
* IOC mediator permits ignition button, cardoor, RTC, SOC and force S5 wakeup
|
||||
* reasons which comes from IOC firmware, others will be masked.
|
||||
*/
|
||||
#define CBC_WK_RSN_ALL \
|
||||
(CBC_WK_RSN_BTN | CBC_WK_RSN_RTC | CBC_WK_RSN_DOR | CBC_WK_RSN_SOC)
|
||||
(CBC_WK_RSN_BTN | CBC_WK_RSN_RTC | CBC_WK_RSN_DOR | CBC_WK_RSN_SOC | \
|
||||
CBC_WK_RSN_FS5)
|
||||
|
||||
/*
|
||||
* CBC ring buffer is used to buffer bytes before build one complete CBC frame.
|
||||
@ -660,6 +662,16 @@ enum ioc_event_type {
|
||||
IOC_E_RESUME
|
||||
};
|
||||
|
||||
/*
|
||||
* VM request types.
|
||||
*/
|
||||
enum vm_request_type {
|
||||
VM_REQ_NONE,
|
||||
VM_REQ_STOP,
|
||||
VM_REQ_SUSPEND,
|
||||
VM_REQ_RESUME
|
||||
};
|
||||
|
||||
/*
|
||||
* CBC packet is mainly structure for CBC protocol process.
|
||||
*/
|
||||
@ -691,6 +703,7 @@ struct ioc_dev {
|
||||
int epfd; /* Epoll fd */
|
||||
int32_t evt_fd; /* Pipe write fd to trigger one event */
|
||||
uint32_t boot_reason; /* Boot or resume wakeup reason */
|
||||
enum vm_request_type vm_req; /* Request from VM Manager (acrnctl) */
|
||||
enum ioc_state_type state; /* IOC state type */
|
||||
struct epoll_event *evts; /* Epoll events table */
|
||||
struct cbc_request *pool; /* CBC requests pool */
|
||||
|
Loading…
Reference in New Issue
Block a user