@@ -542,35 +542,24 @@ static int has_svm(void)
542542 return static_cpu_has (X86_FEATURE_SVM );
543543}
544544
545- static inline void cpu_svm_disable (void )
546- {
547- uint64_t efer ;
548-
549- wrmsrl (MSR_VM_HSAVE_PA , 0 );
550- rdmsrl (MSR_EFER , efer );
551- wrmsrl (MSR_EFER , efer & ~EFER_SVME );
552- }
553-
554545static void svm_hardware_disable (void )
555546{
556- cpu_svm_disable ();
557-
558547 //amd_pmu_disable_virt();
559548}
560549
550+ /*
551+ * This does not turn on SVM as Linus does now, as on Windows coexistence with
552+ * other VMMs is important and requires turning on/off SVM dynamically at run
553+ * time.
554+ */
561555static int svm_hardware_enable (void )
562556{
563557
564558 struct svm_cpu_data * sd ;
565- uint64_t efer ;
566559 struct desc_ptr gdt_descr ;
567560 struct desc_struct * gdt ;
568561 int me = raw_smp_processor_id ();
569562
570- rdmsrl (MSR_EFER , efer );
571- if (efer & EFER_SVME )
572- return - EBUSY ;
573-
574563 if (!has_svm ()) {
575564 pr_err ("%s: err EOPNOTSUPP on %d\n" , __func__ , me );
576565 return - EINVAL ;
@@ -589,11 +578,6 @@ static int svm_hardware_enable(void)
589578 gdt = (struct desc_struct * )gdt_descr .address ;
590579 sd -> tss_desc = (struct kvm_ldttss_desc * )(gdt + GDT_ENTRY_TSS );
591580
592- wrmsrl (MSR_EFER , efer | EFER_SVME );
593-
594- wrmsrl (MSR_VM_HSAVE_PA , page_to_pfn (sd -> save_area ) << PAGE_SHIFT );
595-
596-
597581 /*
598582 * Get OSVW bits.
599583 *
@@ -4220,6 +4204,10 @@ static void svm_cancel_injection(struct kvm_vcpu *vcpu)
42204204static void svm_vcpu_run (struct kvm_vcpu * vcpu )
42214205{
42224206 struct vcpu_svm * svm = to_svm (vcpu );
4207+ int me = raw_smp_processor_id ();
4208+ struct svm_cpu_data * sd ;
4209+ uint64_t efer , hsave_pa = 0 ;
4210+ uint64_t svm_enabled ;
42234211
42244212 svm -> vmcb -> save .rax = vcpu -> arch .regs [VCPU_REGS_RAX ];
42254213 svm -> vmcb -> save .rsp = vcpu -> arch .regs [VCPU_REGS_RSP ];
@@ -4238,6 +4226,15 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
42384226
42394227 svm -> vmcb -> save .cr2 = vcpu -> arch .cr2 ;
42404228
4229+ sd = per_cpu (svm_data , me );
4230+ rdmsrl (MSR_EFER , efer );
4231+ svm_enabled = !!(efer & EFER_SVME );
4232+ if (!svm_enabled )
4233+ wrmsrl (MSR_EFER , efer | EFER_SVME );
4234+ else
4235+ rdmsrl (MSR_VM_HSAVE_PA , hsave_pa );
4236+ wrmsrl (MSR_VM_HSAVE_PA , page_to_pfn (sd -> save_area ) << PAGE_SHIFT );
4237+
42414238 clgi ();
42424239
42434240 local_irq_enable ();
@@ -4265,6 +4262,10 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu)
42654262
42664263 stgi ();
42674264
4265+ wrmsrl (MSR_VM_HSAVE_PA , hsave_pa );
4266+ if (!svm_enabled )
4267+ wrmsrl (MSR_EFER , efer );
4268+
42684269 /* Any pending NMI will happen here */
42694270
42704271 if (unlikely (svm -> vmcb -> control .exit_code == SVM_EXIT_NMI ))
0 commit comments