diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 5fa553babe56..fce3ba0f2079 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -110,6 +110,12 @@ struct nested_state { | |||
110 | #define MSRPM_OFFSETS 16 | 110 | #define MSRPM_OFFSETS 16 |
111 | static u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; | 111 | static u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly; |
112 | 112 | ||
113 | /* | ||
114 | * Set osvw_len to higher value when updated Revision Guides | ||
115 | * are published and we know what the new status bits are | ||
116 | */ | ||
117 | static uint64_t osvw_len = 4, osvw_status; | ||
118 | |||
113 | struct vcpu_svm { | 119 | struct vcpu_svm { |
114 | struct kvm_vcpu vcpu; | 120 | struct kvm_vcpu vcpu; |
115 | struct vmcb *vmcb; | 121 | struct vmcb *vmcb; |
@@ -556,6 +562,27 @@ static void svm_init_erratum_383(void) | |||
556 | erratum_383_found = true; | 562 | erratum_383_found = true; |
557 | } | 563 | } |
558 | 564 | ||
565 | static void svm_init_osvw(struct kvm_vcpu *vcpu) | ||
566 | { | ||
567 | /* | ||
568 | * Guests should see errata 400 and 415 as fixed (assuming that | ||
569 | * HLT and IO instructions are intercepted). | ||
570 | */ | ||
571 | vcpu->arch.osvw.length = (osvw_len >= 3) ? (osvw_len) : 3; | ||
572 | vcpu->arch.osvw.status = osvw_status & ~(6ULL); | ||
573 | |||
574 | /* | ||
575 | * By increasing VCPU's osvw.length to 3 we are telling the guest that | ||
576 | * all osvw.status bits inside that length, including bit 0 (which is | ||
577 | * reserved for erratum 298), are valid. However, if host processor's | ||
578 | * osvw_len is 0 then osvw_status[0] carries no information. We need to | ||
579 | * be conservative here and therefore we tell the guest that erratum 298 | ||
580 | * is present (because we really don't know). | ||
581 | */ | ||
582 | if (osvw_len == 0 && boot_cpu_data.x86 == 0x10) | ||
583 | vcpu->arch.osvw.status |= 1; | ||
584 | } | ||
585 | |||
559 | static int has_svm(void) | 586 | static int has_svm(void) |
560 | { | 587 | { |
561 | const char *msg; | 588 | const char *msg; |
@@ -620,6 +647,36 @@ static int svm_hardware_enable(void *garbage) | |||
620 | __get_cpu_var(current_tsc_ratio) = TSC_RATIO_DEFAULT; | 647 | __get_cpu_var(current_tsc_ratio) = TSC_RATIO_DEFAULT; |
621 | } | 648 | } |
622 | 649 | ||
650 | |||
651 | /* | ||
652 | * Get OSVW bits. | ||
653 | * | ||
654 | * Note that it is possible to have a system with mixed processor | ||
655 | * revisions and therefore different OSVW bits. If bits are not the same | ||
656 | * on different processors then choose the worst case (i.e. if erratum | ||
657 | * is present on one processor and not on another then assume that the | ||
658 | * erratum is present everywhere). | ||
659 | */ | ||
660 | if (cpu_has(&boot_cpu_data, X86_FEATURE_OSVW)) { | ||
661 | uint64_t len, status = 0; | ||
662 | int err; | ||
663 | |||
664 | len = native_read_msr_safe(MSR_AMD64_OSVW_ID_LENGTH, &err); | ||
665 | if (!err) | ||
666 | status = native_read_msr_safe(MSR_AMD64_OSVW_STATUS, | ||
667 | &err); | ||
668 | |||
669 | if (err) | ||
670 | osvw_status = osvw_len = 0; | ||
671 | else { | ||
672 | if (len < osvw_len) | ||
673 | osvw_len = len; | ||
674 | osvw_status |= status; | ||
675 | osvw_status &= (1ULL << osvw_len) - 1; | ||
676 | } | ||
677 | } else | ||
678 | osvw_status = osvw_len = 0; | ||
679 | |||
623 | svm_init_erratum_383(); | 680 | svm_init_erratum_383(); |
624 | 681 | ||
625 | return 0; | 682 | return 0; |
@@ -1186,6 +1243,8 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
1186 | if (kvm_vcpu_is_bsp(&svm->vcpu)) | 1243 | if (kvm_vcpu_is_bsp(&svm->vcpu)) |
1187 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; | 1244 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; |
1188 | 1245 | ||
1246 | svm_init_osvw(&svm->vcpu); | ||
1247 | |||
1189 | return &svm->vcpu; | 1248 | return &svm->vcpu; |
1190 | 1249 | ||
1191 | free_page4: | 1250 | free_page4: |