hv: vCAT: implementing the vCAT MSRs read handlers

Implement the read_vcbm() and read_vclosid() functions to handle the MSR_IA32_PQR_ASSOC
and MSR_IA32_type_MASK_n vCAT MSRs read request.

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:
dongshen 2021-08-19 14:36:04 -07:00 committed by wenlingz
parent be855d2352
commit 3ab50f2ef5
3 changed files with 74 additions and 0 deletions

View File

@ -167,6 +167,48 @@ uint64_t vcat_pcbm_to_vcbm(const struct acrn_vm *vm, uint64_t pcbm, int res)
return (pcbm & max_pcbm) >> low; return (pcbm & max_pcbm) >> low;
} }
/**
* @pre vm != NULL
*/
static bool is_l2_vcbm_msr(const struct acrn_vm *vm, uint32_t vmsr)
{
/* num_vcbm_msrs = num_vclosids */
uint16_t num_vcbm_msrs = vcat_get_num_vclosids(vm);
return ((get_rdt_res_cap_info(RDT_RESOURCE_L2)->num_closids > 0U)
&& (vmsr >= MSR_IA32_L2_MASK_BASE) && (vmsr < (MSR_IA32_L2_MASK_BASE + num_vcbm_msrs)));
}
/**
* @pre vm != NULL
*/
static bool is_l3_vcbm_msr(const struct acrn_vm *vm, uint32_t vmsr)
{
/* num_vcbm_msrs = num_vclosids */
uint16_t num_vcbm_msrs = vcat_get_num_vclosids(vm);
return ((get_rdt_res_cap_info(RDT_RESOURCE_L3)->num_closids > 0U)
&& (vmsr >= MSR_IA32_L3_MASK_BASE) && (vmsr < (MSR_IA32_L3_MASK_BASE + num_vcbm_msrs)));
}
/**
* @brief vCBM MSR read handler
*
* @pre vcpu != NULL && vcpu->vm != NULL && rval != NULL
*/
int32_t read_vcbm(const struct acrn_vcpu *vcpu, uint32_t vmsr, uint64_t *rval)
{
int ret = -EACCES;
struct acrn_vm *vm = vcpu->vm;
if (is_vcat_configured(vm) && (is_l2_vcbm_msr(vm, vmsr) || is_l3_vcbm_msr(vm, vmsr))) {
*rval = vcpu_get_guest_msr(vcpu, vmsr);
ret = 0;
}
return ret;
}
/** /**
* @brief vCBM MSR write handler * @brief vCBM MSR write handler
* *
@ -183,6 +225,23 @@ int32_t write_vcbm(__unused struct acrn_vcpu *vcpu, __unused uint32_t vmsr, __un
return -EACCES; return -EACCES;
} }
/**
* @brief vCLOSID MSR read handler
*
* @pre vcpu != NULL && vcpu->vm != NULL
*/
int32_t read_vclosid(const struct acrn_vcpu *vcpu, uint64_t *rval)
{
int ret = -EACCES;
if (is_vcat_configured(vcpu->vm)) {
*rval = vcpu_get_guest_msr(vcpu, MSR_IA32_PQR_ASSOC);
ret = 0;
}
return ret;
}
/** /**
* @brief vCLOSID MSR write handler * @brief vCLOSID MSR write handler
* *

View File

@ -703,6 +703,19 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
} }
break; break;
} }
#ifdef CONFIG_VCAT_ENABLED
case MSR_IA32_L2_MASK_BASE ... (MSR_IA32_L2_MASK_BASE + NUM_VCAT_L2_MSRS - 1U):
case MSR_IA32_L3_MASK_BASE ... (MSR_IA32_L3_MASK_BASE + NUM_VCAT_L3_MSRS - 1U):
{
err = read_vcbm(vcpu, msr, &v);
break;
}
case MSR_IA32_PQR_ASSOC:
{
err = read_vclosid(vcpu, &v);
break;
}
#endif
default: default:
{ {
if (is_x2apic_msr(msr)) { if (is_x2apic_msr(msr)) {

View File

@ -15,6 +15,8 @@ uint16_t vcat_get_vcbm_len(const struct acrn_vm *vm, int res);
void init_vcat_msrs(struct acrn_vcpu *vcpu); void init_vcat_msrs(struct acrn_vcpu *vcpu);
uint16_t vcat_get_num_vclosids(const struct acrn_vm *vm); uint16_t vcat_get_num_vclosids(const struct acrn_vm *vm);
uint64_t vcat_pcbm_to_vcbm(const struct acrn_vm *vm, uint64_t pcbm, int res); uint64_t vcat_pcbm_to_vcbm(const struct acrn_vm *vm, uint64_t pcbm, int res);
int32_t read_vcbm(const struct acrn_vcpu *vcpu, uint32_t vmsr, uint64_t *rval);
int32_t read_vclosid(const struct acrn_vcpu *vcpu, uint64_t *rval);
#endif /* VCAT_H_ */ #endif /* VCAT_H_ */