Skip to content

Commit 887e381

Browse files
vijaydhanrajwenlingz
authored andcommitted
HV: Add both HW and SW checks for RDT support
There can be times when user unknowinlgy enables CONFIG_CAT_ENBALED SW flag, but the hardware might not support L3 or L2 CAT. In such case software can end up writing to the CAT MSRs which can cause undefined results. The patch fixes the issue by enabling CAT only when both HW as well software via the CONFIG_CAT_ENABLED supports CAT. The patch also address typo with "clos2prq_msr" function name. It should be "clos2pqr_msr" instead. PQR stands for platform qos register. Tracked-On: #3715 Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent b8a021d commit 887e381

File tree

4 files changed

+43
-30
lines changed

4 files changed

+43
-30
lines changed

hypervisor/arch/x86/configs/vm_config.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,15 @@ bool sanitize_vm_config(void)
184184
break;
185185
}
186186

187-
if (cat_cap_info.enabled && (vm_config->clos > cat_cap_info.clos_max)) {
188-
pr_err("%s set CLOS(%d) more than system supports(%d)\n", __func__,
189-
vm_config->clos, cat_cap_info.clos_max);
187+
if (ret &&
188+
is_platform_rdt_capable() &&
189+
(vm_config->clos >= platform_clos_num)) {
190+
pr_err("%s set wrong CLOS. Please set below %d\n", __func__, platform_clos_num);
190191
ret = false;
191192
}
192193

193-
if (((vm_config->epc.size | vm_config->epc.base) & ~PAGE_MASK) != 0UL) {
194+
if (ret &&
195+
(((vm_config->epc.size | vm_config->epc.base) & ~PAGE_MASK) != 0UL)) {
194196
ret = false;
195197
}
196198

@@ -199,15 +201,18 @@ bool sanitize_vm_config(void)
199201
ret = check_vm_uuid_collision(vm_id);
200202
}
201203

202-
/* vuart[1+] are used for VM communications */
203-
for (vuart_idx = 1U; vuart_idx < MAX_VUART_NUM_PER_VM; vuart_idx++) {
204-
const struct vuart_config *vu_config = &vm_config->vuart[vuart_idx];
205-
206-
if (!(vu_config->type == VUART_LEGACY_PIO) && (vu_config->addr.port_base == INVALID_COM_BASE)) {
207-
if ((vu_config->t_vuart.vm_id >= CONFIG_MAX_VM_NUM) ||
208-
(vu_config->t_vuart.vm_id == vm_id)) {
209-
pr_err("%s invalid vuart configuration for VM %d\n", __func__, vm_id);
210-
ret = false;
204+
if (ret) {
205+
/* vuart[1+] are used for VM communications */
206+
for (vuart_idx = 1U; vuart_idx < MAX_VUART_NUM_PER_VM; vuart_idx++) {
207+
const struct vuart_config *vu_config = &vm_config->vuart[vuart_idx];
208+
209+
if (!(vu_config->type == VUART_LEGACY_PIO) &&
210+
(vu_config->addr.port_base == INVALID_COM_BASE)) {
211+
if ((vu_config->t_vuart.vm_id >= CONFIG_MAX_VM_NUM) ||
212+
(vu_config->t_vuart.vm_id == vm_id)) {
213+
pr_err("%s invalid vuart configuration for VM %d\n", __func__, vm_id);
214+
ret = false;
215+
}
211216
}
212217
}
213218
}

hypervisor/arch/x86/guest/vmsr.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,11 @@ static void init_msr_area(struct acrn_vcpu *vcpu)
302302
vcpu->arch.msr_area.count++;
303303

304304
/* only load/restore MSR IA32_PQR_ASSOC when hv and guest have differnt settings */
305-
if (cat_cap_info.enabled && (cfg->clos != hv_clos)) {
305+
if (is_platform_rdt_capable() && (cfg->clos != hv_clos)) {
306306
vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC;
307-
vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].value = clos2prq_msr(cfg->clos);
307+
vcpu->arch.msr_area.guest[MSR_AREA_IA32_PQR_ASSOC].value = clos2pqr_msr(cfg->clos);
308308
vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].msr_index = MSR_IA32_PQR_ASSOC;
309-
vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].value = clos2prq_msr(hv_clos);
309+
vcpu->arch.msr_area.host[MSR_AREA_IA32_PQR_ASSOC].value = clos2pqr_msr(hv_clos);
310310
vcpu->arch.msr_area.count++;
311311
pr_acrnlog("switch clos for VM %u vcpu_id %u, host 0x%x, guest 0x%x",
312312
vcpu->vm->vm_id, vcpu->vcpu_id, hv_clos, cfg->clos);

hypervisor/arch/x86/rdt.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
#include <vm_config.h>
1717
#include <msr.h>
1818

19-
struct cat_hw_info cat_cap_info;
19+
struct cat_hw_info cat_cap_info = {false, 0U, 0U, 0U, 0U};
2020
const uint16_t hv_clos = 0U;
21-
static uint16_t platform_clos_num = MAX_PLATFORM_CLOS_NUM;
21+
uint16_t platform_clos_num = MAX_PLATFORM_CLOS_NUM;
2222

2323
int32_t init_cat_cap_info(void)
2424
{
@@ -29,16 +29,16 @@ int32_t init_cat_cap_info(void)
2929
cpuid_subleaf(CPUID_RSD_ALLOCATION, 0, &eax, &ebx, &ecx, &edx);
3030
/* If support L3 CAT, EBX[1] is set */
3131
if ((ebx & 2U) != 0U) {
32+
cat_cap_info.enabled = true;
3233
cat_cap_info.res_id = CAT_RESID_L3;
3334
}
3435

3536
/* If support L2 CAT, EBX[2] is set */
3637
if ((ebx & 4U) != 0U) {
38+
cat_cap_info.enabled = true;
3739
cat_cap_info.res_id = CAT_RESID_L2;
3840
}
3941

40-
cat_cap_info.enabled = true;
41-
4242
/* CPUID.(EAX=0x10,ECX=ResID):EAX[4:0] reports the length of CBM supported
4343
* CPUID.(EAX=0x10,ECX=ResID):EBX[31:0] indicates the corresponding uints
4444
* may be used by other entities such as graphic and H/W outside processor.
@@ -50,23 +50,23 @@ int32_t init_cat_cap_info(void)
5050
cat_cap_info.clos_max = (uint16_t)(edx & 0xffffU);
5151

5252
if ((platform_clos_num != 0U) && ((cat_cap_info.clos_max + 1U) != platform_clos_num)) {
53-
pr_err("%s clos_max:%hu, platform_clos_num:%u\n", __func__, cat_cap_info.clos_max, platform_clos_num);
53+
pr_err("%s clos_max:%hu, platform_clos_num:%u\n",
54+
__func__, cat_cap_info.clos_max, platform_clos_num);
5455
ret = -EINVAL;
5556
}
5657
}
5758

5859
return ret;
5960
}
6061

61-
6262
void setup_clos(uint16_t pcpu_id)
6363
{
6464
uint16_t i;
6565
uint32_t msr_index;
6666
uint64_t val;
6767

6868
if (cat_cap_info.enabled) {
69-
for (i = 0U; i < platform_clos_num; i++) {
69+
for (i = 0; i < platform_clos_num; i++) {
7070
switch (cat_cap_info.res_id) {
7171
case CAT_RESID_L2:
7272
msr_index = platform_l2_clos_array[i].msr_index;
@@ -83,16 +83,21 @@ void setup_clos(uint16_t pcpu_id)
8383
}
8484
}
8585
/* set hypervisor CAT clos */
86-
msr_write_pcpu(MSR_IA32_PQR_ASSOC, clos2prq_msr(hv_clos), pcpu_id);
86+
msr_write_pcpu(MSR_IA32_PQR_ASSOC, clos2pqr_msr(hv_clos), pcpu_id);
8787
}
8888
}
8989

90-
uint64_t clos2prq_msr(uint16_t clos)
90+
uint64_t clos2pqr_msr(uint16_t clos)
9191
{
92-
uint64_t prq_assoc;
92+
uint64_t pqr_assoc;
9393

94-
prq_assoc = msr_read(MSR_IA32_PQR_ASSOC);
95-
prq_assoc = (prq_assoc & 0xffffffffUL) | ((uint64_t)clos << 32U);
94+
pqr_assoc = msr_read(MSR_IA32_PQR_ASSOC);
95+
pqr_assoc = (pqr_assoc & 0xffffffffUL) | ((uint64_t)clos << 32U);
9696

97-
return prq_assoc;
97+
return pqr_assoc;
98+
}
99+
100+
bool is_platform_rdt_capable(void)
101+
{
102+
return cat_cap_info.enabled;
98103
}

hypervisor/include/arch/x86/rdt.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ struct cat_hw_info {
1919

2020
extern struct cat_hw_info cat_cap_info;
2121
extern const uint16_t hv_clos;
22+
extern uint16_t platform_clos_num;
2223
void setup_clos(uint16_t pcpu_id);
2324

25+
2426
#define CAT_RESID_L3 1U
2527
#define CAT_RESID_L2 2U
2628

2729
int32_t init_cat_cap_info(void);
28-
uint64_t clos2prq_msr(uint16_t clos);
30+
uint64_t clos2pqr_msr(uint16_t clos);
31+
bool is_platform_rdt_capable(void);
2932

3033
#endif /* RDT_H */

0 commit comments

Comments
 (0)