diff options
| -rw-r--r-- | arch/x86/kvm/vmx/nested.c | 72 |
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 | ||
| 503 | static 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) |
