hv: implement NEED_SHUTDOWN_VM request to idle thread
For pre-launched VMs and SOS, VM shutdown should not be executed in the current VM context. - implement NEED_SHUTDOWN_VM request so that the BSP of the target VM can shut down the guest in idle thread. - implement shutdown_vm_from_idle() to shut down target VM. 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
db952315c5
commit
8ad0fd98a3
|
@ -213,6 +213,7 @@ C_SRCS += arch/x86/guest/vmcs.c
|
||||||
C_SRCS += arch/x86/guest/vmexit.c
|
C_SRCS += arch/x86/guest/vmexit.c
|
||||||
S_SRCS += arch/x86/guest/vmx_asm.S
|
S_SRCS += arch/x86/guest/vmx_asm.S
|
||||||
C_SRCS += arch/x86/guest/trusty.c
|
C_SRCS += arch/x86/guest/trusty.c
|
||||||
|
C_SRCS += arch/x86/guest/vm_reset.c
|
||||||
C_SRCS += arch/x86/cat.c
|
C_SRCS += arch/x86/cat.c
|
||||||
C_SRCS += arch/x86/lib/memory.c
|
C_SRCS += arch/x86/lib/memory.c
|
||||||
C_SRCS += lib/string.c
|
C_SRCS += lib/string.c
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vm.h>
|
||||||
|
#include <vm_reset.h>
|
||||||
|
#include <per_cpu.h>
|
||||||
|
|
||||||
|
void shutdown_vm_from_idle(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
struct acrn_vm *vm = get_vm_from_vmid(per_cpu(shutdown_vm_id, pcpu_id));
|
||||||
|
const struct acrn_vcpu *vcpu = vcpu_from_vid(vm, BOOT_CPU_ID);
|
||||||
|
|
||||||
|
if (vcpu->pcpu_id == pcpu_id) {
|
||||||
|
(void)shutdown_vm(vm);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
|
#include <vm_reset.h>
|
||||||
#include <vmcs.h>
|
#include <vmcs.h>
|
||||||
#include <vmexit.h>
|
#include <vmexit.h>
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
|
@ -88,6 +89,8 @@ void default_idle(__unused struct sched_object *obj)
|
||||||
schedule();
|
schedule();
|
||||||
} else if (need_offline(pcpu_id) != 0) {
|
} else if (need_offline(pcpu_id) != 0) {
|
||||||
cpu_dead();
|
cpu_dead();
|
||||||
|
} else if (need_shutdown_vm(pcpu_id)) {
|
||||||
|
shutdown_vm_from_idle(pcpu_id);
|
||||||
} else {
|
} else {
|
||||||
CPU_IRQ_ENABLE();
|
CPU_IRQ_ENABLE();
|
||||||
cpu_do_idle();
|
cpu_do_idle();
|
||||||
|
|
|
@ -152,6 +152,23 @@ int32_t need_offline(uint16_t pcpu_id)
|
||||||
return bitmap_test_and_clear_lock(NEED_OFFLINE, &ctx->flags);
|
return bitmap_test_and_clear_lock(NEED_OFFLINE, &ctx->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void make_shutdown_vm_request(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
struct sched_context *ctx = &per_cpu(sched_ctx, pcpu_id);
|
||||||
|
|
||||||
|
bitmap_set_lock(NEED_SHUTDOWN_VM, &ctx->flags);
|
||||||
|
if (get_pcpu_id() != pcpu_id) {
|
||||||
|
send_single_ipi(pcpu_id, VECTOR_NOTIFY_VCPU);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool need_shutdown_vm(uint16_t pcpu_id)
|
||||||
|
{
|
||||||
|
struct sched_context *ctx = &per_cpu(sched_ctx, pcpu_id);
|
||||||
|
|
||||||
|
return bitmap_test_and_clear_lock(NEED_SHUTDOWN_VM, &ctx->flags);
|
||||||
|
}
|
||||||
|
|
||||||
static void prepare_switch(struct sched_object *prev, struct sched_object *next)
|
static void prepare_switch(struct sched_object *prev, struct sched_object *next)
|
||||||
{
|
{
|
||||||
if ((prev != NULL) && (prev->prepare_switch_out != NULL)) {
|
if ((prev != NULL) && (prev->prepare_switch_out != NULL)) {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef VM_RESET_H_
|
||||||
|
#define VM_RESET_H_
|
||||||
|
|
||||||
|
void shutdown_vm_from_idle(uint16_t pcpu_id);
|
||||||
|
|
||||||
|
#endif /* VM_RESET_H_ */
|
|
@ -18,6 +18,7 @@
|
||||||
#include <gdt.h>
|
#include <gdt.h>
|
||||||
#include <schedule.h>
|
#include <schedule.h>
|
||||||
#include <security.h>
|
#include <security.h>
|
||||||
|
#include <vm_config.h>
|
||||||
|
|
||||||
struct per_cpu_region {
|
struct per_cpu_region {
|
||||||
/* vmxon_region MUST be 4KB-aligned */
|
/* vmxon_region MUST be 4KB-aligned */
|
||||||
|
@ -52,6 +53,7 @@ struct per_cpu_region {
|
||||||
#ifdef PROFILING_ON
|
#ifdef PROFILING_ON
|
||||||
struct profiling_info_wrapper profiling_info;
|
struct profiling_info_wrapper profiling_info;
|
||||||
#endif
|
#endif
|
||||||
|
uint16_t shutdown_vm_id;
|
||||||
} __aligned(PAGE_SIZE); /* per_cpu_region size aligned with PAGE_SIZE */
|
} __aligned(PAGE_SIZE); /* per_cpu_region size aligned with PAGE_SIZE */
|
||||||
|
|
||||||
extern struct per_cpu_region per_cpu_data[CONFIG_MAX_PCPU_NUM];
|
extern struct per_cpu_region per_cpu_data[CONFIG_MAX_PCPU_NUM];
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#define NEED_RESCHEDULE (1U)
|
#define NEED_RESCHEDULE (1U)
|
||||||
#define NEED_OFFLINE (2U)
|
#define NEED_OFFLINE (2U)
|
||||||
|
#define NEED_SHUTDOWN_VM (3U)
|
||||||
|
|
||||||
#define DEL_MODE_INIT (1U)
|
#define DEL_MODE_INIT (1U)
|
||||||
#define DEL_MODE_IPI (2U)
|
#define DEL_MODE_IPI (2U)
|
||||||
|
@ -50,6 +51,8 @@ void make_reschedule_request(uint16_t pcpu_id, uint16_t delmode);
|
||||||
bool need_reschedule(uint16_t pcpu_id);
|
bool need_reschedule(uint16_t pcpu_id);
|
||||||
void make_pcpu_offline(uint16_t pcpu_id);
|
void make_pcpu_offline(uint16_t pcpu_id);
|
||||||
int32_t need_offline(uint16_t pcpu_id);
|
int32_t need_offline(uint16_t pcpu_id);
|
||||||
|
void make_shutdown_vm_request(uint16_t pcpu_id);
|
||||||
|
bool need_shutdown_vm(uint16_t pcpu_id);
|
||||||
|
|
||||||
void schedule(void);
|
void schedule(void);
|
||||||
void run_sched_thread(struct sched_object *obj);
|
void run_sched_thread(struct sched_object *obj);
|
||||||
|
|
Loading…
Reference in New Issue