mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-04 18:00:55 +00:00
hv: emulate reset register 0xcf9 and 0x64
- post-launched RTVM: intercept both PIO ports so that hypervisor has a chance to set VM_POWERING_OFF flag. - all other type of VMs: deny these 2 ports from guest access so that guests are not able to reset host. Tracked-On: #2700 Signed-off-by: Zide Chen <zide.chen@intel.com> Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
8ad0fd98a3
commit
9aa3fe646b
@ -8,6 +8,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sprintf.h>
|
#include <sprintf.h>
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
|
#include <vm_reset.h>
|
||||||
#include <bits.h>
|
#include <bits.h>
|
||||||
#include <e820.h>
|
#include <e820.h>
|
||||||
#include <multiboot.h>
|
#include <multiboot.h>
|
||||||
@ -423,6 +424,8 @@ int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_
|
|||||||
|
|
||||||
vpci_init(vm);
|
vpci_init(vm);
|
||||||
|
|
||||||
|
register_reset_port_handler(vm);
|
||||||
|
|
||||||
/* vpic wire_mode default is INTR */
|
/* vpic wire_mode default is INTR */
|
||||||
vm->wire_mode = VPIC_WIRE_INTR;
|
vm->wire_mode = VPIC_WIRE_INTR;
|
||||||
|
|
||||||
|
@ -5,8 +5,102 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
#include <vm_reset.h>
|
#include <io.h>
|
||||||
|
#include <logmsg.h>
|
||||||
#include <per_cpu.h>
|
#include <per_cpu.h>
|
||||||
|
#include <vm_reset.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vcpu != NULL && vm != NULL
|
||||||
|
*/
|
||||||
|
static bool handle_reset_reg_read(struct acrn_vm *vm, struct acrn_vcpu *vcpu, __unused uint16_t addr,
|
||||||
|
__unused size_t bytes)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
if (is_postlaunched_vm(vm)) {
|
||||||
|
/* re-inject to DM */
|
||||||
|
ret = false;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* - keyboard control/status register 0x64: ACRN doesn't expose kbd controller to the guest.
|
||||||
|
* - reset control register 0xcf9: hide this from guests for now.
|
||||||
|
*/
|
||||||
|
vcpu->req.reqs.pio.value = ~0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
static bool handle_common_reset_reg_write(struct acrn_vm *vm, bool reset)
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
if (is_postlaunched_vm(vm)) {
|
||||||
|
/* re-inject to DM */
|
||||||
|
ret = false;
|
||||||
|
|
||||||
|
if (reset && is_rt_vm(vm)) {
|
||||||
|
vm->state = VM_POWERING_OFF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* ignore writes from SOS or pre-launched VMs.
|
||||||
|
* equivalent to hide this port from guests.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
static bool handle_kb_write(struct acrn_vm *vm, __unused uint16_t addr, size_t bytes, uint32_t val)
|
||||||
|
{
|
||||||
|
/* ignore commands other than system reset */
|
||||||
|
return handle_common_reset_reg_write(vm, ((bytes == 1U) && (val == 0xfeU)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset Control register at I/O port 0xcf9.
|
||||||
|
* Bit 1 - 0: "soft" reset. Force processor begin execution at power-on reset vector.
|
||||||
|
* 1: "hard" reset. e.g. assert PLTRST# (if implemented) to do a host reset.
|
||||||
|
* Bit 2 - initiates a system reset when it transitions from 0 to 1.
|
||||||
|
* Bit 3 - 1: full reset (aka code reset), SLP_S3#/4#/5# or similar pins are asserted for full power cycle.
|
||||||
|
* 0: will be dropped if system in S3/S4/S5.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
static bool handle_cf9_write(struct acrn_vm *vm, __unused uint16_t addr, size_t bytes, uint32_t val)
|
||||||
|
{
|
||||||
|
/* We don't differentiate among hard/soft/warm/cold reset */
|
||||||
|
return handle_common_reset_reg_write(vm, ((bytes == 1U) && ((val & 0x4U) == 0x4U) && ((val & 0xaU) != 0U)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
void register_reset_port_handler(struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
/* Don't support SOS and pre-launched VM re-launch for now. */
|
||||||
|
if (!is_postlaunched_vm(vm) || is_rt_vm(vm)) {
|
||||||
|
struct vm_io_range io_range = {
|
||||||
|
.flags = IO_ATTR_RW,
|
||||||
|
.len = 1U
|
||||||
|
};
|
||||||
|
|
||||||
|
io_range.base = 0x64U;
|
||||||
|
register_pio_emulation_handler(vm, KB_PIO_IDX, &io_range, handle_reset_reg_read, handle_kb_write);
|
||||||
|
|
||||||
|
io_range.base = 0xcf9U;
|
||||||
|
register_pio_emulation_handler(vm, CF9_PIO_IDX, &io_range, handle_reset_reg_read, handle_cf9_write);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void shutdown_vm_from_idle(uint16_t pcpu_id)
|
void shutdown_vm_from_idle(uint16_t pcpu_id)
|
||||||
{
|
{
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#ifndef VM_RESET_H_
|
#ifndef VM_RESET_H_
|
||||||
#define VM_RESET_H_
|
#define VM_RESET_H_
|
||||||
|
|
||||||
|
void register_reset_port_handler(struct acrn_vm *vm);
|
||||||
void shutdown_vm_from_idle(uint16_t pcpu_id);
|
void shutdown_vm_from_idle(uint16_t pcpu_id);
|
||||||
|
|
||||||
#endif /* VM_RESET_H_ */
|
#endif /* VM_RESET_H_ */
|
||||||
|
@ -24,7 +24,9 @@
|
|||||||
#define PM1B_CNT_PIO_IDX (PM1B_EVT_PIO_IDX + 1U)
|
#define PM1B_CNT_PIO_IDX (PM1B_EVT_PIO_IDX + 1U)
|
||||||
#define RTC_PIO_IDX (PM1B_CNT_PIO_IDX + 1U)
|
#define RTC_PIO_IDX (PM1B_CNT_PIO_IDX + 1U)
|
||||||
#define VIRTUAL_PM1A_CNT_PIO_IDX (RTC_PIO_IDX + 1U)
|
#define VIRTUAL_PM1A_CNT_PIO_IDX (RTC_PIO_IDX + 1U)
|
||||||
#define EMUL_PIO_IDX_MAX (VIRTUAL_PM1A_CNT_PIO_IDX + 1U)
|
#define KB_PIO_IDX (VIRTUAL_PM1A_CNT_PIO_IDX + 1U)
|
||||||
|
#define CF9_PIO_IDX (KB_PIO_IDX + 1U)
|
||||||
|
#define EMUL_PIO_IDX_MAX (CF9_PIO_IDX + 1U)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The handler of VM exits on I/O instructions
|
* @brief The handler of VM exits on I/O instructions
|
||||||
|
Loading…
Reference in New Issue
Block a user