mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-11-16 13:55:04 +00:00
hv: vm: Move some common helpers to common scope
No logic change. Only movement. Tracked-On: #8830 Signed-off-by: Yifan Liu <yifan1.liu@intel.com> Reviewed-by: Fei Li <fei1.li@intel.com> Acked-by: Wang Yu1 <yu1.wang@intel.com>
This commit is contained in:
@@ -10,22 +10,6 @@
|
|||||||
|
|
||||||
#include <asm/guest/vm.h>
|
#include <asm/guest/vm.h>
|
||||||
|
|
||||||
/* FIXME */
|
|
||||||
struct acrn_vm *get_vm_from_vmid(__unused uint16_t vm_id)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_paused_vm(__unused const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_poweroff_vm(__unused const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void arch_trigger_level_intr(__unused struct acrn_vm *vm,
|
void arch_trigger_level_intr(__unused struct acrn_vm *vm,
|
||||||
__unused uint32_t irq, __unused bool assert) {}
|
__unused uint32_t irq, __unused bool assert) {}
|
||||||
|
|
||||||
|
|||||||
@@ -56,75 +56,6 @@ void *get_sworld_memory_base(void)
|
|||||||
return post_user_vm_sworld_memory;
|
return post_user_vm_sworld_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_unused_vmid(void)
|
|
||||||
{
|
|
||||||
uint16_t vm_id;
|
|
||||||
struct acrn_vm_config *vm_config;
|
|
||||||
|
|
||||||
for (vm_id = 0; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
|
||||||
vm_config = get_vm_config(vm_id);
|
|
||||||
if ((vm_config->name[0] == '\0') && ((vm_config->guest_flags & GUEST_FLAG_STATIC_VM) == 0U)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t get_vmid_by_name(const char *name)
|
|
||||||
{
|
|
||||||
uint16_t vm_id;
|
|
||||||
|
|
||||||
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
|
||||||
if ((*name != '\0') && vm_has_matched_name(vm_id, name)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
bool is_poweroff_vm(const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
return (vm->state == VM_POWERED_OFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
bool is_created_vm(const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
return (vm->state == VM_CREATED);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_service_vm(const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
return (vm != NULL) && (get_vm_config(vm->vm_id)->load_order == SERVICE_VM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL
|
|
||||||
* @pre vm->vmid < CONFIG_MAX_VM_NUM
|
|
||||||
*/
|
|
||||||
bool is_postlaunched_vm(const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
return (get_vm_config(vm->vm_id)->load_order == POST_LAUNCHED_VM);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL
|
|
||||||
* @pre vm->vmid < CONFIG_MAX_VM_NUM
|
|
||||||
*/
|
|
||||||
bool is_prelaunched_vm(const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
struct acrn_vm_config *vm_config;
|
|
||||||
|
|
||||||
vm_config = get_vm_config(vm->vm_id);
|
|
||||||
return (vm_config->load_order == PRE_LAUNCHED_VM);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
*/
|
*/
|
||||||
@@ -145,31 +76,6 @@ bool is_pmu_pt_configured(const struct acrn_vm *vm)
|
|||||||
return ((vm_config->guest_flags & GUEST_FLAG_PMU_PASSTHROUGH) != 0U);
|
return ((vm_config->guest_flags & GUEST_FLAG_PMU_PASSTHROUGH) != 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
|
||||||
*/
|
|
||||||
bool is_rt_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_RT) != 0U);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
|
||||||
*
|
|
||||||
* Stateful VM refers to VM that has its own state (such as internal file cache),
|
|
||||||
* and will experience state loss (file system corruption) if force powered down.
|
|
||||||
*/
|
|
||||||
bool is_stateful_vm(const struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
|
||||||
|
|
||||||
/* TEE VM has GUEST_FLAG_STATELESS set implicitly */
|
|
||||||
return ((vm_config->guest_flags & GUEST_FLAG_STATELESS) == 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
|
||||||
*/
|
*/
|
||||||
@@ -190,16 +96,6 @@ bool is_vcat_configured(const struct acrn_vm *vm)
|
|||||||
return ((vm_config->guest_flags & GUEST_FLAG_VCAT_ENABLED) != 0U);
|
return ((vm_config->guest_flags & GUEST_FLAG_VCAT_ENABLED) != 0U);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
|
||||||
*/
|
|
||||||
bool is_static_configured_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_STATIC_VM) != 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
|
||||||
*/
|
*/
|
||||||
@@ -234,24 +130,6 @@ bool is_pi_capable(const struct acrn_vm *vm)
|
|||||||
return (platform_caps.pi && (!is_lapic_pt_configured(vm)));
|
return (platform_caps.pi && (!is_lapic_pt_configured(vm)));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct acrn_vm *get_highest_severity_vm(bool runtime)
|
|
||||||
{
|
|
||||||
uint16_t vm_id, highest_vm_id = 0U;
|
|
||||||
|
|
||||||
for (vm_id = 1U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
|
||||||
if (runtime && is_poweroff_vm(get_vm_from_vmid(vm_id))) {
|
|
||||||
/* If vm is non-existed or shutdown, it's not highest severity VM */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_vm_severity(vm_id) > get_vm_severity(highest_vm_id)) {
|
|
||||||
highest_vm_id = vm_id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return get_vm_from_vmid(highest_vm_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
*/
|
*/
|
||||||
@@ -891,16 +769,6 @@ int32_t arch_reset_vm(struct acrn_vm *vm)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
void poweroff_if_rt_vm(struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
if (is_rt_vm(vm) && !is_paused_vm(vm) && !is_poweroff_vm(vm)) {
|
|
||||||
vm->state = VM_READY_TO_POWEROFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Resume vm from S3 state
|
* @brief Resume vm from S3 state
|
||||||
*
|
*
|
||||||
@@ -1016,50 +884,6 @@ enum vm_vlapic_mode check_vm_vlapic_mode(const struct acrn_vm *vm)
|
|||||||
return vlapic_mode;
|
return vlapic_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* if there is RT VM return true otherwise return false.
|
|
||||||
*/
|
|
||||||
bool has_rt_vm(void)
|
|
||||||
{
|
|
||||||
uint16_t vm_id;
|
|
||||||
|
|
||||||
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
|
||||||
if (is_rt_vm(get_vm_from_vmid(vm_id))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (vm_id != CONFIG_MAX_VM_NUM);
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_shutdown_vm_request(uint16_t pcpu_id)
|
|
||||||
{
|
|
||||||
bitmap_set(NEED_SHUTDOWN_VM, &per_cpu(pcpu_flag, pcpu_id));
|
|
||||||
if (get_pcpu_id() != pcpu_id) {
|
|
||||||
kick_pcpu(pcpu_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool need_shutdown_vm(uint16_t pcpu_id)
|
|
||||||
{
|
|
||||||
return bitmap_test_and_clear(NEED_SHUTDOWN_VM, &per_cpu(pcpu_flag, pcpu_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
void get_vm_lock(struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
spinlock_obtain(&vm->vm_state_lock);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
void put_vm_lock(struct acrn_vm *vm)
|
|
||||||
{
|
|
||||||
spinlock_release(&vm->vm_state_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void arch_trigger_level_intr(struct acrn_vm *vm, uint32_t irq, bool assert)
|
void arch_trigger_level_intr(struct acrn_vm *vm, uint32_t irq, bool assert)
|
||||||
{
|
{
|
||||||
union ioapic_rte rte;
|
union ioapic_rte rte;
|
||||||
|
|||||||
@@ -239,23 +239,3 @@ void register_reset_port_handler(struct acrn_vm *vm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown_vm_from_idle(uint16_t pcpu_id)
|
|
||||||
{
|
|
||||||
uint16_t vm_id;
|
|
||||||
uint64_t *vms = &per_cpu(shutdown_vm_bitmap, pcpu_id);
|
|
||||||
struct acrn_vm *vm;
|
|
||||||
|
|
||||||
for (vm_id = fls64(*vms); vm_id < CONFIG_MAX_VM_NUM; vm_id = fls64(*vms)) {
|
|
||||||
vm = get_vm_from_vmid(vm_id);
|
|
||||||
get_vm_lock(vm);
|
|
||||||
if (is_paused_vm(vm)) {
|
|
||||||
(void)destroy_vm(vm);
|
|
||||||
if (is_ready_for_system_shutdown()) {
|
|
||||||
shutdown_system();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
put_vm_lock(vm);
|
|
||||||
bitmap_clear_non_atomic(vm_id, vms);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* SPDX-License-Identifier: BSD-3-Clause
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <per_cpu.h>
|
||||||
#include <vcpu.h>
|
#include <vcpu.h>
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
@@ -15,6 +16,166 @@ static struct acrn_vm vm_array[CONFIG_MAX_VM_NUM] __aligned(PAGE_SIZE);
|
|||||||
|
|
||||||
static struct acrn_vm *service_vm_ptr = NULL;
|
static struct acrn_vm *service_vm_ptr = NULL;
|
||||||
|
|
||||||
|
uint16_t get_unused_vmid(void)
|
||||||
|
{
|
||||||
|
uint16_t vm_id;
|
||||||
|
struct acrn_vm_config *vm_config;
|
||||||
|
|
||||||
|
for (vm_id = 0; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
||||||
|
vm_config = get_vm_config(vm_id);
|
||||||
|
if ((vm_config->name[0] == '\0') && ((vm_config->guest_flags & GUEST_FLAG_STATIC_VM) == 0U)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t get_vmid_by_name(const char *name)
|
||||||
|
{
|
||||||
|
uint16_t vm_id;
|
||||||
|
|
||||||
|
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
||||||
|
if ((*name != '\0') && vm_has_matched_name(vm_id, name)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (vm_id < CONFIG_MAX_VM_NUM) ? (vm_id) : (ACRN_INVALID_VMID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
bool is_poweroff_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
return (vm->state == VM_POWERED_OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
bool is_created_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
return (vm->state == VM_CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_service_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
return (vm != NULL) && (get_vm_config(vm->vm_id)->load_order == SERVICE_VM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
* @pre vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
|
*/
|
||||||
|
bool is_postlaunched_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
return (get_vm_config(vm->vm_id)->load_order == POST_LAUNCHED_VM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
* @pre vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
|
*/
|
||||||
|
bool is_prelaunched_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
struct acrn_vm_config *vm_config;
|
||||||
|
|
||||||
|
vm_config = get_vm_config(vm->vm_id);
|
||||||
|
return (vm_config->load_order == PRE_LAUNCHED_VM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
|
*/
|
||||||
|
bool is_rt_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_RT) != 0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
|
*
|
||||||
|
* Stateful VM refers to VM that has its own state (such as internal file cache),
|
||||||
|
* and will experience state loss (file system corruption) if force powered down.
|
||||||
|
*/
|
||||||
|
bool is_stateful_vm(const struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
struct acrn_vm_config *vm_config = get_vm_config(vm->vm_id);
|
||||||
|
|
||||||
|
/* TEE VM has GUEST_FLAG_STATELESS set implicitly */
|
||||||
|
return ((vm_config->guest_flags & GUEST_FLAG_STATELESS) == 0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL && vm_config != NULL && vm->vmid < CONFIG_MAX_VM_NUM
|
||||||
|
*/
|
||||||
|
bool is_static_configured_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_STATIC_VM) != 0U);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct acrn_vm *get_highest_severity_vm(bool runtime)
|
||||||
|
{
|
||||||
|
uint16_t vm_id, highest_vm_id = 0U;
|
||||||
|
|
||||||
|
for (vm_id = 1U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
||||||
|
if (runtime && is_poweroff_vm(get_vm_from_vmid(vm_id))) {
|
||||||
|
/* If vm is non-existed or shutdown, it's not highest severity VM */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_vm_severity(vm_id) > get_vm_severity(highest_vm_id)) {
|
||||||
|
highest_vm_id = vm_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_vm_from_vmid(highest_vm_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
void poweroff_if_rt_vm(struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
if (is_rt_vm(vm) && !is_paused_vm(vm) && !is_poweroff_vm(vm)) {
|
||||||
|
vm->state = VM_READY_TO_POWEROFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* if there is RT VM return true otherwise return false.
|
||||||
|
*/
|
||||||
|
bool has_rt_vm(void)
|
||||||
|
{
|
||||||
|
uint16_t vm_id;
|
||||||
|
|
||||||
|
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
|
||||||
|
if (is_rt_vm(get_vm_from_vmid(vm_id))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (vm_id != CONFIG_MAX_VM_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
void get_vm_lock(struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
spinlock_obtain(&vm->vm_state_lock);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
void put_vm_lock(struct acrn_vm *vm)
|
||||||
|
{
|
||||||
|
spinlock_release(&vm->vm_state_lock);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @pre vm != NULL
|
* @pre vm != NULL
|
||||||
*/
|
*/
|
||||||
@@ -269,3 +430,36 @@ int32_t reset_vm(struct acrn_vm *vm)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_shutdown_vm_request(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
bitmap_set(NEED_SHUTDOWN_VM, &per_cpu(pcpu_flag, pcpu_id));
|
||||||
|
if (get_pcpu_id() != pcpu_id) {
|
||||||
|
arch_smp_call_kick_pcpu(pcpu_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_shutdown_vm(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
return bitmap_test_and_clear(NEED_SHUTDOWN_VM, &per_cpu(pcpu_flag, pcpu_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown_vm_from_idle(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
uint16_t vm_id;
|
||||||
|
uint64_t *vms = &per_cpu(shutdown_vm_bitmap, pcpu_id);
|
||||||
|
struct acrn_vm *vm;
|
||||||
|
|
||||||
|
for (vm_id = fls64(*vms); vm_id < CONFIG_MAX_VM_NUM; vm_id = fls64(*vms)) {
|
||||||
|
vm = get_vm_from_vmid(vm_id);
|
||||||
|
get_vm_lock(vm);
|
||||||
|
if (is_paused_vm(vm)) {
|
||||||
|
(void)destroy_vm(vm);
|
||||||
|
if (is_ready_for_system_shutdown()) {
|
||||||
|
shutdown_system();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
put_vm_lock(vm);
|
||||||
|
bitmap_clear_non_atomic(vm_id, vms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,10 +7,4 @@
|
|||||||
#ifndef RISCV_VM_RESET_H_
|
#ifndef RISCV_VM_RESET_H_
|
||||||
#define RISCV_VM_RESET_H_
|
#define RISCV_VM_RESET_H_
|
||||||
|
|
||||||
/* FIXME: riscv dummy function */
|
|
||||||
static inline void shutdown_vm_from_idle(uint16_t pcpu_id)
|
|
||||||
{
|
|
||||||
(void)pcpu_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* RISCV_VM_RESET_H_ */
|
#endif /* RISCV_VM_RESET_H_ */
|
||||||
|
|||||||
@@ -319,8 +319,8 @@ struct descriptor_table {
|
|||||||
uint64_t base;
|
uint64_t base;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
#define NEED_OFFLINE (1U)
|
#define NEED_OFFLINE (1U)
|
||||||
#define NEED_SHUTDOWN_VM (2U)
|
|
||||||
void make_pcpu_offline(uint16_t pcpu_id);
|
void make_pcpu_offline(uint16_t pcpu_id);
|
||||||
bool need_offline(uint16_t pcpu_id);
|
bool need_offline(uint16_t pcpu_id);
|
||||||
|
|
||||||
|
|||||||
@@ -112,69 +112,26 @@ struct vm_arch {
|
|||||||
|
|
||||||
} __aligned(PAGE_SIZE);
|
} __aligned(PAGE_SIZE);
|
||||||
|
|
||||||
/* Convert relative vm id to absolute vm id */
|
|
||||||
static inline uint16_t rel_vmid_2_vmid(uint16_t service_vmid, uint16_t rel_vmid) {
|
|
||||||
return (service_vmid + rel_vmid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Convert absolute vm id to relative vm id */
|
|
||||||
static inline uint16_t vmid_2_rel_vmid(uint16_t service_vmid, uint16_t vmid) {
|
|
||||||
return (vmid - service_vmid);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool is_severity_pass(uint16_t target_vmid)
|
|
||||||
{
|
|
||||||
return SEVERITY_SERVICE_VM >= get_vm_severity(target_vmid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_shutdown_vm_request(uint16_t pcpu_id);
|
|
||||||
bool need_shutdown_vm(uint16_t pcpu_id);
|
|
||||||
void poweroff_if_rt_vm(struct acrn_vm *vm);
|
|
||||||
void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec);
|
void resume_vm_from_s3(struct acrn_vm *vm, uint32_t wakeup_vec);
|
||||||
bool is_created_vm(const struct acrn_vm *vm);
|
|
||||||
bool is_service_vm(const struct acrn_vm *vm);
|
|
||||||
bool is_postlaunched_vm(const struct acrn_vm *vm);
|
|
||||||
bool is_prelaunched_vm(const struct acrn_vm *vm);
|
|
||||||
uint16_t get_vmid_by_name(const char *name);
|
|
||||||
struct acrn_vm *get_service_vm(void);
|
|
||||||
|
|
||||||
void create_service_vm_e820(struct acrn_vm *vm);
|
void create_service_vm_e820(struct acrn_vm *vm);
|
||||||
void create_prelaunched_vm_e820(struct acrn_vm *vm);
|
void create_prelaunched_vm_e820(struct acrn_vm *vm);
|
||||||
void prepare_vm_identical_memmap(struct acrn_vm *vm, uint16_t e820_entry_type, uint64_t prot_orig);
|
void prepare_vm_identical_memmap(struct acrn_vm *vm, uint16_t e820_entry_type, uint64_t prot_orig);
|
||||||
uint64_t find_space_from_ve820(struct acrn_vm *vm, uint32_t size, uint64_t min_addr, uint64_t max_addr);
|
uint64_t find_space_from_ve820(struct acrn_vm *vm, uint32_t size, uint64_t min_addr, uint64_t max_addr);
|
||||||
|
|
||||||
int32_t prepare_os_image(struct acrn_vm *vm);
|
|
||||||
|
|
||||||
void suspend_vrtc(void);
|
void suspend_vrtc(void);
|
||||||
void resume_vrtc(void);
|
void resume_vrtc(void);
|
||||||
void vrtc_init(struct acrn_vm *vm);
|
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_pmu_pt_configured(const struct acrn_vm *vm);
|
bool is_pmu_pt_configured(const struct acrn_vm *vm);
|
||||||
bool is_rt_vm(const struct acrn_vm *vm);
|
|
||||||
bool is_stateful_vm(const struct acrn_vm *vm);
|
|
||||||
bool is_nvmx_configured(const struct acrn_vm *vm);
|
bool is_nvmx_configured(const struct acrn_vm *vm);
|
||||||
bool is_vcat_configured(const struct acrn_vm *vm);
|
bool is_vcat_configured(const struct acrn_vm *vm);
|
||||||
bool is_static_configured_vm(const struct acrn_vm *vm);
|
|
||||||
uint16_t get_unused_vmid(void);
|
|
||||||
bool is_pi_capable(const struct acrn_vm *vm);
|
bool is_pi_capable(const struct acrn_vm *vm);
|
||||||
bool has_rt_vm(void);
|
|
||||||
struct acrn_vm *get_highest_severity_vm(bool runtime);
|
|
||||||
bool vm_hide_mtrr(const struct acrn_vm *vm);
|
bool vm_hide_mtrr(const struct acrn_vm *vm);
|
||||||
void update_vm_vlapic_state(struct acrn_vm *vm);
|
void update_vm_vlapic_state(struct acrn_vm *vm);
|
||||||
enum vm_vlapic_mode check_vm_vlapic_mode(const struct acrn_vm *vm);
|
enum vm_vlapic_mode check_vm_vlapic_mode(const struct acrn_vm *vm);
|
||||||
bool is_vhwp_configured(const struct acrn_vm *vm);
|
bool is_vhwp_configured(const struct acrn_vm *vm);
|
||||||
bool is_vtm_configured(const struct acrn_vm *vm);
|
bool is_vtm_configured(const struct acrn_vm *vm);
|
||||||
/*
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
void get_vm_lock(struct acrn_vm *vm);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @pre vm != NULL
|
|
||||||
*/
|
|
||||||
void put_vm_lock(struct acrn_vm *vm);
|
|
||||||
|
|
||||||
void *get_sworld_memory_base(void);
|
void *get_sworld_memory_base(void);
|
||||||
#endif /* !ASSEMBLER */
|
#endif /* !ASSEMBLER */
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <acrn_common.h>
|
#include <acrn_common.h>
|
||||||
|
|
||||||
void register_reset_port_handler(struct acrn_vm *vm);
|
void register_reset_port_handler(struct acrn_vm *vm);
|
||||||
void shutdown_vm_from_idle(uint16_t pcpu_id);
|
|
||||||
void triple_fault_shutdown_vm(struct acrn_vcpu *vcpu);
|
void triple_fault_shutdown_vm(struct acrn_vcpu *vcpu);
|
||||||
|
|
||||||
#endif /* VM_RESET_H_ */
|
#endif /* VM_RESET_H_ */
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <vcpu.h>
|
#include <vcpu.h>
|
||||||
|
|
||||||
|
#define NEED_SHUTDOWN_VM (2U)
|
||||||
|
|
||||||
struct vm_hw_info {
|
struct vm_hw_info {
|
||||||
/* vcpu array of this VM */
|
/* vcpu array of this VM */
|
||||||
struct acrn_vcpu vcpu_array[MAX_VCPUS_PER_VM];
|
struct acrn_vcpu vcpu_array[MAX_VCPUS_PER_VM];
|
||||||
@@ -150,6 +152,53 @@ bool is_ready_for_system_shutdown(void);
|
|||||||
void arch_trigger_level_intr(__unused struct acrn_vm *vm,
|
void arch_trigger_level_intr(__unused struct acrn_vm *vm,
|
||||||
__unused uint32_t irq, __unused bool assert);
|
__unused uint32_t irq, __unused bool assert);
|
||||||
|
|
||||||
|
/* Convert relative vm id to absolute vm id */
|
||||||
|
static inline uint16_t rel_vmid_2_vmid(uint16_t service_vmid, uint16_t rel_vmid) {
|
||||||
|
return (service_vmid + rel_vmid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Convert absolute vm id to relative vm id */
|
||||||
|
static inline uint16_t vmid_2_rel_vmid(uint16_t service_vmid, uint16_t vmid) {
|
||||||
|
return (vmid - service_vmid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_severity_pass(uint16_t target_vmid)
|
||||||
|
{
|
||||||
|
return SEVERITY_SERVICE_VM >= get_vm_severity(target_vmid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void shutdown_vm_from_idle(uint16_t pcpu_id);
|
||||||
|
void make_shutdown_vm_request(uint16_t pcpu_id);
|
||||||
|
bool need_shutdown_vm(uint16_t pcpu_id);
|
||||||
|
void poweroff_if_rt_vm(struct acrn_vm *vm);
|
||||||
|
bool is_poweroff_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_created_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_paused_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_service_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_postlaunched_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_prelaunched_vm(const struct acrn_vm *vm);
|
||||||
|
uint16_t get_vmid_by_name(const char *name);
|
||||||
|
struct acrn_vm *get_vm_from_vmid(uint16_t vm_id);
|
||||||
|
struct acrn_vm *get_service_vm(void);
|
||||||
|
bool is_rt_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_stateful_vm(const struct acrn_vm *vm);
|
||||||
|
bool is_static_configured_vm(const struct acrn_vm *vm);
|
||||||
|
uint16_t get_unused_vmid(void);
|
||||||
|
bool has_rt_vm(void);
|
||||||
|
struct acrn_vm *get_highest_severity_vm(bool runtime);
|
||||||
|
int32_t prepare_os_image(struct acrn_vm *vm);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
void get_vm_lock(struct acrn_vm *vm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @pre vm != NULL
|
||||||
|
*/
|
||||||
|
void put_vm_lock(struct acrn_vm *vm);
|
||||||
|
|
||||||
int32_t arch_init_vm(struct acrn_vm *vm, struct acrn_vm_config *vm_config);
|
int32_t arch_init_vm(struct acrn_vm *vm, struct acrn_vm_config *vm_config);
|
||||||
int32_t arch_deinit_vm(struct acrn_vm *vm);
|
int32_t arch_deinit_vm(struct acrn_vm *vm);
|
||||||
void arch_vm_prepare_bsp(struct acrn_vcpu *bsp);
|
void arch_vm_prepare_bsp(struct acrn_vcpu *bsp);
|
||||||
|
|||||||
Reference in New Issue
Block a user