Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added full device support
[palacios.git] / palacios / src / palacios / svm_handler.c
1 #include <palacios/svm_handler.h>
2 #include <palacios/vmm.h>
3 #include <palacios/vm_guest_mem.h>
4 #include <palacios/vmm_emulate.h>
5 #include <palacios/svm_ctrl_regs.h>
6 #include <palacios/svm_io.h>
7 #include <palacios/vmm_intr.h>
8
9 extern struct vmm_os_hooks * os_hooks;
10
11
12 int handle_svm_exit(struct guest_info * info) {
13   vmcb_ctrl_t * guest_ctrl = 0;
14   vmcb_saved_state_t * guest_state = 0;
15   ulong_t exit_code = 0;
16   
17   guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
18   guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
19   
20
21   // Update the high level state 
22   info->rip = guest_state->rip;
23   info->vm_regs.rsp = guest_state->rsp;
24   info->vm_regs.rax = guest_state->rax;
25   info->vm_regs.rsp = guest_state->rsp;  
26
27
28   exit_code = guest_ctrl->exit_code;
29  
30   // PrintDebugVMCB((vmcb_t*)(info->vmm_data));
31
32   if (exit_code == VMEXIT_IOIO) {
33     struct svm_io_info * io_info = (struct svm_io_info *)&(guest_ctrl->exit_info1);
34     
35     if (io_info->type == 0) {
36       if (io_info->str) {
37         handle_svm_io_outs(info);
38       } else {
39         handle_svm_io_out(info);
40       }
41     } else {
42       if (io_info->str) {
43         handle_svm_io_ins(info);
44       } else {
45         handle_svm_io_in(info);
46       }
47     }
48   } else if (exit_code == VMEXIT_CR0_WRITE) {
49     PrintDebug("CR0 Write\n");
50
51     if (handle_cr0_write(info) == -1) {
52       return -1;
53     }
54     /*
55   } else if (( (exit_code == VMEXIT_CR3_READ)  ||
56                (exit_code == VMEXIT_CR3_WRITE) ||
57                (exit_code == VMEXIT_INVLPG)    ||
58                (exit_code == VMEXIT_INVLPGA)   || 
59                (exit_code == VMEXIT_EXCP14)) && 
60              (info->page_mode == SHADOW_PAGING)) {
61     handle_shadow_paging(info);
62     */
63   } else {
64     addr_t rip_addr = get_addr_linear(info, guest_state->rip, guest_state->cs.selector);
65     char buf[15];
66     addr_t host_addr;
67
68
69     PrintDebug("SVM Returned:(VMCB=%x)\n", info->vmm_data); 
70     PrintDebug("RIP: %x\n", guest_state->rip);
71     PrintDebug("RIP Linear: %x\n", rip_addr);
72     
73     PrintDebug("SVM Returned: Exit Code: %x\n",exit_code); 
74     
75     PrintDebug("io_info1 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info1));
76     PrintDebug("io_info1 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info1)) + 4));
77     
78     PrintDebug("io_info2 low = 0x%.8x\n", *(uint_t*)&(guest_ctrl->exit_info2));
79     PrintDebug("io_info2 high = 0x%.8x\n", *(uint_t *)(((uchar_t *)&(guest_ctrl->exit_info2)) + 4));
80
81     
82
83     if (guest_pa_to_host_pa(info, guest_state->rip, &host_addr) == -1) {
84       PrintDebug("Could not translate guest_state->rip to host address\n");
85       return -1;
86     }
87
88     PrintDebug("Host Address of rip = 0x%x\n", host_addr);
89
90     memset(buf, 0, 15);
91     
92     PrintDebug("Reading from 0x%x in guest\n", rip_addr);
93     
94     read_guest_pa_memory(info, rip_addr, 15, buf);
95
96     PrintTraceMemDump(buf, 15);
97
98     while(1);
99
100   }
101
102
103   // Update the low level state
104
105   if (intr_pending(&(info->intr_state))) {
106     guest_ctrl->EVENTINJ.vector = get_intr_number(&(info->intr_state));
107     guest_ctrl->EVENTINJ.valid = 1;
108  
109     switch (get_intr_type(&(info->intr_state))) {
110     case EXTERNAL_IRQ:
111       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXTERNAL_INTR;
112       break;
113     case NMI:
114       guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
115       break;
116     case EXCEPTION:
117       guest_ctrl->EVENTINJ.type = SVM_INJECTION_EXCEPTION;
118       guest_ctrl->EVENTINJ.error_code = info->intr_state.excp_error_code;
119       break;
120     case SOFTWARE:
121       guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
122       break;
123     case VIRTUAL:
124       guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
125       break;
126
127     case INVALID_INTR: 
128     default:
129       PrintDebug("Attempted to issue an invalid interrupt\n");
130       return -1;
131     }
132
133     // IMPORTANT TODO
134     // We need to figure out stack parameters....
135
136     //EVENTINJ.error_code
137
138   }
139
140   guest_state->rax = info->vm_regs.rax;
141   guest_state->rip = info->rip;
142   guest_state->rsp = info->vm_regs.rsp;
143
144   return 0;
145 }
146
147
148
149
150 int handle_shadow_paging(struct guest_info * info) {
151   vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
152   //  vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data));
153
154   if (guest_ctrl->exit_code == VMEXIT_CR3_READ) {
155
156   }
157
158   return 0;
159 }
160
161
162