diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 138 |
1 files changed, 121 insertions, 17 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ce438e0fdd26..56c9b6bd7655 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * AMD SVM support | 4 | * AMD SVM support |
5 | * | 5 | * |
6 | * Copyright (C) 2006 Qumranet, Inc. | 6 | * Copyright (C) 2006 Qumranet, Inc. |
7 | * Copyright 2010 Red Hat, Inc. and/or its affilates. | ||
7 | * | 8 | * |
8 | * Authors: | 9 | * Authors: |
9 | * Yaniv Kamay <yaniv@qumranet.com> | 10 | * Yaniv Kamay <yaniv@qumranet.com> |
@@ -285,11 +286,11 @@ static inline void flush_guest_tlb(struct kvm_vcpu *vcpu) | |||
285 | 286 | ||
286 | static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) | 287 | static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) |
287 | { | 288 | { |
289 | vcpu->arch.efer = efer; | ||
288 | if (!npt_enabled && !(efer & EFER_LMA)) | 290 | if (!npt_enabled && !(efer & EFER_LMA)) |
289 | efer &= ~EFER_LME; | 291 | efer &= ~EFER_LME; |
290 | 292 | ||
291 | to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; | 293 | to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; |
292 | vcpu->arch.efer = efer; | ||
293 | } | 294 | } |
294 | 295 | ||
295 | static int is_external_interrupt(u32 info) | 296 | static int is_external_interrupt(u32 info) |
@@ -640,7 +641,7 @@ static __init int svm_hardware_setup(void) | |||
640 | 641 | ||
641 | if (nested) { | 642 | if (nested) { |
642 | printk(KERN_INFO "kvm: Nested Virtualization enabled\n"); | 643 | printk(KERN_INFO "kvm: Nested Virtualization enabled\n"); |
643 | kvm_enable_efer_bits(EFER_SVME); | 644 | kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE); |
644 | } | 645 | } |
645 | 646 | ||
646 | for_each_possible_cpu(cpu) { | 647 | for_each_possible_cpu(cpu) { |
@@ -806,7 +807,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
806 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. | 807 | * svm_set_cr0() sets PG and WP and clears NW and CD on save->cr0. |
807 | */ | 808 | */ |
808 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; | 809 | svm->vcpu.arch.cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET; |
809 | kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0); | 810 | (void)kvm_set_cr0(&svm->vcpu, svm->vcpu.arch.cr0); |
810 | 811 | ||
811 | save->cr4 = X86_CR4_PAE; | 812 | save->cr4 = X86_CR4_PAE; |
812 | /* rdx = ?? */ | 813 | /* rdx = ?? */ |
@@ -903,13 +904,18 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
903 | svm->asid_generation = 0; | 904 | svm->asid_generation = 0; |
904 | init_vmcb(svm); | 905 | init_vmcb(svm); |
905 | 906 | ||
906 | fx_init(&svm->vcpu); | 907 | err = fx_init(&svm->vcpu); |
908 | if (err) | ||
909 | goto free_page4; | ||
910 | |||
907 | svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; | 911 | svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; |
908 | if (kvm_vcpu_is_bsp(&svm->vcpu)) | 912 | if (kvm_vcpu_is_bsp(&svm->vcpu)) |
909 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; | 913 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; |
910 | 914 | ||
911 | return &svm->vcpu; | 915 | return &svm->vcpu; |
912 | 916 | ||
917 | free_page4: | ||
918 | __free_page(hsave_page); | ||
913 | free_page3: | 919 | free_page3: |
914 | __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); | 920 | __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER); |
915 | free_page2: | 921 | free_page2: |
@@ -1488,7 +1494,7 @@ static void svm_handle_mce(struct vcpu_svm *svm) | |||
1488 | */ | 1494 | */ |
1489 | pr_err("KVM: Guest triggered AMD Erratum 383\n"); | 1495 | pr_err("KVM: Guest triggered AMD Erratum 383\n"); |
1490 | 1496 | ||
1491 | set_bit(KVM_REQ_TRIPLE_FAULT, &svm->vcpu.requests); | 1497 | kvm_make_request(KVM_REQ_TRIPLE_FAULT, &svm->vcpu); |
1492 | 1498 | ||
1493 | return; | 1499 | return; |
1494 | } | 1500 | } |
@@ -1535,7 +1541,7 @@ static int io_interception(struct vcpu_svm *svm) | |||
1535 | string = (io_info & SVM_IOIO_STR_MASK) != 0; | 1541 | string = (io_info & SVM_IOIO_STR_MASK) != 0; |
1536 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; | 1542 | in = (io_info & SVM_IOIO_TYPE_MASK) != 0; |
1537 | if (string || in) | 1543 | if (string || in) |
1538 | return !(emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DO_MMIO); | 1544 | return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; |
1539 | 1545 | ||
1540 | port = io_info >> 16; | 1546 | port = io_info >> 16; |
1541 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; | 1547 | size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT; |
@@ -1957,7 +1963,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) | |||
1957 | svm->vmcb->save.cr3 = hsave->save.cr3; | 1963 | svm->vmcb->save.cr3 = hsave->save.cr3; |
1958 | svm->vcpu.arch.cr3 = hsave->save.cr3; | 1964 | svm->vcpu.arch.cr3 = hsave->save.cr3; |
1959 | } else { | 1965 | } else { |
1960 | kvm_set_cr3(&svm->vcpu, hsave->save.cr3); | 1966 | (void)kvm_set_cr3(&svm->vcpu, hsave->save.cr3); |
1961 | } | 1967 | } |
1962 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, hsave->save.rax); | 1968 | kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, hsave->save.rax); |
1963 | kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, hsave->save.rsp); | 1969 | kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, hsave->save.rsp); |
@@ -2080,7 +2086,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
2080 | svm->vmcb->save.cr3 = nested_vmcb->save.cr3; | 2086 | svm->vmcb->save.cr3 = nested_vmcb->save.cr3; |
2081 | svm->vcpu.arch.cr3 = nested_vmcb->save.cr3; | 2087 | svm->vcpu.arch.cr3 = nested_vmcb->save.cr3; |
2082 | } else | 2088 | } else |
2083 | kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); | 2089 | (void)kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3); |
2084 | 2090 | ||
2085 | /* Guest paging mode is active - reset mmu */ | 2091 | /* Guest paging mode is active - reset mmu */ |
2086 | kvm_mmu_reset_context(&svm->vcpu); | 2092 | kvm_mmu_reset_context(&svm->vcpu); |
@@ -2386,16 +2392,12 @@ static int iret_interception(struct vcpu_svm *svm) | |||
2386 | 2392 | ||
2387 | static int invlpg_interception(struct vcpu_svm *svm) | 2393 | static int invlpg_interception(struct vcpu_svm *svm) |
2388 | { | 2394 | { |
2389 | if (emulate_instruction(&svm->vcpu, 0, 0, 0) != EMULATE_DONE) | 2395 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; |
2390 | pr_unimpl(&svm->vcpu, "%s: failed\n", __func__); | ||
2391 | return 1; | ||
2392 | } | 2396 | } |
2393 | 2397 | ||
2394 | static int emulate_on_interception(struct vcpu_svm *svm) | 2398 | static int emulate_on_interception(struct vcpu_svm *svm) |
2395 | { | 2399 | { |
2396 | if (emulate_instruction(&svm->vcpu, 0, 0, 0) != EMULATE_DONE) | 2400 | return emulate_instruction(&svm->vcpu, 0, 0, 0) == EMULATE_DONE; |
2397 | pr_unimpl(&svm->vcpu, "%s: failed\n", __func__); | ||
2398 | return 1; | ||
2399 | } | 2401 | } |
2400 | 2402 | ||
2401 | static int cr8_write_interception(struct vcpu_svm *svm) | 2403 | static int cr8_write_interception(struct vcpu_svm *svm) |
@@ -2726,6 +2728,99 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2726 | [SVM_EXIT_NPF] = pf_interception, | 2728 | [SVM_EXIT_NPF] = pf_interception, |
2727 | }; | 2729 | }; |
2728 | 2730 | ||
2731 | void dump_vmcb(struct kvm_vcpu *vcpu) | ||
2732 | { | ||
2733 | struct vcpu_svm *svm = to_svm(vcpu); | ||
2734 | struct vmcb_control_area *control = &svm->vmcb->control; | ||
2735 | struct vmcb_save_area *save = &svm->vmcb->save; | ||
2736 | |||
2737 | pr_err("VMCB Control Area:\n"); | ||
2738 | pr_err("cr_read: %04x\n", control->intercept_cr_read); | ||
2739 | pr_err("cr_write: %04x\n", control->intercept_cr_write); | ||
2740 | pr_err("dr_read: %04x\n", control->intercept_dr_read); | ||
2741 | pr_err("dr_write: %04x\n", control->intercept_dr_write); | ||
2742 | pr_err("exceptions: %08x\n", control->intercept_exceptions); | ||
2743 | pr_err("intercepts: %016llx\n", control->intercept); | ||
2744 | pr_err("pause filter count: %d\n", control->pause_filter_count); | ||
2745 | pr_err("iopm_base_pa: %016llx\n", control->iopm_base_pa); | ||
2746 | pr_err("msrpm_base_pa: %016llx\n", control->msrpm_base_pa); | ||
2747 | pr_err("tsc_offset: %016llx\n", control->tsc_offset); | ||
2748 | pr_err("asid: %d\n", control->asid); | ||
2749 | pr_err("tlb_ctl: %d\n", control->tlb_ctl); | ||
2750 | pr_err("int_ctl: %08x\n", control->int_ctl); | ||
2751 | pr_err("int_vector: %08x\n", control->int_vector); | ||
2752 | pr_err("int_state: %08x\n", control->int_state); | ||
2753 | pr_err("exit_code: %08x\n", control->exit_code); | ||
2754 | pr_err("exit_info1: %016llx\n", control->exit_info_1); | ||
2755 | pr_err("exit_info2: %016llx\n", control->exit_info_2); | ||
2756 | pr_err("exit_int_info: %08x\n", control->exit_int_info); | ||
2757 | pr_err("exit_int_info_err: %08x\n", control->exit_int_info_err); | ||
2758 | pr_err("nested_ctl: %lld\n", control->nested_ctl); | ||
2759 | pr_err("nested_cr3: %016llx\n", control->nested_cr3); | ||
2760 | pr_err("event_inj: %08x\n", control->event_inj); | ||
2761 | pr_err("event_inj_err: %08x\n", control->event_inj_err); | ||
2762 | pr_err("lbr_ctl: %lld\n", control->lbr_ctl); | ||
2763 | pr_err("next_rip: %016llx\n", control->next_rip); | ||
2764 | pr_err("VMCB State Save Area:\n"); | ||
2765 | pr_err("es: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2766 | save->es.selector, save->es.attrib, | ||
2767 | save->es.limit, save->es.base); | ||
2768 | pr_err("cs: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2769 | save->cs.selector, save->cs.attrib, | ||
2770 | save->cs.limit, save->cs.base); | ||
2771 | pr_err("ss: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2772 | save->ss.selector, save->ss.attrib, | ||
2773 | save->ss.limit, save->ss.base); | ||
2774 | pr_err("ds: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2775 | save->ds.selector, save->ds.attrib, | ||
2776 | save->ds.limit, save->ds.base); | ||
2777 | pr_err("fs: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2778 | save->fs.selector, save->fs.attrib, | ||
2779 | save->fs.limit, save->fs.base); | ||
2780 | pr_err("gs: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2781 | save->gs.selector, save->gs.attrib, | ||
2782 | save->gs.limit, save->gs.base); | ||
2783 | pr_err("gdtr: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2784 | save->gdtr.selector, save->gdtr.attrib, | ||
2785 | save->gdtr.limit, save->gdtr.base); | ||
2786 | pr_err("ldtr: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2787 | save->ldtr.selector, save->ldtr.attrib, | ||
2788 | save->ldtr.limit, save->ldtr.base); | ||
2789 | pr_err("idtr: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2790 | save->idtr.selector, save->idtr.attrib, | ||
2791 | save->idtr.limit, save->idtr.base); | ||
2792 | pr_err("tr: s: %04x a: %04x l: %08x b: %016llx\n", | ||
2793 | save->tr.selector, save->tr.attrib, | ||
2794 | save->tr.limit, save->tr.base); | ||
2795 | pr_err("cpl: %d efer: %016llx\n", | ||
2796 | save->cpl, save->efer); | ||
2797 | pr_err("cr0: %016llx cr2: %016llx\n", | ||
2798 | save->cr0, save->cr2); | ||
2799 | pr_err("cr3: %016llx cr4: %016llx\n", | ||
2800 | save->cr3, save->cr4); | ||
2801 | pr_err("dr6: %016llx dr7: %016llx\n", | ||
2802 | save->dr6, save->dr7); | ||
2803 | pr_err("rip: %016llx rflags: %016llx\n", | ||
2804 | save->rip, save->rflags); | ||
2805 | pr_err("rsp: %016llx rax: %016llx\n", | ||
2806 | save->rsp, save->rax); | ||
2807 | pr_err("star: %016llx lstar: %016llx\n", | ||
2808 | save->star, save->lstar); | ||
2809 | pr_err("cstar: %016llx sfmask: %016llx\n", | ||
2810 | save->cstar, save->sfmask); | ||
2811 | pr_err("kernel_gs_base: %016llx sysenter_cs: %016llx\n", | ||
2812 | save->kernel_gs_base, save->sysenter_cs); | ||
2813 | pr_err("sysenter_esp: %016llx sysenter_eip: %016llx\n", | ||
2814 | save->sysenter_esp, save->sysenter_eip); | ||
2815 | pr_err("gpat: %016llx dbgctl: %016llx\n", | ||
2816 | save->g_pat, save->dbgctl); | ||
2817 | pr_err("br_from: %016llx br_to: %016llx\n", | ||
2818 | save->br_from, save->br_to); | ||
2819 | pr_err("excp_from: %016llx excp_to: %016llx\n", | ||
2820 | save->last_excp_from, save->last_excp_to); | ||
2821 | |||
2822 | } | ||
2823 | |||
2729 | static int handle_exit(struct kvm_vcpu *vcpu) | 2824 | static int handle_exit(struct kvm_vcpu *vcpu) |
2730 | { | 2825 | { |
2731 | struct vcpu_svm *svm = to_svm(vcpu); | 2826 | struct vcpu_svm *svm = to_svm(vcpu); |
@@ -2770,6 +2865,8 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
2770 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; | 2865 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
2771 | kvm_run->fail_entry.hardware_entry_failure_reason | 2866 | kvm_run->fail_entry.hardware_entry_failure_reason |
2772 | = svm->vmcb->control.exit_code; | 2867 | = svm->vmcb->control.exit_code; |
2868 | pr_err("KVM: FAILED VMRUN WITH VMCB:\n"); | ||
2869 | dump_vmcb(vcpu); | ||
2773 | return 0; | 2870 | return 0; |
2774 | } | 2871 | } |
2775 | 2872 | ||
@@ -2826,9 +2923,6 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq) | |||
2826 | { | 2923 | { |
2827 | struct vmcb_control_area *control; | 2924 | struct vmcb_control_area *control; |
2828 | 2925 | ||
2829 | trace_kvm_inj_virq(irq); | ||
2830 | |||
2831 | ++svm->vcpu.stat.irq_injections; | ||
2832 | control = &svm->vmcb->control; | 2926 | control = &svm->vmcb->control; |
2833 | control->int_vector = irq; | 2927 | control->int_vector = irq; |
2834 | control->int_ctl &= ~V_INTR_PRIO_MASK; | 2928 | control->int_ctl &= ~V_INTR_PRIO_MASK; |
@@ -2842,6 +2936,9 @@ static void svm_set_irq(struct kvm_vcpu *vcpu) | |||
2842 | 2936 | ||
2843 | BUG_ON(!(gif_set(svm))); | 2937 | BUG_ON(!(gif_set(svm))); |
2844 | 2938 | ||
2939 | trace_kvm_inj_virq(vcpu->arch.interrupt.nr); | ||
2940 | ++vcpu->stat.irq_injections; | ||
2941 | |||
2845 | svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr | | 2942 | svm->vmcb->control.event_inj = vcpu->arch.interrupt.nr | |
2846 | SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR; | 2943 | SVM_EVTINJ_VALID | SVM_EVTINJ_TYPE_INTR; |
2847 | } | 2944 | } |
@@ -3327,6 +3424,11 @@ static bool svm_rdtscp_supported(void) | |||
3327 | return false; | 3424 | return false; |
3328 | } | 3425 | } |
3329 | 3426 | ||
3427 | static bool svm_has_wbinvd_exit(void) | ||
3428 | { | ||
3429 | return true; | ||
3430 | } | ||
3431 | |||
3330 | static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) | 3432 | static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) |
3331 | { | 3433 | { |
3332 | struct vcpu_svm *svm = to_svm(vcpu); | 3434 | struct vcpu_svm *svm = to_svm(vcpu); |
@@ -3411,6 +3513,8 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
3411 | .rdtscp_supported = svm_rdtscp_supported, | 3513 | .rdtscp_supported = svm_rdtscp_supported, |
3412 | 3514 | ||
3413 | .set_supported_cpuid = svm_set_supported_cpuid, | 3515 | .set_supported_cpuid = svm_set_supported_cpuid, |
3516 | |||
3517 | .has_wbinvd_exit = svm_has_wbinvd_exit, | ||
3414 | }; | 3518 | }; |
3415 | 3519 | ||
3416 | static int __init svm_init(void) | 3520 | static int __init svm_init(void) |