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:
Zide Chen 2019-02-27 09:54:58 -08:00 committed by wenlingz
parent db952315c5
commit 8ad0fd98a3
7 changed files with 57 additions and 0 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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)) {

View File

@ -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_ */

View File

@ -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];

View File

@ -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);