2 #include <palacios/vmx_io.h>
3 #include <palacios/vmm_io.h>
4 #include <palacios/vmcs.h>
5 #include <palacios/vmx_lowlevel.h>
6 #include <palacios/vmm.h>
7 #include <palacios/vmx_handler.h>
10 static int update_map(struct guest_info * info, uint16_t port, int hook_read, int hook_write)
12 uchar_t * bitmap = (uint8_t *)(info->io_map.arch_data);
16 if ((hook_read == 0) && (hook_write == 0)) {
17 *(bitmap + major) &= ~(0x1 << minor);
19 *(bitmap + major) |= (0x1 << minor);
25 int v3_init_vmx_io_map(struct guest_info * info)
27 info->io_map.update_map = update_map;
29 info->io_map.arch_data = V3_VAddr(V3_AllocPages(2));
30 memset(info->io_map.arch_data, 0, PAGE_SIZE_4KB*2);
35 int v3_handle_vmx_io_in(struct guest_info * info)
39 vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
41 struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
43 struct v3_io_hook * hook = v3_get_io_hook(info,io_qual->port);
47 PrintError("Hook not present for IN on port %x\n", io_qual->port);
51 read_size = 1<<(io_qual->access_size);
53 PrintDebug("IN of %d bytes on port %d (0x%x)\n", read_size, io_qual->port, io_qual->port);
55 if(hook->read(io_qual->port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
56 PrintError("Read failure for IN on port %x\n", io_qual->port);
60 uint32_t instr_length = 0;
62 if(vmcs_read(VMCS_EXIT_INSTR_LEN, &instr_length) != VMX_SUCCESS) {
63 PrintError("Could not read instruction length\n");
67 info->rip += instr_length;
72 int v3_handle_vmx_io_ins(struct guest_info * info)
74 PrintDebug("INS not implemented\n");
78 int v3_handle_vmx_io_out(struct guest_info * info)
82 vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
84 struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
86 struct v3_io_hook * hook = v3_get_io_hook(info, io_qual->port);
89 PrintError("Hook not present for out on port %x\n", io_qual->port);
93 int write_size = 1<<(io_qual->access_size);
95 PrintDebug("OUT of %d bytes on port %d (0x%x)\n", write_size, io_qual->port, io_qual->port);
98 if(hook->write(io_qual->port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
99 PrintError("Write failure for out on port %x\n",io_qual->port);
103 uint32_t instr_length = 0;
105 if(vmcs_read(VMCS_EXIT_INSTR_LEN, &instr_length) != VMX_SUCCESS) {
106 PrintError("Could not read instruction length\n");
110 info->rip += instr_length;
115 int v3_handle_vmx_io_outs(struct guest_info * info)
119 vmcs_read(VMCS_EXIT_QUAL, &exit_qual);
121 struct vmexit_io_qual * io_qual = (struct vmexit_io_qual *)&exit_qual;
123 PrintDebug("OUTS on port %d, (0x%x)\n", io_qual->port, io_qual->port);