From 3b2784ec1be4badd5f57a63060101f29c02d9336 Mon Sep 17 00:00:00 2001 From: "yuhong.tao@intel.com" Date: Wed, 30 Jan 2019 19:08:19 +0800 Subject: [PATCH] HV: CAT: support config CAT from acrn_vm_config When CAT is supported, UOS can setup acrn_vm_config.clos, to use CAT feature. Eg., struct acrn_vm_config vm_configs[CONFIG_MAX_VM_NUM] = { { .guest_flags |= CLOS_REQUIRED, .clos = 1, }, }; sanitize_vm_config() will check if CAT is supported and vm_configs.clos is valid. Tracked-On: #2462 Signed-off-by: Tao Yuhong Acked-by: Eddie Dong --- hypervisor/arch/x86/cat.c | 16 ++++++++++++++++ hypervisor/arch/x86/cpu.c | 2 ++ hypervisor/arch/x86/guest/vcpu.c | 11 +++++++++++ hypervisor/arch/x86/guest/vm.c | 16 ++++++++++++++++ hypervisor/include/arch/x86/cat.h | 1 + hypervisor/include/arch/x86/guest/vm.h | 1 + hypervisor/include/public/acrn_common.h | 1 + 7 files changed, 48 insertions(+) diff --git a/hypervisor/arch/x86/cat.c b/hypervisor/arch/x86/cat.c index 64963fc62..9d0481309 100644 --- a/hypervisor/arch/x86/cat.c +++ b/hypervisor/arch/x86/cat.c @@ -54,3 +54,19 @@ int32_t init_cat_cap_info(void) return ret; } + + +void setup_clos(uint16_t pcpu_id) +{ + uint16_t i; + uint32_t msr_index; + uint64_t val; + + if (cat_cap_info.enabled) { + for (i = 0U; i < platform_clos_num; i++) { + msr_index = platform_clos_array[i].msr_index; + val = (uint64_t)platform_clos_array[i].clos_mask; + msr_write_pcpu(msr_index, val, pcpu_id); + } + } +} diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 86d252945..044166c71 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -230,6 +230,8 @@ void init_cpu_post(uint16_t pcpu_id) /* Wait for boot processor to signal all secondary cores to continue */ wait_sync_change(&pcpu_sync, 0UL); } + + setup_clos(pcpu_id); } static uint16_t get_cpu_id_from_lapic_id(uint32_t lapic_id) diff --git a/hypervisor/arch/x86/guest/vcpu.c b/hypervisor/arch/x86/guest/vcpu.c index 70fdedf2e..3ef979f9f 100644 --- a/hypervisor/arch/x86/guest/vcpu.c +++ b/hypervisor/arch/x86/guest/vcpu.c @@ -18,6 +18,7 @@ #include #include #include +#include inline uint64_t vcpu_get_gpreg(const struct acrn_vcpu *vcpu, uint32_t reg) { @@ -678,6 +679,8 @@ int32_t prepare_vcpu(struct acrn_vm *vm, uint16_t pcpu_id) int32_t ret = 0; struct acrn_vcpu *vcpu = NULL; char thread_name[16]; + uint64_t orig_val, final_val; + struct acrn_vm_config *conf; ret = create_vcpu(pcpu_id, vm, &vcpu); if (ret != 0) { @@ -686,6 +689,14 @@ int32_t prepare_vcpu(struct acrn_vm *vm, uint16_t pcpu_id) set_pcpu_used(pcpu_id); + /* Update CLOS for this CPU */ + if (cat_cap_info.enabled) { + conf = get_vm_config(vm->vm_id); + orig_val = msr_read(MSR_IA32_PQR_ASSOC); + final_val = (orig_val & 0xffffffffUL) | (((uint64_t)conf->clos) << 32UL); + msr_write_pcpu(MSR_IA32_PQR_ASSOC, final_val, pcpu_id); + } + INIT_LIST_HEAD(&vcpu->sched_obj.run_list); snprintf(thread_name, 16U, "vm%hu:vcpu%hu", vm->vm_id, vcpu->vcpu_id); (void)strncpy_s(vcpu->sched_obj.name, 16U, thread_name, 16U); diff --git a/hypervisor/arch/x86/guest/vm.c b/hypervisor/arch/x86/guest/vm.c index 7962d0a9c..79992d691 100644 --- a/hypervisor/arch/x86/guest/vm.c +++ b/hypervisor/arch/x86/guest/vm.c @@ -22,6 +22,7 @@ #include #include #include +#include vm_sw_loader_t vm_sw_loader; @@ -622,6 +623,21 @@ int32_t sanitize_vm_config(void) /* Nothing to do for a UNDEFINED_VM, break directly. */ break; } + + if ((vm_config->guest_flags & CLOS_REQUIRED) != 0U) { + if (cat_cap_info.support) { + if (vm_config->clos > cat_cap_info.clos_max) { + pr_err("%s CLOS exceed MAX CLOS\n", __func__); + ret = -EINVAL; + } else { + cat_cap_info.enabled = true; + } + } else { + pr_err("%s set CLOS but CAT is not supported\n", __func__); + ret = -EINVAL; + } + } + if (ret != 0) { break; } diff --git a/hypervisor/include/arch/x86/cat.h b/hypervisor/include/arch/x86/cat.h index 1739a07a4..92598a31c 100644 --- a/hypervisor/include/arch/x86/cat.h +++ b/hypervisor/include/arch/x86/cat.h @@ -19,6 +19,7 @@ struct cat_hw_info { }; extern struct cat_hw_info cat_cap_info; +void setup_clos(uint16_t pcpu_id); #define CAT_RESID_L3 1U #define CAT_RESID_L2 2U diff --git a/hypervisor/include/arch/x86/guest/vm.h b/hypervisor/include/arch/x86/guest/vm.h index 6261c1d6a..0a2728c58 100644 --- a/hypervisor/include/arch/x86/guest/vm.h +++ b/hypervisor/include/arch/x86/guest/vm.h @@ -209,6 +209,7 @@ struct acrn_vm_config { bool vm_vuart; #endif + uint16_t clos; /* if guest_flags has CAT_ENABLED, then VM use this CLOS */ } __aligned(8); /* diff --git a/hypervisor/include/public/acrn_common.h b/hypervisor/include/public/acrn_common.h index b19437ae2..89d2bbb03 100644 --- a/hypervisor/include/public/acrn_common.h +++ b/hypervisor/include/public/acrn_common.h @@ -50,6 +50,7 @@ #define SECURE_WORLD_ENABLED (1UL << 0U) /* Whether secure world is enabled */ #define LAPIC_PASSTHROUGH (1UL << 1U) /* Whether LAPIC is passed through */ #define IO_COMPLETION_POLLING (1UL << 2U) /* Whether need hypervisor poll IO completion */ +#define CLOS_REQUIRED (1UL << 3U) /* Whether CLOS is required */ /** * @brief Hypercall