HV: sanitize vm config

Add a API to sanitize vm_configs[] array, in this API, we will do sanity
check for VM configurations and refill some fields in vm_configs[]. If
sanity check is failed, the HV would reject to boot.

About pcpu_bitmap of SOS_VM:

We should not hard code pcpu_bitmap for SOS_VM, this is not convenient for
unconfigured boards. The pcpu_bitmap follows a very simple rule:

All physical CPUs except ocuppied by Pre-launched VMs are all belong to
SOS_VM. In this way, the pcpu_bitmap of a SOS_VM is decided by pcpu_bitmap
status in PRE_LAUNCHED_VMs.

To get the correct pcpu_bitmap of SOS_VM, We need to setup another rule, that
the vm_configs[] array should follow the order of PRE_LAUNCHED_VM - SOS_VM
strictly.

With this patch enabled, the pcpu_bitmap field of sos vm config is not needed
to configure;

Tracked-On: #2291

Signed-off-by: Victor Sun <victor.sun@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Victor Sun 2019-01-24 22:37:51 +08:00 committed by Eddie Dong
parent 285b64faec
commit 66e0023029
4 changed files with 56 additions and 1 deletions

View File

@ -11,7 +11,6 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] __aligned(PAGE_SIZE) = {
{ {
.type = SOS_VM, .type = SOS_VM,
.name = SOS_VM_CONFIG_NAME, .name = SOS_VM_CONFIG_NAME,
.pcpu_bitmap = SOS_VM_CONFIG_PCPU_BITMAP,
.guest_flags = SOS_VM_CONFIG_GUEST_FLAGS, .guest_flags = SOS_VM_CONFIG_GUEST_FLAGS,
.memory = { .memory = {
.start_hpa = 0x0UL, .start_hpa = 0x0UL,

View File

@ -171,6 +171,10 @@ void init_cpu_post(uint16_t pcpu_id)
panic("hardware not support!"); panic("hardware not support!");
} }
if (sanitize_vm_config() != 0) {
panic("VM Configuration Error!");
}
/* Warn for security feature not ready */ /* Warn for security feature not ready */
if (!check_cpu_security_cap()) { if (!check_cpu_security_cap()) {
pr_fatal("SECURITY WARNING!!!!!!"); pr_fatal("SECURITY WARNING!!!!!!");

View File

@ -438,6 +438,57 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
} }
} }
/**
* @pre vm_config != NULL
*/
int32_t sanitize_vm_config(void)
{
int32_t ret = 0;
uint16_t vm_id;
uint64_t sos_pcpu_bitmap, pre_launch_pcpu_bitmap;
struct acrn_vm_config *vm_config;
sos_pcpu_bitmap = (uint64_t)((((uint64_t)1U) << get_pcpu_nums()) - 1U);
pre_launch_pcpu_bitmap = 0U;
/* All physical CPUs except ocuppied by Pre-launched VMs are all
* belong to SOS_VM. i.e. The pcpu_bitmap of a SOS_VM is decided
* by pcpu_bitmap status in PRE_LAUNCHED_VMs.
* We need to setup a rule, that the vm_configs[] array should follow
* the order of PRE_LAUNCHED_VM first, and then SOS_VM.
*/
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
vm_config = get_vm_config(vm_id);
switch (vm_config->type) {
case PRE_LAUNCHED_VM:
if (vm_config->pcpu_bitmap == 0U) {
ret = -EINVAL;
} else {
pre_launch_pcpu_bitmap |= vm_config->pcpu_bitmap;
}
break;
case SOS_VM:
/* Deduct pcpus of PRE_LAUNCHED_VMs */
sos_pcpu_bitmap ^= pre_launch_pcpu_bitmap;
if ((sos_pcpu_bitmap == 0U) || ((vm_config->guest_flags & LAPIC_PASSTHROUGH) != 0U)) {
ret = -EINVAL;
} else {
vm_config->pcpu_bitmap = sos_pcpu_bitmap;
}
break;
case NORMAL_VM:
ret = -EINVAL;
break;
default:
/* Nothing to do for a UNDEFINED_VM, break directly. */
break;
}
if (ret != 0) {
break;
}
}
return ret;
}
/** /**
* @pre vm_config != NULL * @pre vm_config != NULL
*/ */

View File

@ -295,6 +295,7 @@ int32_t reset_vm(struct acrn_vm *vm);
int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_vm **rtn_vm); int32_t create_vm(uint16_t vm_id, struct acrn_vm_config *vm_config, struct acrn_vm **rtn_vm);
void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config); void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config);
void launch_vms(uint16_t pcpu_id); void launch_vms(uint16_t pcpu_id);
int32_t sanitize_vm_config(void);
extern struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM]; extern struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM];