HV: add cpu affinity info for SOS VM

Previously the CPU affinity of SOS VM is initialized at runtime during
sanitize_vm_config() stage, follow the policy that all physical CPUs
except ocuppied by Pre-launched VMs are all belong to SOS_VM. Now change
the process that SOS CPU affinity should be initialized at build time
and has the assumption that its validity is guarenteed before runtime.

Tracked-On: #5077

Signed-off-by: Victor Sun <victor.sun@intel.com>
Reviewed-by: Jason Chen CJ <jason.cj.chen@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Victor Sun 2020-07-16 14:45:41 +08:00 committed by wenlingz
parent 3acafd140f
commit b9ad04d24d
8 changed files with 18 additions and 23 deletions

View File

@ -121,29 +121,23 @@ bool sanitize_vm_config(void)
{ {
bool ret = true; bool ret = true;
uint16_t vm_id, vuart_idx; uint16_t vm_id, vuart_idx;
uint64_t pre_launch_pcpu_bitmap = 0UL;
struct acrn_vm_config *vm_config; struct acrn_vm_config *vm_config;
/* All physical CPUs except ocuppied by Pre-launched VMs are all /* We need to setup a rule, that the vm_configs[] array should follow
* belong to SOS_VM. i.e. The cpu_affinity of a SOS_VM is decided
* by cpu_affinity 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. * the order of PRE_LAUNCHED_VM first, and then SOS_VM.
*/ */
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
vm_config = get_vm_config(vm_id); vm_config = get_vm_config(vm_id);
if ((vm_config->cpu_affinity & ~ALL_CPUS_MASK) != 0UL) { if ((vm_config->cpu_affinity == 0UL) || ((vm_config->cpu_affinity & ~ALL_CPUS_MASK) != 0UL)) {
pr_err("%s: vm%u assigns invalid PCPU (0x%llx)", __func__, vm_id, vm_config->cpu_affinity); pr_err("%s: vm%u assigns invalid PCPU (0x%llx)", __func__, vm_id, vm_config->cpu_affinity);
ret = false; ret = false;
} }
switch (vm_config->load_order) { switch (vm_config->load_order) {
case PRE_LAUNCHED_VM: case PRE_LAUNCHED_VM:
if (vm_config->cpu_affinity == 0UL) {
ret = false;
/* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */ /* GUEST_FLAG_RT must be set if we have GUEST_FLAG_LAPIC_PASSTHROUGH set in guest_flags */
} else if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U) if (((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)
&& ((vm_config->guest_flags & GUEST_FLAG_RT) == 0U)) { && ((vm_config->guest_flags & GUEST_FLAG_RT) == 0U)) {
ret = false; ret = false;
} else if (vm_config->epc.size != 0UL) { } else if (vm_config->epc.size != 0UL) {
@ -151,24 +145,16 @@ bool sanitize_vm_config(void)
} else if (is_safety_vm_uuid(vm_config->uuid) && (vm_config->severity != (uint8_t)SEVERITY_SAFETY_VM)) { } else if (is_safety_vm_uuid(vm_config->uuid) && (vm_config->severity != (uint8_t)SEVERITY_SAFETY_VM)) {
ret = false; ret = false;
} else { } else {
pre_launch_pcpu_bitmap |= vm_config->cpu_affinity; /* nothing to do here */
} }
break; break;
case SOS_VM: case SOS_VM:
/* Deduct pcpus of PRE_LAUNCHED_VMs */ if ((vm_config->severity != (uint8_t)SEVERITY_SOS) ||
vm_config->cpu_affinity = ALL_CPUS_MASK ^ pre_launch_pcpu_bitmap;
if ((vm_config->cpu_affinity == 0UL) || (vm_config->severity != (uint8_t)SEVERITY_SOS) ||
((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)) { ((vm_config->guest_flags & GUEST_FLAG_LAPIC_PASSTHROUGH) != 0U)) {
ret = false; ret = false;
} }
break; break;
case POST_LAUNCHED_VM: case POST_LAUNCHED_VM:
if ((vm_config->cpu_affinity == 0UL) ||
((vm_config->cpu_affinity & pre_launch_pcpu_bitmap) != 0UL)) {
pr_err("%s: Post-launch VM has no pcpus or share pcpu with Pre-launch VM!", __func__);
ret = false;
}
if ((vm_config->severity == (uint8_t)SEVERITY_SAFETY_VM) || if ((vm_config->severity == (uint8_t)SEVERITY_SAFETY_VM) ||
(vm_config->severity == (uint8_t)SEVERITY_SOS)) { (vm_config->severity == (uint8_t)SEVERITY_SOS)) {
ret = false; ret = false;

View File

@ -770,6 +770,7 @@ void prepare_vm(uint16_t vm_id, struct acrn_vm_config *vm_config)
/** /**
* @pre vm_config != NULL * @pre vm_config != NULL
* @Application constraint: The validity of vm_config->cpu_affinity should be guaranteed before run-time.
*/ */
void launch_vms(uint16_t pcpu_id) void launch_vms(uint16_t pcpu_id)
{ {
@ -779,11 +780,10 @@ void launch_vms(uint16_t pcpu_id)
for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) { for (vm_id = 0U; vm_id < CONFIG_MAX_VM_NUM; vm_id++) {
vm_config = get_vm_config(vm_id); vm_config = get_vm_config(vm_id);
if ((vm_config->load_order == SOS_VM) || (vm_config->load_order == PRE_LAUNCHED_VM)) { if ((vm_config->load_order == SOS_VM) || (vm_config->load_order == PRE_LAUNCHED_VM)) {
if (vm_config->load_order == SOS_VM) {
sos_vm_ptr = &vm_array[vm_id];
}
if (pcpu_id == get_configured_bsp_pcpu_id(vm_config)) { if (pcpu_id == get_configured_bsp_pcpu_id(vm_config)) {
if (vm_config->load_order == SOS_VM) {
sos_vm_ptr = &vm_array[vm_id];
}
prepare_vm(vm_id, vm_config); prepare_vm(vm_id, vm_config);
} }
} }

View File

@ -45,6 +45,7 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
/* Allow SOS to reboot the host since there is supposed to be the highest severity guest */ /* Allow SOS to reboot the host since there is supposed to be the highest severity guest */
.guest_flags = 0UL, .guest_flags = 0UL,
.cpu_affinity = SOS_VM_CONFIG_CPU_AFFINITY,
.memory = { .memory = {
.start_hpa = 0UL, .start_hpa = 0UL,
.size = CONFIG_SOS_RAM_SIZE, .size = CONFIG_SOS_RAM_SIZE,

View File

@ -34,6 +34,8 @@
SOS_IDLE \ SOS_IDLE \
SOS_BOOTARGS_DIFF SOS_BOOTARGS_DIFF
#define SOS_VM_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U) | AFFINITY_CPU(2U))
#define VM2_CONFIG_CPU_AFFINITY (AFFINITY_CPU(2U)) #define VM2_CONFIG_CPU_AFFINITY (AFFINITY_CPU(2U))
#endif /* VM_CONFIGURATIONS_H */ #endif /* VM_CONFIGURATIONS_H */

View File

@ -58,6 +58,7 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
/* Allow SOS to reboot the host since there is supposed to be the highest severity guest */ /* Allow SOS to reboot the host since there is supposed to be the highest severity guest */
.guest_flags = 0UL, .guest_flags = 0UL,
.cpu_affinity = SOS_VM_CONFIG_CPU_AFFINITY,
.memory = { .memory = {
.start_hpa = 0UL, .start_hpa = 0UL,
.size = CONFIG_SOS_RAM_SIZE, .size = CONFIG_SOS_RAM_SIZE,

View File

@ -34,6 +34,8 @@
SOS_IDLE \ SOS_IDLE \
SOS_BOOTARGS_DIFF SOS_BOOTARGS_DIFF
#define SOS_VM_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U))
#define VM2_CONFIG_CPU_AFFINITY (AFFINITY_CPU(1U)) #define VM2_CONFIG_CPU_AFFINITY (AFFINITY_CPU(1U))
#endif /* VM_CONFIGURATIONS_H */ #endif /* VM_CONFIGURATIONS_H */

View File

@ -14,6 +14,7 @@ struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = {
/* Allow SOS to reboot the host since there is supposed to be the highest severity guest */ /* Allow SOS to reboot the host since there is supposed to be the highest severity guest */
.guest_flags = 0UL, .guest_flags = 0UL,
.cpu_affinity = SOS_VM_CONFIG_CPU_AFFINITY,
.memory = { .memory = {
.start_hpa = 0UL, .start_hpa = 0UL,
.size = CONFIG_SOS_RAM_SIZE, .size = CONFIG_SOS_RAM_SIZE,

View File

@ -27,6 +27,8 @@
SOS_IDLE \ SOS_IDLE \
SOS_BOOTARGS_DIFF SOS_BOOTARGS_DIFF
#define SOS_VM_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U) | AFFINITY_CPU(2U) | AFFINITY_CPU(3U))
#define VM1_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U)) #define VM1_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U))
#define VM2_CONFIG_CPU_AFFINITY (AFFINITY_CPU(2U) | AFFINITY_CPU(3U)) #define VM2_CONFIG_CPU_AFFINITY (AFFINITY_CPU(2U) | AFFINITY_CPU(3U))
#define VM3_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U)) #define VM3_CONFIG_CPU_AFFINITY (AFFINITY_CPU(0U) | AFFINITY_CPU(1U))