diff options
author | Xiao Guangrong <guangrong.xiao@intel.com> | 2015-07-15 15:25:54 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-07-23 02:21:33 -0400 |
commit | 10dc331ff5e7e4668c0f0c95b1a873aba9b70826 (patch) | |
tree | 969d2dea497daa3132ec97647b6c55048e4edc84 | |
parent | c5dfd654d0ec0a28fe81e7bd4d4fd984a9855e09 (diff) |
KVM: MTRR: fix memory type handling if MTRR is completely disabled
Currently code uses default memory type if MTRR is fully disabled,
fix it by using UC instead.
Signed-off-by: Xiao Guangrong <guangrong.xiao@intel.com>
Tested-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/kvm/mtrr.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c index de1d2d8062e2..e2750134a22b 100644 --- a/arch/x86/kvm/mtrr.c +++ b/arch/x86/kvm/mtrr.c | |||
@@ -120,6 +120,16 @@ static u8 mtrr_default_type(struct kvm_mtrr *mtrr_state) | |||
120 | return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK; | 120 | return mtrr_state->deftype & IA32_MTRR_DEF_TYPE_TYPE_MASK; |
121 | } | 121 | } |
122 | 122 | ||
123 | static u8 mtrr_disabled_type(void) | ||
124 | { | ||
125 | /* | ||
126 | * Intel SDM 11.11.2.2: all MTRRs are disabled when | ||
127 | * IA32_MTRR_DEF_TYPE.E bit is cleared, and the UC | ||
128 | * memory type is applied to all of physical memory. | ||
129 | */ | ||
130 | return MTRR_TYPE_UNCACHABLE; | ||
131 | } | ||
132 | |||
123 | /* | 133 | /* |
124 | * Three terms are used in the following code: | 134 | * Three terms are used in the following code: |
125 | * - segment, it indicates the address segments covered by fixed MTRRs. | 135 | * - segment, it indicates the address segments covered by fixed MTRRs. |
@@ -434,6 +444,8 @@ struct mtrr_iter { | |||
434 | 444 | ||
435 | /* output fields. */ | 445 | /* output fields. */ |
436 | int mem_type; | 446 | int mem_type; |
447 | /* mtrr is completely disabled? */ | ||
448 | bool mtrr_disabled; | ||
437 | /* [start, end) is not fully covered in MTRRs? */ | 449 | /* [start, end) is not fully covered in MTRRs? */ |
438 | bool partial_map; | 450 | bool partial_map; |
439 | 451 | ||
@@ -549,7 +561,7 @@ static void mtrr_lookup_var_next(struct mtrr_iter *iter) | |||
549 | static void mtrr_lookup_start(struct mtrr_iter *iter) | 561 | static void mtrr_lookup_start(struct mtrr_iter *iter) |
550 | { | 562 | { |
551 | if (!mtrr_is_enabled(iter->mtrr_state)) { | 563 | if (!mtrr_is_enabled(iter->mtrr_state)) { |
552 | iter->partial_map = true; | 564 | iter->mtrr_disabled = true; |
553 | return; | 565 | return; |
554 | } | 566 | } |
555 | 567 | ||
@@ -563,6 +575,7 @@ static void mtrr_lookup_init(struct mtrr_iter *iter, | |||
563 | iter->mtrr_state = mtrr_state; | 575 | iter->mtrr_state = mtrr_state; |
564 | iter->start = start; | 576 | iter->start = start; |
565 | iter->end = end; | 577 | iter->end = end; |
578 | iter->mtrr_disabled = false; | ||
566 | iter->partial_map = false; | 579 | iter->partial_map = false; |
567 | iter->fixed = false; | 580 | iter->fixed = false; |
568 | iter->range = NULL; | 581 | iter->range = NULL; |
@@ -656,6 +669,9 @@ u8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn) | |||
656 | return MTRR_TYPE_WRBACK; | 669 | return MTRR_TYPE_WRBACK; |
657 | } | 670 | } |
658 | 671 | ||
672 | if (iter.mtrr_disabled) | ||
673 | return mtrr_disabled_type(); | ||
674 | |||
659 | /* It is not covered by MTRRs. */ | 675 | /* It is not covered by MTRRs. */ |
660 | if (iter.partial_map) { | 676 | if (iter.partial_map) { |
661 | /* | 677 | /* |
@@ -689,6 +705,9 @@ bool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn, | |||
689 | return false; | 705 | return false; |
690 | } | 706 | } |
691 | 707 | ||
708 | if (iter.mtrr_disabled) | ||
709 | return true; | ||
710 | |||
692 | if (!iter.partial_map) | 711 | if (!iter.partial_map) |
693 | return true; | 712 | return true; |
694 | 713 | ||