diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 96ce15151..daa385a50 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -305,24 +305,32 @@ static void intercept_x2apic_msrs(uint8_t *msr_bitmap_arg, uint32_t mode) } /** - * @pre vcpu != NULL + * @pre vcpu != NULL && vcpu->vm != NULL && vcpu->vm->vm_id < CONFIG_MAX_VM_NUM + * @pre (is_platform_rdt_capable() == false()) || (is_platform_rdt_capable() && get_vm_config(vcpu->vm->vm_id)->pclosids != NULL) */ -static void prepare_auto_msr_area (struct acrn_vcpu *vcpu) +static void prepare_auto_msr_area(struct acrn_vcpu *vcpu) { - struct acrn_vm_config *cfg = get_vm_config(vcpu->vm->vm_id); - uint16_t vcpu_clos = cfg->clos[vcpu->vcpu_id]; - vcpu->arch.msr_area.count = 0U; - /* only load/restore MSR IA32_PQR_ASSOC when hv and guest have differnt settings */ - if (is_platform_rdt_capable() && (vcpu_clos != hv_clos)) { - vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC; - vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].value = clos2pqr_msr(vcpu_clos); - vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC; - vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].value = clos2pqr_msr(hv_clos); - vcpu->arch.msr_area.count++; - pr_acrnlog("switch clos for VM %u vcpu_id %u, host 0x%x, guest 0x%x", - vcpu->vm->vm_id, vcpu->vcpu_id, hv_clos, vcpu_clos); + if (is_platform_rdt_capable()) { + struct acrn_vm_config *cfg = get_vm_config(vcpu->vm->vm_id); + uint16_t vcpu_clos; + + ASSERT(cfg->pclosids != NULL, "error, cfg->pclosids is NULL"); + + vcpu_clos = cfg->pclosids[vcpu->vcpu_id%cfg->num_pclosids]; + + /* RDT: only load/restore MSR_IA32_PQR_ASSOC when hv and guest have different settings */ + if (vcpu_clos != hv_clos) { + vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC; + vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].value = clos2pqr_msr(vcpu_clos); + vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC; + vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].value = clos2pqr_msr(hv_clos); + vcpu->arch.msr_area.count++; + + pr_acrnlog("switch clos for VM %u vcpu_id %u, host 0x%x, guest 0x%x", + vcpu->vm->vm_id, vcpu->vcpu_id, hv_clos, vcpu_clos); + } } } @@ -392,7 +400,7 @@ void init_msr_emulation(struct acrn_vcpu *vcpu) pr_dbg("VMX_MSR_BITMAP: 0x%016lx ", value64); /* Initialize the MSR save/store area */ - prepare_auto_msr_area (vcpu); + prepare_auto_msr_area(vcpu); /* Setup initial value for emulated MSRs */ init_emulated_msrs(vcpu); diff --git a/hypervisor/include/arch/x86/asm/vm_config.h b/hypervisor/include/arch/x86/asm/vm_config.h index 528210375..051c07148 100644 --- a/hypervisor/include/arch/x86/asm/vm_config.h +++ b/hypervisor/include/arch/x86/asm/vm_config.h @@ -182,9 +182,24 @@ struct acrn_vm_config { * SOS can get the vm_configs[] array through hypercall, but SOS may not * need to parse these members. */ - uint16_t clos[MAX_VCPUS_PER_VM]; /* Class of Service, effective only if CONFIG_RDT_ENABLED - * is defined on CAT capable platforms - */ + + uint16_t num_pclosids; /* This defines the number of elements in the array pointed to by pclosids */ + /* pclosids: a pointer to an array of physical CLOSIDs (pCLOSIDs)) that is defined in vm_configurations.c + * by vmconfig, + * applicable only if CONFIG_RDT_ENABLED is defined on CAT capable platforms. + * The number of elements in the array must be equal to the value given by num_pclosids + */ + uint16_t *pclosids; + + /* max_type_pcbm (type: l2 or l3) specifies the allocated portion of physical cache + * for the VM and is a contiguous capacity bitmask (CBM) starting at bit position low + * (the lowest assigned physical cache way) and ending at position high + * (the highest assigned physical cache way, inclusive). + * As CBM only allows contiguous '1' combinations, so max_type_pcbm essentially + * is a bitmask that selects/covers all the physical cache ways assigned to the VM. + */ + uint32_t max_l2_pcbm; + uint32_t max_l3_pcbm; struct vuart_config vuart[MAX_VUART_NUM_PER_VM];/* vuart configuration for VM */ diff --git a/misc/config_tools/xforms/lib.xsl b/misc/config_tools/xforms/lib.xsl index 57345d419..cc26ebddb 100644 --- a/misc/config_tools/xforms/lib.xsl +++ b/misc/config_tools/xforms/lib.xsl @@ -376,6 +376,17 @@ + + + + + + + + + + + diff --git a/misc/config_tools/xforms/misc_cfg.h.xsl b/misc/config_tools/xforms/misc_cfg.h.xsl index 35fa10740..b409acf0a 100644 --- a/misc/config_tools/xforms/misc_cfg.h.xsl +++ b/misc/config_tools/xforms/misc_cfg.h.xsl @@ -122,12 +122,6 @@ - - - - - - @@ -70,7 +85,11 @@ - + + + + + @@ -133,7 +152,23 @@ - + + + + + + + + + + + + + + + + + @@ -148,13 +183,13 @@ - + }, - + diff --git a/misc/hv_prebuild/vm_cfg_checks.c b/misc/hv_prebuild/vm_cfg_checks.c index 8620c1580..a966883ae 100644 --- a/misc/hv_prebuild/vm_cfg_checks.c +++ b/misc/hv_prebuild/vm_cfg_checks.c @@ -84,13 +84,12 @@ static bool check_vm_clos_config(uint16_t vm_id) uint16_t platform_clos_num = HV_SUPPORTED_MAX_CLOS; bool ret = true; struct acrn_vm_config *vm_config = get_vm_config(vm_id); - uint16_t vcpu_num = bitmap_weight(vm_config->cpu_affinity); - for (i = 0U; i < vcpu_num; i++) { - if (((platform_clos_num != 0U) && (vm_config->clos[i] == platform_clos_num)) - || (vm_config->clos[i] > platform_clos_num)) { + for (i = 0U; i < vm_config->num_pclosids; i++) { + if (((platform_clos_num != 0U) && (vm_config->pclosids[i] == platform_clos_num)) + || (vm_config->pclosids[i] > platform_clos_num)) { printf("vm%u: vcpu%u clos(%u) exceed the max clos(%u).", - vm_id, i, vm_config->clos[i], platform_clos_num); + vm_id, i, vm_config->pclosids[i], platform_clos_num); ret = false; break; }