svm.c (267367) | svm.c (270511) |
---|---|
1/*- 2 * Copyright (c) 2013, Anish Gupta (akgupt3@gmail.com) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2013, Anish Gupta (akgupt3@gmail.com) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c 267367 2014-06-11 17:48:07Z neel $"); | 28__FBSDID("$FreeBSD: projects/bhyve_svm/sys/amd64/vmm/amd/svm.c 270511 2014-08-25 00:58:20Z neel $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/smp.h> 33#include <sys/kernel.h> 34#include <sys/malloc.h> 35#include <sys/pcpu.h> 36#include <sys/proc.h> --- 660 unchanged lines hidden (view full) --- 697 info1 = ctrl->exitinfo1; 698 info2 = ctrl->exitinfo2; 699 700 update_rip = true; 701 loop = true; 702 vmexit->exitcode = VM_EXITCODE_VMX; 703 vmexit->u.vmx.status = 0; 704 | 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/smp.h> 33#include <sys/kernel.h> 34#include <sys/malloc.h> 35#include <sys/pcpu.h> 36#include <sys/proc.h> --- 660 unchanged lines hidden (view full) --- 697 info1 = ctrl->exitinfo1; 698 info2 = ctrl->exitinfo2; 699 700 update_rip = true; 701 loop = true; 702 vmexit->exitcode = VM_EXITCODE_VMX; 703 vmexit->u.vmx.status = 0; 704 |
705 KASSERT((ctrl->eventinj & VMCB_EVENTINJ_VALID) == 0, ("%s: event " 706 "injection valid bit is set %#lx", __func__, ctrl->eventinj)); 707 |
|
705 switch (code) { 706 case VMCB_EXIT_MC: /* Machine Check. */ 707 vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_MTRAP, 1); 708 vmexit->exitcode = VM_EXITCODE_MTRAP; 709 loop = false; 710 break; 711 712 case VMCB_EXIT_MSR: /* MSR access. */ --- 212 unchanged lines hidden (view full) --- 925 926 KASSERT(vcpu < svm_sc->vcpu_cnt, ("Guest doesn't have VCPU%d", vcpu)); 927 928 ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu); 929 /* Can't inject another NMI if last one is pending.*/ 930 if (!vm_nmi_pending(svm_sc->vm, vcpu)) 931 return (0); 932 | 708 switch (code) { 709 case VMCB_EXIT_MC: /* Machine Check. */ 710 vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_MTRAP, 1); 711 vmexit->exitcode = VM_EXITCODE_MTRAP; 712 loop = false; 713 break; 714 715 case VMCB_EXIT_MSR: /* MSR access. */ --- 212 unchanged lines hidden (view full) --- 928 929 KASSERT(vcpu < svm_sc->vcpu_cnt, ("Guest doesn't have VCPU%d", vcpu)); 930 931 ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu); 932 /* Can't inject another NMI if last one is pending.*/ 933 if (!vm_nmi_pending(svm_sc->vm, vcpu)) 934 return (0); 935 |
933 /* Inject NMI, vector number is not used.*/ 934 if (vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_NMI, IDT_NMI, 0, false)) { 935 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:NMI injection failed.\n"); 936 return (EIO); 937 } | 936 /* Inject NMI, vector number is not used.*/ 937 vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_NMI, IDT_NMI, 0, false); |
938 939 /* Acknowledge the request is accepted.*/ 940 vm_nmi_clear(svm_sc->vm, vcpu); 941 942 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:Injected NMI.\n"); 943 944 return (1); 945} --- 10 unchanged lines hidden (view full) --- 956 int extint_pending; 957 int vector; 958 959 KASSERT(vcpu < svm_sc->vcpu_cnt, ("Guest doesn't have VCPU%d", vcpu)); 960 961 state = svm_get_vmcb_state(svm_sc, vcpu); 962 ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu); 963 | 938 939 /* Acknowledge the request is accepted.*/ 940 vm_nmi_clear(svm_sc->vm, vcpu); 941 942 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:Injected NMI.\n"); 943 944 return (1); 945} --- 10 unchanged lines hidden (view full) --- 956 int extint_pending; 957 int vector; 958 959 KASSERT(vcpu < svm_sc->vcpu_cnt, ("Guest doesn't have VCPU%d", vcpu)); 960 961 state = svm_get_vmcb_state(svm_sc, vcpu); 962 ctrl = svm_get_vmcb_ctrl(svm_sc, vcpu); 963 |
964 if (vm_exception_pending(svm_sc->vm, vcpu, &exc)) { 965 KASSERT(exc.vector >= 0 && exc.vector < 32, 966 ("Exception vector% invalid", exc.vector)); 967 vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_EXCEPTION, exc.vector, 968 exc.error_code, exc.error_code_valid); 969 } 970 |
|
964 /* Can't inject multiple events at once. */ 965 if (ctrl->eventinj & VMCB_EVENTINJ_VALID) { 966 VCPU_CTR1(svm_sc->vm, vcpu, 967 "SVM:Last event(0x%lx) is pending.\n", ctrl->eventinj); 968 return ; 969 } 970 971 /* Wait for guest to come out of interrupt shadow. */ 972 if (ctrl->intr_shadow) { 973 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:Guest in interrupt shadow.\n"); 974 return; 975 } | 971 /* Can't inject multiple events at once. */ 972 if (ctrl->eventinj & VMCB_EVENTINJ_VALID) { 973 VCPU_CTR1(svm_sc->vm, vcpu, 974 "SVM:Last event(0x%lx) is pending.\n", ctrl->eventinj); 975 return ; 976 } 977 978 /* Wait for guest to come out of interrupt shadow. */ 979 if (ctrl->intr_shadow) { 980 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:Guest in interrupt shadow.\n"); 981 return; 982 } |
976 977 if (vm_exception_pending(svm_sc->vm, vcpu, &exc)) { 978 KASSERT(exc.vector >= 0 && exc.vector < 32, 979 ("Exception vector% invalid", exc.vector)); 980 if (vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_EXCEPTION, 981 exc.vector, exc.error_code, 982 exc.error_code_valid)) { 983 VCPU_CTR1(svm_sc->vm, vcpu, "SVM:Exception%d injection" 984 " failed.\n", exc.vector); 985 return; 986 } 987 } | 983 |
988 /* NMI event has priority over interrupts.*/ 989 if (svm_inject_nmi(svm_sc, vcpu)) { 990 return; 991 } 992 993 extint_pending = vm_extint_pending(svm_sc->vm, vcpu); 994 995 if (!extint_pending) { --- 12 unchanged lines hidden (view full) --- 1008 return; 1009 } 1010 1011 if ((state->rflags & PSL_I) == 0) { 1012 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:Interrupt is disabled\n"); 1013 return; 1014 } 1015 | 984 /* NMI event has priority over interrupts.*/ 985 if (svm_inject_nmi(svm_sc, vcpu)) { 986 return; 987 } 988 989 extint_pending = vm_extint_pending(svm_sc->vm, vcpu); 990 991 if (!extint_pending) { --- 12 unchanged lines hidden (view full) --- 1004 return; 1005 } 1006 1007 if ((state->rflags & PSL_I) == 0) { 1008 VCPU_CTR0(svm_sc->vm, vcpu, "SVM:Interrupt is disabled\n"); 1009 return; 1010 } 1011 |
1016 if (vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_INTR, vector, 0, false)) { 1017 VCPU_CTR1(svm_sc->vm, vcpu, "SVM:Event injection failed to" 1018 " vector=%d.\n", vector); 1019 return; 1020 } | 1012 vmcb_eventinject(ctrl, VMCB_EVENTINJ_TYPE_INTR, vector, 0, false); |
1021 1022 if (!extint_pending) { 1023 /* Update the Local APIC ISR */ 1024 vlapic_intr_accepted(vlapic, vector); 1025 } else { 1026 vm_extint_clear(svm_sc->vm, vcpu); 1027 vatpic_intr_accepted(svm_sc->vm, vector); 1028 --- 33 unchanged lines hidden (view full) --- 1062 1063 /* 1064 * VMEXIT while delivering an exception or interrupt. 1065 * Inject it as virtual interrupt. 1066 * Section 15.7.2 Intercepts during IDT interrupt delivery. 1067 */ 1068 intinfo = ctrl->exitintinfo; 1069 | 1013 1014 if (!extint_pending) { 1015 /* Update the Local APIC ISR */ 1016 vlapic_intr_accepted(vlapic, vector); 1017 } else { 1018 vm_extint_clear(svm_sc->vm, vcpu); 1019 vatpic_intr_accepted(svm_sc->vm, vector); 1020 --- 33 unchanged lines hidden (view full) --- 1054 1055 /* 1056 * VMEXIT while delivering an exception or interrupt. 1057 * Inject it as virtual interrupt. 1058 * Section 15.7.2 Intercepts during IDT interrupt delivery. 1059 */ 1060 intinfo = ctrl->exitintinfo; 1061 |
1070 if (intinfo & VMCB_EXITINTINFO_VALID) { | 1062 if (VMCB_EXITINTINFO_VALID(intinfo)) { |
1071 vmm_stat_incr(svm_sc->vm, vcpu, VCPU_EXITINTINFO, 1); 1072 VCPU_CTR1(svm_sc->vm, vcpu, "SVM:EXITINTINFO:0x%lx is valid\n", 1073 intinfo); | 1063 vmm_stat_incr(svm_sc->vm, vcpu, VCPU_EXITINTINFO, 1); 1064 VCPU_CTR1(svm_sc->vm, vcpu, "SVM:EXITINTINFO:0x%lx is valid\n", 1065 intinfo); |
1074 if (vmcb_eventinject(ctrl, VMCB_EXITINTINFO_TYPE(intinfo), 1075 VMCB_EXITINTINFO_VECTOR(intinfo), 1076 VMCB_EXITINTINFO_EC(intinfo), 1077 VMCB_EXITINTINFO_EC_VALID & intinfo)) { 1078 VCPU_CTR1(svm_sc->vm, vcpu, "SVM:couldn't inject pending" 1079 " interrupt, exitintinfo:0x%lx\n", intinfo); 1080 } | 1066 vmcb_eventinject(ctrl, VMCB_EXITINTINFO_TYPE(intinfo), 1067 VMCB_EXITINTINFO_VECTOR(intinfo), 1068 VMCB_EXITINTINFO_EC(intinfo), 1069 VMCB_EXITINTINFO_EC_VALID(intinfo)); |
1081 } 1082} 1083/* 1084 * Start vcpu with specified RIP. 1085 */ 1086static int 1087svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t pmap, 1088 void *rend_cookie, void *suspended_cookie) --- 104 unchanged lines hidden (view full) --- 1193 vmexit->rip = state->rip; 1194 break; 1195 } 1196 1197 (void)svm_set_vmcb(svm_get_vmcb(svm_sc, vcpu), svm_sc->asid); 1198 1199 svm_handle_exitintinfo(svm_sc, vcpu); 1200 | 1070 } 1071} 1072/* 1073 * Start vcpu with specified RIP. 1074 */ 1075static int 1076svm_vmrun(void *arg, int vcpu, register_t rip, pmap_t pmap, 1077 void *rend_cookie, void *suspended_cookie) --- 104 unchanged lines hidden (view full) --- 1182 vmexit->rip = state->rip; 1183 break; 1184 } 1185 1186 (void)svm_set_vmcb(svm_get_vmcb(svm_sc, vcpu), svm_sc->asid); 1187 1188 svm_handle_exitintinfo(svm_sc, vcpu); 1189 |
1201 (void)svm_inj_interrupts(svm_sc, vcpu, vlapic); | 1190 svm_inj_interrupts(svm_sc, vcpu, vlapic); |
1202 1203 /* Change TSS type to available.*/ 1204 setup_tss_type(); 1205 1206 /* Launch Virtual Machine. */ 1207 svm_launch(vmcb_pa, gctx, hctx); 1208 1209 /* --- 372 unchanged lines hidden --- | 1191 1192 /* Change TSS type to available.*/ 1193 setup_tss_type(); 1194 1195 /* Launch Virtual Machine. */ 1196 svm_launch(vmcb_pa, gctx, hctx); 1197 1198 /* --- 372 unchanged lines hidden --- |