mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 04:33:55 +00:00
hv: initial host reset implementation
- add the GUEST_FLAG_HIGHEST_SEVERITY flag to indicate that the guest has privilege to reboot the host system. - this flag is statically assigned to guest(s) in vm_configurations.c in different scenarios. - implement reset_host() function to reset the host. First try the ACPI reset register if available, then try the 0xcf9 PIO. Tracked-On: #3145 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
321e4f1300
commit
5a23f7b664
@ -111,6 +111,16 @@ bool is_rt_vm(const struct acrn_vm *vm)
|
|||||||
return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U);
|
return ((vm_config->guest_flags & GUEST_FLAG_RT) != 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
|
*/
|
||||||
|
bool is_highest_severity_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
||||||
|
|
||||||
|
return ((vm_config->guest_flags & GUEST_FLAG_HIGHEST_SEVERITY) != 0U);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
*/
|
*/
|
||||||
|
@ -78,6 +78,45 @@ void triple_fault_shutdown_vm(struct acrn_vm *vm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void reset_host(void)
|
||||||
|
{
|
||||||
|
struct acpi_generic_address *gas = &(host_reset_reg.reg);
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO: gracefully shut down all guests before doing host reset. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* UEFI more likely sets the reset value as 0x6 (not 0xe) for 0xcf9 port.
|
||||||
|
* This asserts PLTRST# to reset devices on the platform, but not the
|
||||||
|
* SLP_S3#/4#/5# signals, which power down the systems. This might not be
|
||||||
|
* enough for us.
|
||||||
|
*/
|
||||||
|
if ((gas->space_id == SPACE_SYSTEM_IO) &&
|
||||||
|
(gas->bit_width == 8U) && (gas->bit_offset == 0U) &&
|
||||||
|
(gas->address != 0U) && (gas->address != 0xcf9U)) {
|
||||||
|
pio_write8(host_reset_reg.val, (uint16_t)host_reset_reg.reg.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fall back
|
||||||
|
* making sure bit 2 (RST_CPU) is '0', when the reset command is issued.
|
||||||
|
*/
|
||||||
|
pio_write8(0x2U, 0xcf9U);
|
||||||
|
pio_write8(0xeU, 0xcf9U);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fall back
|
||||||
|
* keyboard controller might cause the INIT# being asserted,
|
||||||
|
* and not power cycle the system.
|
||||||
|
*/
|
||||||
|
pio_write8(0xfeU, 0x64U);
|
||||||
|
|
||||||
|
pr_fatal("%s(): can't reset host.", __func__);
|
||||||
|
while (1) {
|
||||||
|
asm_pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vcpu != NULL && vm != NULL
|
* @pre vcpu != NULL && vm != NULL
|
||||||
*/
|
*/
|
||||||
@ -108,7 +147,11 @@ static bool handle_common_reset_reg_write(struct acrn_vm *vm, bool reset)
|
|||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (is_postlaunched_vm(vm)) {
|
if (is_highest_severity_vm(vm)) {
|
||||||
|
if (reset) {
|
||||||
|
reset_host();
|
||||||
|
}
|
||||||
|
} else if (is_postlaunched_vm(vm)) {
|
||||||
/* re-inject to DM */
|
/* re-inject to DM */
|
||||||
ret = false;
|
ret = false;
|
||||||
|
|
||||||
@ -155,7 +198,11 @@ static bool handle_reset_reg_write(__unused struct acrn_vm *vm, uint16_t addr, s
|
|||||||
{
|
{
|
||||||
if (bytes == 1U) {
|
if (bytes == 1U) {
|
||||||
if (val == host_reset_reg.val) {
|
if (val == host_reset_reg.val) {
|
||||||
|
if (is_highest_severity_vm(vm)) {
|
||||||
|
reset_host();
|
||||||
|
} else {
|
||||||
/* ignore reset request */
|
/* ignore reset request */
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* ACPI defines the reset value but doesn't specify the meaning of other values.
|
* ACPI defines the reset value but doesn't specify the meaning of other values.
|
||||||
|
@ -218,6 +218,7 @@ void vrtc_init(struct acrn_vm *vm);
|
|||||||
|
|
||||||
bool is_lapic_pt_configured(const struct acrn_vm *vm);
|
bool is_lapic_pt_configured(const struct acrn_vm *vm);
|
||||||
bool is_rt_vm(const struct acrn_vm *vm);
|
bool is_rt_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_highest_severity_vm(const struct acrn_vm *vm);
|
||||||
bool vm_hide_mtrr(const struct acrn_vm *vm);
|
bool vm_hide_mtrr(const struct acrn_vm *vm);
|
||||||
|
|
||||||
#endif /* !ASSEMBLER */
|
#endif /* !ASSEMBLER */
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#define GUEST_FLAG_CLOS_REQUIRED (1UL << 3U) /* Whether CLOS is required */
|
#define GUEST_FLAG_CLOS_REQUIRED (1UL << 3U) /* Whether CLOS is required */
|
||||||
#define GUEST_FLAG_HIDE_MTRR (1UL << 4U) /* Whether hide MTRR from VM */
|
#define GUEST_FLAG_HIDE_MTRR (1UL << 4U) /* Whether hide MTRR from VM */
|
||||||
#define GUEST_FLAG_RT (1UL << 5U) /* Whether the vm is RT-VM */
|
#define GUEST_FLAG_RT (1UL << 5U) /* Whether the vm is RT-VM */
|
||||||
|
#define GUEST_FLAG_HIGHEST_SEVERITY (1UL << 6U) /* Whether has the highest severity */
|
||||||
|
|
||||||
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
|
/* TODO: We may need to get this addr from guest ACPI instead of hardcode here */
|
||||||
#define VIRTUAL_PM1A_CNT_ADDR 0x404U
|
#define VIRTUAL_PM1A_CNT_ADDR 0x404U
|
||||||
|
@ -53,6 +53,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
.uuid = {0x49U, 0x5aU, 0xe2U, 0xe5U, 0x26U, 0x03U, 0x4dU, 0x64U, \
|
.uuid = {0x49U, 0x5aU, 0xe2U, 0xe5U, 0x26U, 0x03U, 0x4dU, 0x64U, \
|
||||||
0xafU, 0x76U, 0xd4U, 0xbcU, 0x5aU, 0x8eU, 0xc0U, 0xe5U},
|
0xafU, 0x76U, 0xd4U, 0xbcU, 0x5aU, 0x8eU, 0xc0U, 0xe5U},
|
||||||
/* 495ae2e5-2603-4d64-af76-d4bc5a8ec0e5 */
|
/* 495ae2e5-2603-4d64-af76-d4bc5a8ec0e5 */
|
||||||
|
|
||||||
|
/* The hard RTVM must be launched as VM2 */
|
||||||
|
.guest_flags = GUEST_FLAG_HIGHEST_SEVERITY,
|
||||||
.vuart[0] = {
|
.vuart[0] = {
|
||||||
.type = VUART_LEGACY_PIO,
|
.type = VUART_LEGACY_PIO,
|
||||||
.addr.port_base = INVALID_COM_BASE,
|
.addr.port_base = INVALID_COM_BASE,
|
||||||
|
@ -14,7 +14,9 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
|
|||||||
.uuid = {0xdbU, 0xbbU, 0xd4U, 0x34U, 0x7aU, 0x57U, 0x42U, 0x16U, \
|
.uuid = {0xdbU, 0xbbU, 0xd4U, 0x34U, 0x7aU, 0x57U, 0x42U, 0x16U, \
|
||||||
0xa1U, 0x2cU, 0x22U, 0x01U, 0xf1U, 0xabU, 0x02U, 0x40U},
|
0xa1U, 0x2cU, 0x22U, 0x01U, 0xf1U, 0xabU, 0x02U, 0x40U},
|
||||||
/* dbbbd434-7a57-4216-a12c-2201f1ab0240 */
|
/* dbbbd434-7a57-4216-a12c-2201f1ab0240 */
|
||||||
.guest_flags = 0UL,
|
|
||||||
|
/* Allow SOS to reboot the host since there is supposed to be the highest severity guest */
|
||||||
|
.guest_flags = GUEST_FLAG_HIGHEST_SEVERITY,
|
||||||
.clos = 0U,
|
.clos = 0U,
|
||||||
.memory = {
|
.memory = {
|
||||||
.start_hpa = 0UL,
|
.start_hpa = 0UL,
|
||||||
|
Loading…
Reference in New Issue
Block a user