Skip to content

Commit bfc08c2

Browse files
ZideChen0acrnsi
authored andcommitted
hv: move msr_bitmap from acrn_vm to acrn_vcpu_arch
At the time the guest is switching to X2APIC mode, different VCPUs in the same VM could expect the setting of the per VM msr_bitmap differently, which could cause problems. Considering different approaches to address this issue: 1) only guest BSP can update msr_bitmap when switching to X2APIC. 2) carefully re-write the update_msr_bitmap_x2apic_xxx() functions to make sure any bit in the bitmap won't be toggled by the VCPUs. 3) make msr_bitmap as per VCPU. We chose option 3) because it's simple and clean, though it takes more memory than other options. BTW, need to remove const modifier from update_msr_bitmap_x2apic_xxx() functions to get it compiled. Tracked-On: #3166 Signed-off-by: Zide Chen <zide.chen@intel.com> Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent f96ae3f commit bfc08c2

File tree

4 files changed

+58
-30
lines changed

4 files changed

+58
-30
lines changed

hypervisor/arch/x86/guest/vmsr.c

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,9 @@ static void intercept_x2apic_msrs(uint8_t *msr_bitmap_arg, uint32_t mode)
279279
}
280280
}
281281

282+
/**
283+
* @pre vcpu != NULL
284+
*/
282285
static void init_msr_area(struct acrn_vcpu *vcpu)
283286
{
284287
vcpu->arch.msr_area.guest[MSR_AREA_TSC_AUX].msr_index = MSR_IA32_TSC_AUX;
@@ -287,47 +290,49 @@ static void init_msr_area(struct acrn_vcpu *vcpu)
287290
vcpu->arch.msr_area.host[MSR_AREA_TSC_AUX].value = vcpu->pcpu_id;
288291
}
289292

293+
/**
294+
* @pre vcpu != NULL
295+
*/
290296
void init_msr_emulation(struct acrn_vcpu *vcpu)
291297
{
298+
uint8_t *msr_bitmap = vcpu->arch.msr_bitmap;
292299
uint32_t msr, i;
293-
uint8_t *msr_bitmap;
294300
uint64_t value64;
295301

296-
if (is_vcpu_bsp(vcpu)) {
297-
msr_bitmap = vcpu->vm->arch_vm.msr_bitmap;
298-
299-
for (i = 0U; i < NUM_GUEST_MSRS; i++) {
300-
enable_msr_interception(msr_bitmap, emulated_guest_msrs[i], INTERCEPT_READ_WRITE);
301-
}
302-
303-
for (i = 0U; i < NUM_MTRR_MSRS; i++) {
304-
enable_msr_interception(msr_bitmap, mtrr_msrs[i], INTERCEPT_READ_WRITE);
305-
}
302+
for (i = 0U; i < NUM_GUEST_MSRS; i++) {
303+
enable_msr_interception(msr_bitmap, emulated_guest_msrs[i], INTERCEPT_READ_WRITE);
304+
}
306305

307-
intercept_x2apic_msrs(msr_bitmap, INTERCEPT_READ_WRITE);
306+
for (i = 0U; i < NUM_MTRR_MSRS; i++) {
307+
enable_msr_interception(msr_bitmap, mtrr_msrs[i], INTERCEPT_READ_WRITE);
308+
}
308309

309-
for (i = 0U; i < NUM_UNSUPPORTED_MSRS; i++) {
310-
enable_msr_interception(msr_bitmap, unsupported_msrs[i], INTERCEPT_READ_WRITE);
311-
}
310+
intercept_x2apic_msrs(msr_bitmap, INTERCEPT_READ_WRITE);
312311

313-
/* RDT-A disabled: CPUID.07H.EBX[12], CPUID.10H */
314-
for (msr = MSR_IA32_L3_MASK_0; msr < MSR_IA32_BNDCFGS; msr++) {
315-
enable_msr_interception(msr_bitmap, msr, INTERCEPT_READ_WRITE);
316-
}
312+
for (i = 0U; i < NUM_UNSUPPORTED_MSRS; i++) {
313+
enable_msr_interception(msr_bitmap, unsupported_msrs[i], INTERCEPT_READ_WRITE);
314+
}
317315

318-
/* don't need to intercept rdmsr for these MSRs */
319-
enable_msr_interception(msr_bitmap, MSR_IA32_TIME_STAMP_COUNTER, INTERCEPT_WRITE);
316+
/* RDT-A disabled: CPUID.07H.EBX[12], CPUID.10H */
317+
for (msr = MSR_IA32_L3_MASK_0; msr < MSR_IA32_BNDCFGS; msr++) {
318+
enable_msr_interception(msr_bitmap, msr, INTERCEPT_READ_WRITE);
320319
}
321320

321+
/* don't need to intercept rdmsr for these MSRs */
322+
enable_msr_interception(msr_bitmap, MSR_IA32_TIME_STAMP_COUNTER, INTERCEPT_WRITE);
323+
322324
/* Setup MSR bitmap - Intel SDM Vol3 24.6.9 */
323-
value64 = hva2hpa(vcpu->vm->arch_vm.msr_bitmap);
325+
value64 = hva2hpa(vcpu->arch.msr_bitmap);
324326
exec_vmwrite64(VMX_MSR_BITMAP_FULL, value64);
325327
pr_dbg("VMX_MSR_BITMAP: 0x%016llx ", value64);
326328

327329
/* Initialize the MSR save/store area */
328330
init_msr_area(vcpu);
329331
}
330332

333+
/**
334+
* @pre vcpu != NULL
335+
*/
331336
int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
332337
{
333338
int32_t err = 0;
@@ -436,6 +441,10 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
436441
* TSC, the logical processor also adds (or subtracts) value X from
437442
* the IA32_TSC_ADJUST MSR.
438443
*/
444+
445+
/**
446+
* @pre vcpu != NULL
447+
*/
439448
static void set_guest_tsc(struct acrn_vcpu *vcpu, uint64_t guest_tsc)
440449
{
441450
uint64_t tsc_delta, tsc_offset_delta, tsc_adjust;
@@ -458,6 +467,10 @@ static void set_guest_tsc(struct acrn_vcpu *vcpu, uint64_t guest_tsc)
458467
* MSR adds (or subtracts) value X from that MSR, the logical
459468
* processor also adds (or subtracts) value X from the TSC."
460469
*/
470+
471+
/**
472+
* @pre vcpu != NULL
473+
*/
461474
static void set_guest_tsc_adjust(struct acrn_vcpu *vcpu, uint64_t tsc_adjust)
462475
{
463476
uint64_t tsc_offset, tsc_adjust_delta;
@@ -473,6 +486,9 @@ static void set_guest_tsc_adjust(struct acrn_vcpu *vcpu, uint64_t tsc_adjust)
473486
vcpu_set_guest_msr(vcpu, MSR_IA32_TSC_ADJUST, tsc_adjust);
474487
}
475488

489+
/**
490+
* @pre vcpu != NULL
491+
*/
476492
static void set_guest_ia32_misc_enalbe(struct acrn_vcpu *vcpu, uint64_t v)
477493
{
478494
uint32_t eax, ebx = 0U, ecx = 0U, edx = 0U;
@@ -520,6 +536,9 @@ static void set_guest_ia32_misc_enalbe(struct acrn_vcpu *vcpu, uint64_t v)
520536
}
521537
}
522538

539+
/**
540+
* @pre vcpu != NULL
541+
*/
523542
int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu)
524543
{
525544
int32_t err = 0;
@@ -630,11 +649,14 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu)
630649
return err;
631650
}
632651

