hv: vCAT: propagate vCBM to other vCPUs that share cache with vcpu
Implement the propagate_vcbm() function: Set vCBM to to all the vCPUs that share cache with vcpu to mimic hardware CAT behavior Tracked-On: #5917 Signed-off-by: dongshen <dongsheng.x.zhang@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
parent
a7014f4654
commit
c0d95558c1
|
@ -224,6 +224,58 @@ static uint64_t vcbm_to_pcbm(const struct acrn_vm *vm, uint64_t vcbm, int res)
|
||||||
return vcbm << low;
|
return vcbm << low;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_cache_shift(uint32_t *l2_shift, uint32_t *l3_shift);
|
||||||
|
/**
|
||||||
|
* @pre vcpu != NULL && l2_id != NULL && l3_id != NULL
|
||||||
|
*/
|
||||||
|
static void get_cache_id(struct acrn_vcpu *vcpu, uint32_t *l2_id, uint32_t *l3_id)
|
||||||
|
{
|
||||||
|
uint32_t l2_shift, l3_shift;
|
||||||
|
uint32_t apicid = vlapic_get_apicid(vcpu_vlapic(vcpu));
|
||||||
|
|
||||||
|
get_cache_shift(&l2_shift, &l3_shift);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Relationship between APIC ID and cache ID:
|
||||||
|
* Intel SDM Vol 2, CPUID 04H:
|
||||||
|
* EAX: bits 25 - 14: Maximum number of addressable IDs for logical processors sharing this cache.
|
||||||
|
* The nearest power-of-2 integer that is not smaller than (1 + EAX[25:14]) is the number of unique
|
||||||
|
* initial APIC IDs reserved for addressing different logical processors sharing this cache
|
||||||
|
*/
|
||||||
|
*l2_id = apicid >> l2_shift;
|
||||||
|
*l3_id = apicid >> l3_shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Propagate vCBM to other vCPUs that share cache with vcpu
|
||||||
|
* @pre vcpu != NULL && vcpu->vm != NULL
|
||||||
|
*/
|
||||||
|
static void propagate_vcbm(struct acrn_vcpu *vcpu, uint32_t vmsr, uint64_t val)
|
||||||
|
{
|
||||||
|
uint16_t i;
|
||||||
|
struct acrn_vcpu *tmp_vcpu;
|
||||||
|
uint32_t l2_id, l3_id;
|
||||||
|
struct acrn_vm *vm = vcpu->vm;
|
||||||
|
|
||||||
|
get_cache_id(vcpu, &l2_id, &l3_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine which logical processors share an MSR (for instance local
|
||||||
|
* to a core, or shared across multiple cores) by checking if they have the same
|
||||||
|
* L2/L3 cache id
|
||||||
|
*/
|
||||||
|
foreach_vcpu(i, vm, tmp_vcpu) {
|
||||||
|
uint32_t tmp_l2_id, tmp_l3_id;
|
||||||
|
|
||||||
|
get_cache_id(tmp_vcpu, &tmp_l2_id, &tmp_l3_id);
|
||||||
|
|
||||||
|
if ((is_l2_vcbm_msr(vm, vmsr) && (l2_id == tmp_l2_id))
|
||||||
|
|| (is_l3_vcbm_msr(vm, vmsr) && (l3_id == tmp_l3_id))) {
|
||||||
|
vcpu_set_guest_msr(tmp_vcpu, vmsr, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if bitmask is contiguous:
|
* Check if bitmask is contiguous:
|
||||||
* All (and only) contiguous '1' combinations are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.)
|
* All (and only) contiguous '1' combinations are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.)
|
||||||
|
@ -284,8 +336,17 @@ int32_t write_vcbm(struct acrn_vcpu *vcpu, uint32_t vmsr, uint64_t val)
|
||||||
uint16_t vclosid;
|
uint16_t vclosid;
|
||||||
uint64_t pcbm, pvalue;
|
uint64_t pcbm, pvalue;
|
||||||
|
|
||||||
/* Write vCBM first: */
|
/*
|
||||||
vcpu_set_guest_msr(vcpu, vmsr, val);
|
* Write vCBM first:
|
||||||
|
* The L2 mask MSRs are scoped at the same level as the L2 cache (similarly,
|
||||||
|
* the L3 mask MSRs are scoped at the same level as the L3 cache).
|
||||||
|
*
|
||||||
|
* For example, the MSR_IA32_L3_MASK_n MSRs are scoped at socket level, which means if
|
||||||
|
* we program MSR_IA32_L3_MASK_n on one cpu and the same MSR_IA32_L3_MASK_n on all other cpus
|
||||||
|
* of the same socket will also get the change!
|
||||||
|
* Set vcbm to all the vCPUs that share cache with vcpu to mimic this hardware behavior.
|
||||||
|
*/
|
||||||
|
propagate_vcbm(vcpu, vmsr, val);
|
||||||
|
|
||||||
/* Write pCBM: */
|
/* Write pCBM: */
|
||||||
vclosid = (uint16_t)(vmsr - msr_base);
|
vclosid = (uint16_t)(vmsr - msr_base);
|
||||||
|
|
|
@ -148,7 +148,7 @@ static uint32_t nearest_pow2(uint32_t n)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_cache_shift(uint32_t *l2_shift, uint32_t *l3_shift)
|
void get_cache_shift(uint32_t *l2_shift, uint32_t *l3_shift)
|
||||||
{
|
{
|
||||||
uint32_t subleaf;
|
uint32_t subleaf;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue