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