633-
void update_msr_bitmap_x2apic_apicv(const struct acrn_vcpu *vcpu)
652+
/**
653+
* @pre vcpu != NULL
654+
*/
655+
void update_msr_bitmap_x2apic_apicv(struct acrn_vcpu *vcpu)
634656
{
635657
uint8_t *msr_bitmap;
636658

637-
msr_bitmap = vcpu->vm->arch_vm.msr_bitmap;
659+
msr_bitmap = vcpu->arch.msr_bitmap;
638660
/*
639661
* For platforms that do not support register virtualization
640662
* all x2APIC MSRs need to intercepted. So no need to update
@@ -666,9 +688,13 @@ void update_msr_bitmap_x2apic_apicv(const struct acrn_vcpu *vcpu)
666688
* - XAPICID/LDR: Read to XAPICID/LDR need to be trapped to guarantee guest always see right vlapic_id.
667689
* - ICR: Write to ICR need to be trapped to avoid milicious IPI.
668690
*/
669-
void update_msr_bitmap_x2apic_passthru(const struct acrn_vcpu *vcpu)
691+
692+
/**
693+
* @pre vcpu != NULL
694+
*/
695+
void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu)
670696
{
671-
uint8_t *msr_bitmap = vcpu->vm->arch_vm.msr_bitmap;
697+
uint8_t *msr_bitmap = vcpu->arch.msr_bitmap;
672698

673699
intercept_x2apic_msrs(msr_bitmap, INTERCEPT_DISABLE);
674700
enable_msr_interception(msr_bitmap, MSR_IA32_EXT_XAPICID, INTERCEPT_READ);

hypervisor/include/arch/x86/guest/vcpu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ struct msr_store_area {
297297
struct acrn_vcpu_arch {
298298
/* vmcs region for this vcpu, MUST be 4KB-aligned */
299299
uint8_t vmcs[PAGE_SIZE];
300+
301+
/* MSR bitmap region for this vcpu, MUST be 4-Kbyte aligned */
302+
uint8_t msr_bitmap[PAGE_SIZE];
303+
300304
/* per vcpu lapic */
301305
struct acrn_vlapic vlapic;
302306

hypervisor/include/arch/x86/guest/vm.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ enum vm_state {
8989
struct vm_arch {
9090
/* I/O bitmaps A and B for this VM, MUST be 4-Kbyte aligned */
9191
uint8_t io_bitmap[PAGE_SIZE*2];
92-
/* MSR bitmap region for this VM, MUST be 4-Kbyte aligned */
93-
uint8_t msr_bitmap[PAGE_SIZE];
9492

9593
uint64_t guest_init_pml4;/* Guest init pml4 */
9694
/* EPT hierarchy for Normal World */

hypervisor/include/arch/x86/msr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,8 @@ struct acrn_vcpu;
581581

582582
void init_msr_emulation(struct acrn_vcpu *vcpu);
583583
uint32_t vmsr_get_guest_msr_index(uint32_t msr);
584-
void update_msr_bitmap_x2apic_apicv(const struct acrn_vcpu *vcpu);
585-
void update_msr_bitmap_x2apic_passthru(const struct acrn_vcpu *vcpu);
584+
void update_msr_bitmap_x2apic_apicv(struct acrn_vcpu *vcpu);
585+
void update_msr_bitmap_x2apic_passthru(struct acrn_vcpu *vcpu);
586586

587587
#endif /* ASSEMBLER */
588588

0 commit comments

Comments
 (0)