Deleted Added
full compact
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 ---