aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/vmx/nested.c72
1 files changed, 44 insertions, 28 deletions
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 153e539c29c9..897d70e3d291 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -500,6 +500,17 @@ static void nested_vmx_disable_intercept_for_msr(unsigned long *msr_bitmap_l1,
500 } 500 }
501} 501}
502 502
503static inline void enable_x2apic_msr_intercepts(unsigned long *msr_bitmap) {
504 int msr;
505
506 for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) {
507 unsigned word = msr / BITS_PER_LONG;
508
509 msr_bitmap[word] = ~0;
510 msr_bitmap[word + (0x800 / sizeof(long))] = ~0;
511 }
512}
513
503/* 514/*
504 * Merge L0's and L1's MSR bitmap, return false to indicate that 515 * Merge L0's and L1's MSR bitmap, return false to indicate that
505 * we do not use the hardware. 516 * we do not use the hardware.
@@ -541,39 +552,44 @@ static inline bool nested_vmx_prepare_msr_bitmap(struct kvm_vcpu *vcpu,
541 return false; 552 return false;
542 553
543 msr_bitmap_l1 = (unsigned long *)kmap(page); 554 msr_bitmap_l1 = (unsigned long *)kmap(page);
544 if (nested_cpu_has_apic_reg_virt(vmcs12)) {
545 /*
546 * L0 need not intercept reads for MSRs between 0x800 and 0x8ff, it
547 * just lets the processor take the value from the virtual-APIC page;
548 * take those 256 bits directly from the L1 bitmap.
549 */
550 for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) {
551 unsigned word = msr / BITS_PER_LONG;
552 msr_bitmap_l0[word] = msr_bitmap_l1[word];
553 msr_bitmap_l0[word + (0x800 / sizeof(long))] = ~0;
554 }
555 } else {
556 for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) {
557 unsigned word = msr / BITS_PER_LONG;
558 msr_bitmap_l0[word] = ~0;
559 msr_bitmap_l0[word + (0x800 / sizeof(long))] = ~0;
560 }
561 }
562 555
563 nested_vmx_disable_intercept_for_msr( 556 /*
564 msr_bitmap_l1, msr_bitmap_l0, 557 * To keep the control flow simple, pay eight 8-byte writes (sixteen
565 X2APIC_MSR(APIC_TASKPRI), 558 * 4-byte writes on 32-bit systems) up front to enable intercepts for
566 MSR_TYPE_W); 559 * the x2APIC MSR range and selectively disable them below.
560 */
561 enable_x2apic_msr_intercepts(msr_bitmap_l0);
562
563 if (nested_cpu_has_virt_x2apic_mode(vmcs12)) {
564 if (nested_cpu_has_apic_reg_virt(vmcs12)) {
565 /*
566 * L0 need not intercept reads for MSRs between 0x800
567 * and 0x8ff, it just lets the processor take the value
568 * from the virtual-APIC page; take those 256 bits
569 * directly from the L1 bitmap.
570 */
571 for (msr = 0x800; msr <= 0x8ff; msr += BITS_PER_LONG) {
572 unsigned word = msr / BITS_PER_LONG;
573
574 msr_bitmap_l0[word] = msr_bitmap_l1[word];
575 }
576 }
567 577
568 if (nested_cpu_has_vid(vmcs12)) {
569 nested_vmx_disable_intercept_for_msr(
570 msr_bitmap_l1, msr_bitmap_l0,
571 X2APIC_MSR(APIC_EOI),
572 MSR_TYPE_W);
573 nested_vmx_disable_intercept_for_msr( 578 nested_vmx_disable_intercept_for_msr(
574 msr_bitmap_l1, msr_bitmap_l0, 579 msr_bitmap_l1, msr_bitmap_l0,
575 X2APIC_MSR(APIC_SELF_IPI), 580 X2APIC_MSR(APIC_TASKPRI),
576 MSR_TYPE_W); 581 MSR_TYPE_W);
582
583 if (nested_cpu_has_vid(vmcs12)) {
584 nested_vmx_disable_intercept_for_msr(
585 msr_bitmap_l1, msr_bitmap_l0,
586 X2APIC_MSR(APIC_EOI),
587 MSR_TYPE_W);
588 nested_vmx_disable_intercept_for_msr(
589 msr_bitmap_l1, msr_bitmap_l0,
590 X2APIC_MSR(APIC_SELF_IPI),
591 MSR_TYPE_W);
592 }
577 } 593 }
578 594
579 if (spec_ctrl) 595 if (spec_ctrl)