help
This turns on debugging for the device manager
+config DEBUG_MEM_ERRORS
+ bool "Verbose memory errors"
+ default n
+ depends on DEBUG_ON
+ help
+ This turns on debugging for memory translations and lookups
+
endmenu
strncpy(dev->url,url,MAX_URL);
- dev->guestdev=gdev;
+ dev->guestdev = gdev;
- dev->guest=guest;
+ dev->guest = guest;
spin_lock_init(&(dev->lock));
#include <linux/percpu.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
#include <interfaces/vmm_stream.h>
#include "vm.h"
#include "iface-stream.h"
+
+// This is going to need to be a lot bigger...
#define STREAM_BUF_SIZE 1024
char name[STREAM_NAME_LEN];
struct ringbuf * buf;
+ int connected;
+
wait_queue_head_t intr_queue;
spinlock_t lock;
}
+
+static ssize_t stream_read(struct file * filp, char __user * buf, size_t size, loff_t * offset) {
+ struct stream_buffer * stream = filp->private_data;
+
+ wait_event_interruptible(stream->intr_queue, (ringbuf_data_len(stream->buf) != 0));
+
+
+ return 0;
+}
+
+
+
+static struct file_operations stream_fops = {
+ .read = stream_read,
+ // .release = stream_close,
+ // .poll = stream_poll,
+};
+
+
+
static void * palacios_stream_open(const char * name, void * private_data) {
struct v3_guest * guest = (struct v3_guest *)private_data;
struct stream_buffer * stream = NULL;
static int stream_deinit( void ) {
if (!list_empty(&(global_streams))) {
printk("Error removing module with open streams\n");
+ printk("TODO: free old streams... \n");
}
return 0;
}
+
+
+
+
static int stream_connect(struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) {
void __user * argp = (void __user *)arg;
- char path_name[STREAM_NAME_LEN];
+ struct stream_buffer * stream = NULL;
+ int stream_fd = 0;
+ char name[STREAM_NAME_LEN];
+ unsigned long flags = 0;
+ int ret = -1;
+
- if (copy_from_user(path_name, argp, STREAM_NAME_LEN)) {
+ if (copy_from_user(name, argp, STREAM_NAME_LEN)) {
printk("%s(%d): copy from user error...\n", __FILE__, __LINE__);
return -EFAULT;
}
+
+ stream = find_stream_by_name(guest, name);
+
+ if (stream == NULL) {
+ printk("Could not find stream (%s)\n", name);
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&(stream->lock), flags);
+ if (stream->connected == 0) {
+ stream->connected = 1;
+ ret = 1;
+ }
+ spin_unlock_irqrestore(&(stream->lock), flags);
+
+
+ if (ret == -1) {
+ printk("Stream (%s) already connected\n", name);
+ return -EFAULT;
+ }
+
+ stream_fd = anon_inode_getfd("v3-stream", &stream_fops, stream, 0);
+ if (stream_fd < 0) {
+ printk("Error creating stream inode for (%s)\n", name);
+ return stream_fd;
+ }
- printk("ERROR: Opening Streams is currently not implemented...\n");
+ printk("Stream (%s) connected\n", name);
- return -EFAULT;
+ return stream_fd;
}
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.northwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __SW_INTR_H__
+#define __SW_INTR_H__
+
+#include <palacios/vmm.h>
+
+
+int v3_handle_swintr (struct guest_info * core);
+
+int v3_hook_swintr (struct guest_info * core,
+ uint8_t vector,
+ int (*handler)(struct guest_info * core, uint8_t vector, void * priv_data),
+ void * priv_data);
+int v3_hook_passthrough_swintr (struct guest_info * core, uint8_t vector);
+
+
+#endif
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.northwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __SYSCALL_HIJACK_H__
+#define __SYSCALL_HIJACK_H__
+
+
+int v3_hook_syscall (struct guest_info * core,
+ uint_t syscall_nr,
+ int (*handler)(struct guest_info * core, uint_t syscall_nr, void * priv_data),
+ void * priv_data);
+
+int v3_hook_passthrough_syscall (struct guest_info * core, uint_t syscall_nr);
+
+
+#endif
uint_t irq_started;
uint_t irq_vector;
+ uint_t swintr_posted;
+ uint8_t swintr_vector;
+
uint8_t virq_map[MAX_IRQ / 8];
v3_lock_t irq_lock;
int v3_lower_irq(struct v3_vm_info * vm, int irq);
+int v3_raise_swintr(struct guest_info * core, uint8_t vector);
+
struct intr_ctrl_ops {
int (*intr_pending)(struct guest_info * info, void * private_data);
help
Provides the inspection extension
+config EXT_SW_INTERRUPTS
+ bool "Enable interception and hooking of software interrupts"
+ default n
+ help
+ This feature will cause the VMM to intercept the execution
+ of software interrupts (i.e. the INTn instruction) and enable
+ any INT vector to be hooked. Extension name is "swintr_intercept"
+
+config DEBUG_EXT_SW_INTERRUPTS
+ bool "Enable debugging of software interrupt interception code"
+ depends on EXT_SW_INTERRUPTS
+ default n
+ help
+ This will enable useful debugging printouts for software
+ intercept code
+
+config EXT_SWINTR_PASSTHROUGH
+ bool "Hook all unhandled sofware interrupts for passthrough"
+ depends on EXT_SW_INTERRUPTS
+ default n
+ help
+ If enabled, this will cause all software interrupts
+ (INT instruction vectors) to be hooked for passthrough.
+ May reduce performance but useful for debugging.
+
+config EXT_SYSCALL_HIJACK
+ bool "Enable System Call Hijacking"
+ depends on EXT_SW_INTERRUPTS
+ default n
+ help
+ Enable the VMM to hijack system calls executed by the guest.
+ If enabled, the VMM will hook execution of INT 80
+
+config DEBUG_EXT_SYSCALL_HIJACK
+ bool "Enable Syscall Hijack Debug in Palacios"
+ depends on EXT_SYSCALL_HIJACK
+ default n
+ help
+ Enable Debugging printouts for syscall hijacking code
+ in Palacios
+
+config EXT_SYSCALL_PASSTHROUGH
+ bool "Hook all unhandled system calls for passthrough"
+ depends on EXT_SYSCALL_HIJACK
+ default n
+ help
+ If enabled, this option will cause all system calls
+ that are not explicitly hooked to be hooked for
+ passthrough. This is useful for debugging.
+
endmenu
obj-$(V3_CONFIG_EXT_VTIME) += ext_vtime.o
obj-$(V3_CONFIG_EXT_INSPECTOR) += ext_inspector.o
obj-$(V3_CONFIG_EXT_MACH_CHECK) += ext_mcheck.o
+obj-$(V3_CONFIG_EXT_SW_INTERRUPTS) += ext_sw_intr.o
+obj-$(V3_CONFIG_EXT_SYSCALL_HIJACK) += ext_syscall_hijack.o
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.norhtwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#include <palacios/vmm.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vmm_string.h>
+#include <palacios/vmm_syscall_hijack.h>
+#include <palacios/vmm_hashtable.h>
+#include <palacios/vmm_execve_hook.h>
+
+
+
+static int free_hook (struct guest_info * core, struct exec_hook * hook) {
+ list_del(&(hook->hook_node));
+ V3_Free(hook);
+ return 0;
+}
+
+static uint_t exec_hash_fn (addr_t key) {
+ return v3_hash_long(key, sizeof(void *) * 8);
+}
+
+
+static int exec_eq_fn (addr_t key1, addr_t key2) {
+ return (key1 == key2);
+}
+
+
+int v3_init_exec_hooks (struct guest_info * core) {
+ struct v3_exec_hooks * hooks = &(core->exec_hooks);
+
+ INIT_LIST_HEAD(&(hooks->hook_list));
+
+ hooks->bin_table = v3_create_htable(0, exec_hash_fn, exec_eq_fn);
+ return 0;
+}
+
+
+int v3_deinit_exec_hooks (struct guest_info * core) {
+ struct v3_exec_hooks * hooks = &(core->exec_hooks);
+ struct exec_hook * hook = NULL;
+ struct exec_hook * tmp = NULL;
+
+ list_for_each_entry_safe(hook, tmp, &(hooks->hook_list), hook_node) {
+ free_hook(core, hook);
+ }
+
+ v3_free_htable(hooks->bin_table, 0, 0);
+
+ return 0;
+}
+
+
+int v3_hook_executable (struct guest_info * core,
+ const uchar_t * binfile,
+ int (*handler)(struct guest_info * core, void * priv_data),
+ void * priv_data)
+{
+ struct exec_hook * hook = V3_Malloc(sizeof(struct exec_hook));
+ struct v3_exec_hooks * hooks = &(core->exec_hooks);
+ addr_t key;
+
+ memset(hook, 0, sizeof(struct exec_hook));
+
+ hook->handler = handler;
+ hook->priv_data = priv_data;
+
+ // we hash the name of the file to produce a key
+ key = v3_hash_buffer((uchar_t*)binfile, strlen(binfile));
+
+ v3_htable_insert(hooks->bin_table, key, (addr_t)hook);
+ list_add(&(hook->hook_node), &(hooks->hook_list));
+
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.norhtwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#include <palacios/vmm.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vmm_intr.h>
+#include <palacios/vmm_syscall_hijack.h>
+#include <palacios/vmm_mpi_accel.h>
+#include <palacios/vmm_process_environment.h>
+#include <palacios/vmm_execve_hook.h>
+
+
+int v3_init_mpi_accel (struct guest_info * core) {
+ //binfile = "./envtest";
+ //args[1] = "LD_PRELOAD=./libcwrap.so";
+
+ v3_hook_swintr(core, 0x80, v3_syscall_handler, NULL);
+ v3_hook_syscall(core, 11, v3_sysexecve_handler, NULL);
+ v3_hook_executable(core, "./envtest", v3_mpi_preload_handler, NULL);
+
+ return 0;
+}
+
+
+int v3_deinit_mpi_accel (struct guest_info * core) {
+
+ return 0;
+}
+
+
+int v3_mpi_preload_handler (struct guest_info * core, void * priv_data) {
+
+ char * a[3];
+ a[0] = "TEST=HITHERE";
+ a[1] = "TEST2=/blah/blah/blah";
+ a[2] = "LD_PRELOAD=./libcwrap.so";
+
+ int ret = v3_inject_strings(core, (const char**)NULL, (const char**)a, 0, 3);
+ if (ret == -1) {
+ PrintDebug("Error injecting strings in execve handler\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.norhtwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vmm_decoder.h>
+#include <palacios/vmm_process_environment.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vm_guest_mem.h>
+
+static int v3_copy_chunk_guest32(struct guest_info * core, addr_t gva, uint_t argcnt, uint_t envcnt) {
+
+ int ret = 0, i = 0;
+ addr_t hva;
+ uint32_t tmp_args[core->var_dump.argc];
+ uint32_t tmp_envs[core->var_dump.envc];
+
+ PrintDebug("Initiating copy into guest (32bit)\n");
+
+ ret = v3_gva_to_hva(core, get_addr_linear(core, gva, &(core->segments.ds)), &hva);
+ if (ret == -1) {
+ PrintDebug("Error translating gva in v3_copy_chunk_2guest\n");
+ return -1;
+ }
+
+ // copy the env strings (we're moving top-down through the stack)
+ char * host_cursor = (char*) hva;
+ uint32_t guest_cursor = (uint32_t) gva;
+ host_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ while (i < core->var_dump.envc) {
+ //PrintDebug("Copying envvar#%d: %s\n", i, core->var_dump.envp[i]);
+ strcpy(host_cursor, core->var_dump.envp[i]);
+ tmp_envs[i] = guest_cursor;
+ i++;
+ if (i != core->var_dump.envc) {
+ host_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ }
+ }
+
+ // then the arg strings
+ i = 0;
+ host_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ while (i < core->var_dump.argc) {
+ //PrintDebug("Copying arg #%d: %s\n", i, core->var_dump.argv[i]);
+ strcpy(host_cursor, core->var_dump.argv[i]);
+ tmp_args[i] = guest_cursor;
+ i++;
+ if (i != core->var_dump.argc) {
+ host_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ }
+ }
+
+
+ // padding
+ host_cursor--;
+ guest_cursor--;
+ while ((long)host_cursor % 4) {
+ *host_cursor = 0;
+ host_cursor--;
+ guest_cursor--;
+ }
+
+ // null ptr
+ host_cursor -= 4;
+ guest_cursor -= 4;
+ *((uint32_t*)host_cursor) = 0;
+
+ host_cursor -= 4;
+ guest_cursor -= 4;
+ for (i = 0; i < core->var_dump.envc; i++) {
+ *((uint32_t*)host_cursor) = tmp_envs[i];
+ host_cursor -= 4;
+ guest_cursor -= 4;
+ }
+
+ core->vm_regs.rdx = guest_cursor + 4;
+
+ *((uint32_t*)host_cursor) = 0;
+ host_cursor -= 4;
+ guest_cursor -= 4;
+ for (i = 0; i < core->var_dump.argc; i++) {
+ *((uint32_t*)host_cursor) = tmp_args[i];
+ host_cursor -= 4;
+ guest_cursor -= 4;
+ }
+
+ core->vm_regs.rcx = guest_cursor + 4;
+
+ // free up our temporary storage in the VMM
+ for (i = 0; i < core->var_dump.argc; i++) {
+ V3_Free(core->var_dump.argv[i]);
+ }
+ for (i = 0; i < core->var_dump.envc; i++) {
+ V3_Free(core->var_dump.envp[i]);
+ }
+
+ V3_Free(core->var_dump.envp);
+ V3_Free(core->var_dump.argv);
+ return 0;
+}
+
+
+static int v3_copy_chunk_vmm32(struct guest_info * core, const char ** argstrs, const char ** envstrs, uint_t argcnt, uint_t envcnt) {
+
+ addr_t envp, argv;
+ uint_t argc = 0, envc = 0, bytes = 0;
+ char * cursor;
+
+ PrintDebug("Initiating copy into vmm\n");
+
+ int ret = v3_gva_to_hva(core, get_addr_linear(core, core->vm_regs.rdx, &(core->segments.ds)), &envp);
+ if (ret == -1) {
+ PrintDebug("Error translating address in rdx\n");
+ return 0;
+ }
+
+ ret = v3_gva_to_hva(core, get_addr_linear(core, core->vm_regs.rcx, &(core->segments.ds)), &argv);
+ if (ret == -1) {
+ PrintDebug("Error translating address in rcx\n");
+ return 0;
+ }
+
+ cursor = (char*)argv;
+ while (*((uint32_t*)cursor) != 0) {
+ addr_t argvn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint32_t*)cursor), &(core->segments.ds)), &argvn);
+ if (ret == -1) {
+ PrintDebug("Error translating address for argvn\n");
+ }
+ argc++;
+ cursor += 4;
+ }
+
+ /* account for new args */
+ argc += argcnt;
+ core->var_dump.argv = (char**)V3_Malloc(sizeof(char*)*argc);
+ core->var_dump.argc = argc;
+ bytes += sizeof(uint32_t)*argc;
+
+ cursor = (char*)argv;
+ int i = 0;
+ while (*((uint32_t*)cursor) != 0) {
+ addr_t argvn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint32_t*)cursor), &(core->segments.ds)), &argvn);
+ if (ret == -1) {
+ PrintDebug("Error translating argvn address\n");
+ }
+
+ /* malloc room for the string */
+ char * tmpstr = (char*)V3_Malloc(strlen((char*)argvn) + 1);
+
+ /* copy the pointer */
+ core->var_dump.argv[i] = tmpstr;
+
+ /* copy the string */
+ strncpy(tmpstr, (char*)argvn, strlen((char*)argvn) + 1);
+ i++;
+ cursor += 4;
+ bytes += strlen((char*)argvn) + 1;
+ }
+
+ /* stick in new arg strings */
+ int j = 0;
+ while (j < argcnt) {
+ char * tmpstr = (char*)V3_Malloc(strlen(argstrs[j]) + 1);
+ strncpy(tmpstr, argstrs[i], strlen(argstrs[j]) + 1);
+ core->var_dump.argv[i] = tmpstr;
+ bytes += strlen(argstrs[j]) + 1;
+ i++; j++;
+ }
+
+
+ cursor = (char*)envp;
+ while (*((uint32_t*)cursor) != 0) {
+ addr_t envpn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint32_t*)cursor), &(core->segments.ds)), &envpn);
+ if (ret == -1) {
+ PrintDebug("Error translating address for envpn\n");
+ }
+ envc++;
+ cursor += 4;
+ }
+
+ envc += envcnt;
+ core->var_dump.envp = (char**)V3_Malloc(sizeof(char*)*envc);
+ core->var_dump.envc = envc;
+ bytes += sizeof(uint32_t)*envc;
+
+ cursor = (char*)envp;
+ i = 0;
+ while (*((uint32_t*)cursor) != 0) {
+ addr_t envpn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint32_t*)cursor), &(core->segments.ds)), &envpn);
+ if (ret == -1) {
+ PrintDebug("Error translating address for envpn\n");
+ }
+
+ /* malloc room for the string */
+ char * tmpstr = (char*)V3_Malloc(strlen((char*)envpn) + 1);
+
+ /* copy the pointer */
+ core->var_dump.envp[i] = tmpstr;
+
+ /* deepcopy the string */
+ strncpy(tmpstr, (char*)envpn, strlen((char*)envpn) + 1);
+ i++;
+ cursor += 4;
+ bytes += strlen((char*)envpn) + 1;
+ }
+
+ /* put in our new env strings */
+ j = 0;
+ while (j < envcnt) {
+ char * tmpstr = (char*)V3_Malloc(strlen(envstrs[j]) + 1);
+ strncpy(tmpstr, envstrs[j], strlen(envstrs[j]) + 1);
+ core->var_dump.envp[i] = tmpstr;
+ bytes += strlen(envstrs[j]) + 1;
+ i++; j++;
+ }
+
+
+ /* account for padding for strings
+ and 2 null pointers */
+ bytes += (bytes % 4) + 8;
+ core->var_dump.bytes = bytes;
+ return bytes;
+}
+
+
+static int v3_inject_strings32 (struct guest_info * core, const char ** argstrs, const char ** envstrs, uint_t argcnt, uint_t envcnt) {
+
+ addr_t inject_gva;
+ uint_t bytes_needed = 0;
+
+ /* copy out all of the arguments and the environment to the VMM */
+ if ((bytes_needed = v3_copy_chunk_vmm32(core, argstrs, envstrs, argcnt, envcnt)) == -1) {
+ PrintDebug("Error copying out environment and arguments\n");
+ return -1;
+ }
+
+ PrintDebug("environment successfully copied into VMM\n");
+
+ inject_gva = v3_prepare_guest_stack(core, bytes_needed);
+ if (!inject_gva) {
+ PrintDebug("Not enough space on user stack\n");
+ return -1;
+ }
+
+ v3_copy_chunk_guest32(core, inject_gva, argcnt, envcnt);
+
+ return 0;
+}
+
+
+static int v3_copy_chunk_guest64(struct guest_info * core, addr_t gva, uint_t argcnt, uint_t envcnt) {
+
+ int ret = 0, i = 0;
+ addr_t hva;
+ uint64_t tmp_args[core->var_dump.argc];
+ uint64_t tmp_envs[core->var_dump.envc];
+
+ PrintDebug("Initiating copy into guest (64bit)\n");
+
+ ret = v3_gva_to_hva(core, get_addr_linear(core, gva, &(core->segments.ds)), &hva);
+ if (ret == -1) {
+ PrintDebug("Error translating gva in v3_copy_chunk_2guest64\n");
+ return -1;
+ }
+
+ char * host_cursor = (char*) hva;
+ uint64_t guest_cursor = (uint64_t) gva;
+ host_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ while (i < core->var_dump.envc) {
+ //PrintDebug("Copying envvar#%d: %s\n", i, core->var_dump.envp[i]);
+ strcpy(host_cursor, core->var_dump.envp[i]);
+ tmp_envs[i] = guest_cursor;
+ i++;
+ if (i != core->var_dump.envc) {
+ host_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.envp[i]) + 1;
+ }
+ }
+
+ i = 0;
+ host_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ while (i < core->var_dump.argc) {
+ //PrintDebug("Copying arg #%d: %s\n", i, core->var_dump.argv[i]);
+ strcpy(host_cursor, core->var_dump.argv[i]);
+ tmp_args[i] = guest_cursor;
+ i++;
+ if (i != core->var_dump.argc) {
+ host_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ guest_cursor -= strlen(core->var_dump.argv[i]) + 1;
+ }
+ }
+
+ // padding
+ host_cursor--;
+ guest_cursor--;
+ while ((long)host_cursor % 8) {
+ *host_cursor = 0;
+ host_cursor--;
+ guest_cursor--;
+ }
+
+ // one null ptr
+ host_cursor -= 8;
+ guest_cursor -= 8;
+ *((uint64_t*)host_cursor) = 0;
+
+ host_cursor -= 8;
+ guest_cursor -= 8;
+ for (i = 0; i < core->var_dump.envc; i++) {
+ *((uint64_t*)host_cursor) = tmp_envs[i];
+ host_cursor -= 8;
+ guest_cursor -= 8;
+ }
+
+ core->vm_regs.rdx = guest_cursor + 8;
+
+ *((uint64_t*)host_cursor) = 0;
+ host_cursor -= 8;
+ guest_cursor -= 8;
+ for (i = 0; i < core->var_dump.argc; i++) {
+ *((uint64_t*)host_cursor) = tmp_args[i];
+ host_cursor -= 8;
+ guest_cursor -= 8;
+ }
+
+ core->vm_regs.rcx = guest_cursor + 8;
+
+ for (i = 0; i < core->var_dump.argc; i++) {
+ V3_Free(core->var_dump.argv[i]);
+ }
+ for (i = 0; i < core->var_dump.envc; i++) {
+ V3_Free(core->var_dump.envp[i]);
+ }
+
+ V3_Free(core->var_dump.envp);
+ V3_Free(core->var_dump.argv);
+ return 0;
+}
+
+
+static int v3_copy_chunk_vmm64(struct guest_info * core, const char ** argstrs, const char ** envstrs, uint_t argcnt, uint_t envcnt) {
+
+ addr_t envp, argv;
+ uint_t argc = 0, envc = 0, bytes = 0;
+ char * cursor;
+
+ PrintDebug("Initiating copy into vmm\n");
+
+ int ret = v3_gva_to_hva(core, get_addr_linear(core, core->vm_regs.rdx, &(core->segments.ds)), &envp);
+ if (ret == -1) {
+ PrintDebug("Error translating address in rdx\n");
+ return 0;
+ }
+
+ ret = v3_gva_to_hva(core, get_addr_linear(core, core->vm_regs.rcx, &(core->segments.ds)), &argv);
+ if (ret == -1) {
+ PrintDebug("Error translating address in rcx\n");
+ return 0;
+ }
+
+ cursor = (char*)argv;
+ while (*((uint64_t*)cursor) != 0) {
+ addr_t argvn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint64_t*)cursor), &(core->segments.ds)), &argvn);
+ if (ret == -1) {
+ PrintDebug("Error translating address for argvn\n");
+ }
+ argc++;
+ cursor += 8;
+ }
+
+ /* account for new strings */
+ argc += argcnt;
+ core->var_dump.argv = (char**)V3_Malloc(sizeof(char*)*argc);
+ core->var_dump.argc = argc;
+ bytes += sizeof(char*)*argc;
+
+ cursor = (char*)argv;
+ int i = 0;
+ while (*((uint64_t*)cursor) != 0) {
+ addr_t argvn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint64_t*)cursor), &(core->segments.ds)), &argvn);
+ if (ret == -1) {
+ PrintDebug("Error translating argvn address\n");
+ }
+
+ /* malloc room for the string */
+ char * tmpstr = (char*)V3_Malloc(strlen((char*)argvn) + 1);
+
+ /* copy the pointer */
+ core->var_dump.argv[i] = tmpstr;
+
+ /* copy the string */
+ strncpy(tmpstr, (char*)argvn, strlen((char*)argvn) + 1);
+ i++;
+ cursor += 8;
+ bytes += strlen((char*)argvn) + 1;
+ }
+
+ /* stick in new arg strings */
+ int j = 0;
+ while (j < argcnt) {
+ char * tmpstr = (char*)V3_Malloc(strlen(argstrs[j]) + 1);
+ strncpy(tmpstr, argstrs[j], strlen(argstrs[j]) + 1);
+ core->var_dump.argv[i] = tmpstr;
+ bytes += strlen(argstrs[j]) + 1;
+ i++; j++;
+ }
+
+
+ cursor = (char*)envp;
+ while (*((uint64_t*)cursor) != 0) {
+ addr_t envpn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint64_t*)cursor), &(core->segments.ds)), &envpn);
+ if (ret == -1) {
+ PrintDebug("Error translating address for envpn\n");
+ }
+ envc++;
+ cursor += 8;
+ }
+
+ envc += envcnt;
+ core->var_dump.envp = (char**)V3_Malloc(sizeof(char*)*envc);
+ core->var_dump.envc = envc;
+ bytes += sizeof(uint64_t)*(envc);
+
+
+ cursor = (char*)envp;
+ i = 0;
+ while (*((uint64_t*)cursor) != 0) {
+ addr_t envpn;
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)*((uint64_t*)cursor), &(core->segments.ds)), &envpn);
+ if (ret == -1) {
+ PrintDebug("Error translating address for envpn\n");
+ }
+
+ /* malloc room for the string */
+ char * tmpstr = (char*)V3_Malloc(strlen((char*)envpn) + 1);
+
+ /* copy the pointer */
+ core->var_dump.envp[i] = tmpstr;
+
+ /* deepcopy the string */
+ strncpy(tmpstr, (char*)envpn, strlen((char*)envpn) + 1);
+ i++;
+ cursor += 8;
+ bytes += strlen((char*)envpn) + 1;
+ }
+
+ /* stick in new env strings */
+ j = 0;
+ while (j < envcnt) {
+ char * tmpstr = (char*)V3_Malloc(strlen(envstrs[j]) + 1);
+ strncpy(tmpstr, envstrs[i], strlen(envstrs[j]) + 1);
+ core->var_dump.envp[i] = tmpstr;
+ bytes += strlen(envstrs[j]) + 1;
+ i++; j++;
+ }
+
+
+ /* account for padding for strings
+ and 2 null pointers */
+ bytes += (bytes % 8) + 16;
+ core->var_dump.bytes = bytes;
+ return bytes;
+}
+
+
+static int v3_inject_strings64 (struct guest_info * core, const char ** argstrs, const char ** envstrs, uint_t argcnt, uint_t envcnt) {
+
+ addr_t inject_gva;
+ uint_t bytes_needed = 0;
+
+ /* copy out all of the arguments and the environment to the VMM */
+ if ((bytes_needed = v3_copy_chunk_vmm64(core, argstrs, envstrs, argcnt, envcnt)) == -1) {
+ PrintDebug("Error copying out environment and arguments\n");
+ return -1;
+ }
+
+ PrintDebug("environment successfully copied into VMM\n");
+
+ inject_gva = v3_prepare_guest_stack(core, bytes_needed);
+ if (!inject_gva) {
+ PrintDebug("Not enough space on user stack\n");
+ return -1;
+ }
+
+ v3_copy_chunk_guest64(core, inject_gva, argcnt, envcnt);
+ return 0;
+}
+
+
+addr_t v3_prepare_guest_stack (struct guest_info * core, uint_t bytes_needed) {
+
+ /* TODO: check if we've injected a page fault to get more stack space */
+
+ // do we have enough room between esp and the next page boundary?
+ uint_t rem_bytes = 4096 - (core->vm_regs.rsp % 4096);
+
+ if (rem_bytes >= bytes_needed) {
+ return (addr_t)core->vm_regs.rsp;
+ } else {
+ // not enough room, find out how many pages we need (ceiling)
+ uint_t num_pages = (bytes_needed + 4095) / 4096;
+
+ // check if num_pages are user & writable
+ int i = 0;
+ int pages_ok = 1;
+ addr_t gva = core->vm_regs.rsp + rem_bytes;
+ for (; i < num_pages; i++, gva -= 4096) {
+ if (!v3_gva_can_access(core, gva)) {
+ pages_ok = 0;
+ }
+ }
+
+ if (pages_ok) {
+ return (addr_t)core->vm_regs.rsp;
+ } else {
+
+ /*
+ // inject a page fault
+ pf_error_t fault_type = {
+ .write = 1,
+ .user = 1
+ };
+
+ // hoping Linux will allocate all pages in between gva and esp
+ v3_inject_guest_pf(core, gva - (num_pages*4096), fault_type);
+ */
+ return -1;
+ }
+ }
+}
+
+
+/* TODO: give these next to functions the ability to copy into guest stack */
+int v3_replace_arg (struct guest_info * core, uint_t argnum, const char * newval) {
+
+ return 0;
+}
+
+
+int v3_replace_env (struct guest_info * core, const char * envname, const char * newval) {
+
+ return 0;
+}
+
+
+int v3_inject_strings (struct guest_info * core, const char ** argstrs, const char ** envstrs, uint_t argcnt, uint_t envcnt) {
+
+ if (core->cpu_mode == LONG || core->cpu_mode == LONG_32_COMPAT) {
+ if (v3_inject_strings64(core, argstrs, envstrs, argcnt, envcnt) == -1) {
+ PrintDebug("Error injecting strings into environment (64)\n");
+ return -1;
+ }
+ } else {
+ if (v3_inject_strings32(core, argstrs, envstrs, argcnt, envcnt) == -1) {
+ PrintDebug("Error injecting strings into environment (32)\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.norhtwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vmcb.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vm_guest_mem.h>
+#include <palacios/vmm_decoder.h>
+#include <palacios/vmm_extensions.h>
+#include <palacios/vmm_intr.h>
+
+#include <interfaces/sw_intr.h>
+
+#ifndef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
+
+static int init_swintr_intercept (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
+
+ return 0;
+}
+
+
+static int init_swintr_intercept_core (struct guest_info * core, void * priv_data) {
+ vmcb_t * vmcb = (vmcb_t*)core->vmm_data;
+ vmcb_ctrl_t * ctrl_area = GET_VMCB_CTRL_AREA(vmcb);
+
+ ctrl_area->instrs.INTn = 1;
+
+ return 0;
+}
+
+
+struct v3_swintr_hook {
+ int (*handler)(struct guest_info * core, uint8_t vector, void * priv_data);
+ void * priv_data;
+};
+
+
+static struct v3_swintr_hook * swintr_hooks[256];
+
+
+static inline struct v3_swintr_hook * get_swintr_hook (struct guest_info * core, uint8_t vector) {
+ return swintr_hooks[vector];
+}
+
+
+static struct v3_extension_impl swintr_impl = {
+ .name = "swintr_intercept",
+ .init = init_swintr_intercept,
+ .deinit = NULL,
+ .core_init = init_swintr_intercept_core,
+ .core_deinit = NULL,
+ .on_entry = NULL,
+ .on_exit = NULL
+};
+
+
+register_extension(&swintr_impl);
+
+
+int v3_handle_swintr (struct guest_info * core) {
+
+ int ret = 0;
+ void * instr_ptr = NULL;
+ struct x86_instr instr;
+
+ if (core->mem_mode == PHYSICAL_MEM) {
+ ret = v3_gpa_to_hva(core, get_addr_linear(core, core->rip, &(core->segments.cs)), (addr_t *)&instr_ptr);
+ } else {
+ ret = v3_gva_to_hva(core, get_addr_linear(core, core->rip, &(core->segments.cs)), (addr_t *)&instr_ptr);
+ }
+
+ if (ret == -1) {
+ PrintError("V3 SWintr Handler: Could not translate Instruction Address (%p)\n", (void *)core->rip);
+ return -1;
+ }
+
+ if (v3_decode(core, (addr_t)instr_ptr, &instr) == -1) {
+ PrintError("V3 SWintr Handler: Decoding Error\n");
+ return -1;
+ }
+
+ uint8_t vector = instr.dst_operand.operand;
+
+ struct v3_swintr_hook * hook = swintr_hooks[vector];
+ if (hook == NULL) {
+#ifdef V3_CONFIG_EXT_SWINTR_PASSTHROUGH
+ if (v3_hook_passthrough_swintr(core, vector) == -1) {
+ PrintDebug("V3 SWintr Handler: Error hooking passthrough swintr\n");
+ return -1;
+ }
+ hook = swintr_hooks[vector];
+#else
+ core->rip += instr.instr_length;
+ return v3_raise_swintr(core, vector);
+#endif
+ }
+
+ ret = hook->handler(core, vector, NULL);
+ if (ret == -1) {
+ PrintDebug("V3 SWintr Handler: Error in swintr hook\n");
+ return -1;
+ }
+
+ /* at some point we _may_ need to prioritize swints
+ so that they finish in time for the next
+ instruction... */
+ core->rip += instr.instr_length;
+ return v3_raise_swintr(core, vector);
+}
+
+
+
+int v3_hook_swintr (struct guest_info * core,
+ uint8_t vector,
+ int (*handler)(struct guest_info * core, uint8_t vector, void * priv_data),
+ void * priv_data)
+{
+ struct v3_swintr_hook * hook = (struct v3_swintr_hook*)V3_Malloc(sizeof(struct v3_swintr_hook));
+
+ if (hook == NULL) {
+ return -1;
+ }
+
+ if (get_swintr_hook(core, vector) != NULL) {
+ PrintError("swint %d already hooked\n", vector);
+ return -1;
+ }
+
+ hook->handler = handler;
+ hook->priv_data = priv_data;
+
+ swintr_hooks[vector] = hook;
+
+ return 0;
+}
+
+
+static int passthrough_swintr_handler (struct guest_info * core, uint8_t vector, void * priv_data) {
+ PrintDebug("[passthrough_swint_handler] INT vector=%d (guest=0x%p)\n",
+ vector, (void*)core);
+ return 0;
+}
+
+
+int v3_hook_passthrough_swintr (struct guest_info * core, uint8_t vector) {
+
+ int rc = v3_hook_swintr(core, vector, passthrough_swintr_handler, NULL);
+
+ if (rc) {
+ PrintError("guest_swintr_injection: failed to hook swint 0x%x (guest=0x%p)\n", vector, (void*)core);
+ return -1;
+ } else {
+ PrintDebug("guest_swintr_injection: hooked swint 0x%x (guest=0x%p)\n", vector, (void*)core);
+ return 0;
+ }
+
+ /* shouldn't get here */
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.norhtwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#include <palacios/vmm.h>
+#include <palacios/vm_guest_mem.h>
+#include <palacios/vm_guest.h>
+#include <palacios/vmm_intr.h>
+#include <palacios/vmm_decoder.h>
+#include <palacios/vmm_string.h>
+#include <palacios/vmm_shadow_paging.h>
+#include <palacios/vmm_extensions.h>
+#include <palacios/vmm_intr.h>
+
+#include <interfaces/syscall_hijack.h>
+#include <interfaces/sw_intr.h>
+
+#include "syscall_ref.h"
+
+#ifndef V3_CONFIG_DEBUG_EXT_SYSCALL_HIJACK
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
+#define MAX_CHARS 256
+#ifndef max
+ #define max(a, b) ( ((a) > (b)) ? (a) : (b) )
+#endif
+
+#define SYSCALL_INT_VECTOR 0x80
+
+
+struct v3_syscall_hook {
+ int (*handler)(struct guest_info * core, uint_t syscall_nr, void * priv_data);
+ void * priv_data;
+};
+
+static struct v3_syscall_hook * syscall_hooks[512];
+
+
+static int v3_syscall_handler (struct guest_info * core, uint8_t vector, void * priv_data) {
+
+ uint_t syscall_nr = (uint_t) core->vm_regs.rax;
+ int err = 0;
+
+ struct v3_syscall_hook * hook = syscall_hooks[syscall_nr];
+ if (hook == NULL) {
+#ifdef V3_CONFIG_EXT_SYSCALL_PASSTHROUGH
+ if (v3_hook_passthrough_syscall(core, syscall_nr) == -1) {
+ PrintDebug("Error hooking passthrough syscall\n");
+ return -1;
+ }
+ hook = syscall_hooks[syscall_nr];
+#else
+ return v3_raise_swintr(core, vector);
+#endif
+ }
+
+ err = hook->handler(core, syscall_nr, hook->priv_data);
+ if (err == -1) {
+ PrintDebug("V3 Syscall Handler: Error in syscall hook\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
+static int init_syscall_hijack (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) {
+
+ return 0;
+}
+
+
+static int init_syscall_hijack_core (struct guest_info * core, void * priv_data) {
+
+ v3_hook_swintr(core, SYSCALL_INT_VECTOR, v3_syscall_handler, NULL);
+ return 0;
+}
+
+
+static void print_arg (struct guest_info * core, v3_reg_t reg, uint8_t argnum) {
+
+ addr_t hva;
+ int ret = 0;
+
+ PrintDebug("\t ARG%d: INT - %ld\n", argnum, (long) reg);
+
+ if (core->mem_mode == PHYSICAL_MEM) {
+ ret = v3_gpa_to_hva(core, get_addr_linear(core, reg, &(core->segments.ds)), &hva);
+ }
+ else {
+ ret = v3_gva_to_hva(core, get_addr_linear(core, reg, &(core->segments.ds)), &hva);
+ }
+
+ PrintDebug("\t STR - ");
+ if (ret == -1) {
+ PrintDebug("\n");
+ return;
+ }
+
+ uint32_t c = max(MAX_CHARS, 4096 - (hva % 4096));
+ int i = 0;
+ for (; i < c && *((char*)(hva + i)) != 0; i++) {
+ PrintDebug("%c", *((char*)(hva + i)));
+ }
+ PrintDebug("\n");
+}
+
+
+static void print_syscall (uint8_t is64, struct guest_info * core) {
+
+ if (is64) {
+ PrintDebug("Syscall #%ld: \"%s\"\n", (long)core->vm_regs.rax, get_linux_syscall_name64(core->vm_regs.rax));
+ } else {
+ PrintDebug("Syscall #%ld: \"%s\"\n", (long)core->vm_regs.rax, get_linux_syscall_name32(core->vm_regs.rax));
+ }
+
+ print_arg(core, core->vm_regs.rbx, 1);
+ print_arg(core, core->vm_regs.rcx, 2);
+ print_arg(core, core->vm_regs.rdx, 3);
+}
+
+
+
+
+static struct v3_extension_impl syscall_impl = {
+ .name = "syscall_intercept",
+ .init = init_syscall_hijack,
+ .deinit = NULL,
+ .core_init = init_syscall_hijack_core,
+ .core_deinit = NULL,
+ .on_entry = NULL,
+ .on_exit = NULL
+};
+
+register_extension(&syscall_impl);
+
+
+
+
+static inline struct v3_syscall_hook * get_syscall_hook (struct guest_info * core, uint_t syscall_nr) {
+ return syscall_hooks[syscall_nr];
+}
+
+
+int v3_hook_syscall (struct guest_info * core,
+ uint_t syscall_nr,
+ int (*handler)(struct guest_info * core, uint_t syscall_nr, void * priv_data),
+ void * priv_data)
+{
+ struct v3_syscall_hook * hook = (struct v3_syscall_hook *)V3_Malloc(sizeof(struct v3_syscall_hook));
+
+
+ if (hook == NULL) {
+ return -1;
+ }
+
+ if (get_syscall_hook(core, syscall_nr) != NULL) {
+ PrintError("System Call #%d already hooked\n", syscall_nr);
+ return -1;
+ }
+
+ hook->handler = handler;
+ hook->priv_data = priv_data;
+
+ syscall_hooks[syscall_nr] = hook;
+
+ return 0;
+}
+
+
+static int passthrough_syscall_handler (struct guest_info * core, uint_t syscall_nr, void * priv_data) {
+ print_syscall(0, core);
+ return 0;
+}
+
+
+int v3_hook_passthrough_syscall (struct guest_info * core, uint_t syscall_nr) {
+
+ int rc = v3_hook_syscall(core, syscall_nr, passthrough_syscall_handler, NULL);
+
+ if (rc) {
+ PrintError("failed to hook syscall 0x%x for passthrough (guest=0x%p)\n", syscall_nr, (void *)core);
+ return -1;
+ } else {
+ PrintDebug("hooked syscall 0x%x for passthrough (guest=0x%p)\n", syscall_nr, (void *)core);
+ return 0;
+ }
+
+ /* shouldn't get here */
+ return 0;
+}
+
+/*
+int v3_sysexecve_handler (struct guest_info * core, uint_t syscall_nr, void * priv_data) {
+ addr_t hva, key;
+ struct exec_hook * hook;
+ int ret;
+
+ ret = v3_gva_to_hva(core, get_addr_linear(core, (addr_t)core->vm_regs.rbx, &(core->segments.ds)), &hva);
+ if (ret == -1) {
+ PrintDebug("Error translating file path in sysexecve handler\n");
+ return -1;
+ }
+
+ key = v3_hash_buffer((uchar_t*)hva, strlen((uchar_t*)hva));
+ if ((hook = (struct exec_hook*)v3_htable_search(core->exec_hooks.bin_table, key)) != NULL) {
+ if (hook->handler(core, NULL) == -1) {
+ PrintDebug("Error handling execve hook\n");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+*/
--- /dev/null
+/*
+ * This file is part of the Palacios Virtual Machine Monitor developed
+ * by the V3VEE Project with funding from the United States National
+ * Science Foundation and the Department of Energy.
+ *
+ * The V3VEE Project is a joint project between Northwestern University
+ * and the University of New Mexico. You can find out more at
+ * http://www.v3vee.org
+ *
+ * Copyright (c) 2011, Kyle C. Hale <kh@u.northwestern.edu>
+ * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org>
+ * All rights reserved.
+ *
+ * Author: Kyle C. Hale <kh@u.northwestern.edu>
+ *
+ * This is free software. You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+#ifndef __SYSCALL_REF_H__
+#define __SYSCALL_REF_H__
+
+
+static char * get_linux_syscall_name32 (uint_t syscall_nr) {
+
+ switch (syscall_nr) {
+
+ case 0: return "restart_syscall"; break;
+ case 1: return "exit"; break;
+ case 2: return "fork"; break;
+ case 3: return "read"; break;
+ case 4: return "write"; break;
+ case 5: return "open"; break;
+ case 6: return "close"; break;
+ case 7: return "waitpid"; break;
+ case 8: return "creat"; break;
+ case 9: return "link"; break;
+ case 10: return "unlink"; break;
+ case 11: return "execve"; break;
+ case 12: return "chdir"; break;
+ case 13: return "time"; break;
+ case 14: return "mknod"; break;
+ case 15: return "chmod"; break;
+ case 16: return "lchown"; break;
+ case 17: return "break"; break;
+ case 18: return "oldstat"; break;
+ case 19: return "lseek"; break;
+ case 20: return "getpid"; break;
+ case 21: return "mount"; break;
+ case 22: return "umount"; break;
+ case 23: return "setuid"; break;
+ case 24: return "getuid"; break;
+ case 25: return "stime"; break;
+ case 26: return "ptrace"; break;
+ case 27: return "alarm"; break;
+ case 28: return "oldfstat"; break;
+ case 29: return "pause"; break;
+ case 30: return "utime"; break;
+ case 31: return "stty"; break;
+ case 32: return "gtty"; break;
+ case 33: return "access"; break;
+ case 34: return "nice"; break;
+ case 35: return "ftime"; break;
+ case 36: return "sync"; break;
+ case 37: return "kill"; break;
+ case 38: return "rename"; break;
+ case 39: return "mkdir"; break;
+ case 40: return "rmdir"; break;
+ case 41: return "dup"; break;
+ case 42: return "pipe"; break;
+ case 43: return "times"; break;
+ case 44: return "prof"; break;
+ case 45: return "brk"; break;
+ case 46: return "setgid"; break;
+ case 47: return "getgid"; break;
+ case 48: return "signal"; break;
+ case 49: return "geteuid"; break;
+ case 50: return "getegid"; break;
+ case 51: return "acct"; break;
+ case 52: return "umount2"; break;
+ case 53: return "lock"; break;
+ case 54: return "ioctl"; break;
+ case 55: return "fcntl"; break;
+ case 56: return "mpx"; break;
+ case 57: return "setpgid"; break;
+ case 58: return "ulimit"; break;
+ case 59: return "oldolduname"; break;
+ case 60: return "umask"; break;
+ case 61: return "chroot"; break;
+ case 62: return "ustat"; break;
+ case 63: return "dup2"; break;
+ case 64: return "getppid"; break;
+ case 65: return "getpgrp"; break;
+ case 66: return "setsid"; break;
+ case 67: return "sigaction"; break;
+ case 68: return "sgetmask"; break;
+ case 69: return "ssetmask"; break;
+ case 70: return "setreuid"; break;
+ case 71: return "setregid"; break;
+ case 72: return "sigsuspend"; break;
+ case 73: return "sigpending"; break;
+ case 74: return "sethostname"; break;
+ case 75: return "setrlimit"; break;
+ case 76: return "getrlimit"; break;
+ case 77: return "getrusage"; break;
+ case 78: return "gettimeofday"; break;
+ case 79: return "settimeofday"; break;
+ case 80: return "getgroups"; break;
+ case 81: return "setgroups"; break;
+ case 82: return "select"; break;
+ case 83: return "symlink"; break;
+ case 84: return "oldlstat"; break;
+ case 85: return "readlink"; break;
+ case 86: return "uselib"; break;
+ case 87: return "swapon"; break;
+ case 88: return "reboot"; break;
+ case 89: return "readdir"; break;
+ case 90: return "mmap"; break;
+ case 91: return "munmap"; break;
+ case 92: return "truncate"; break;
+ case 93: return "ftruncate"; break;
+ case 94: return "fchmod"; break;
+ case 95: return "fchown"; break;
+ case 96: return "getpriority"; break;
+ case 97: return "setpriority"; break;
+ case 98: return "profil"; break;
+ case 99: return "statfs"; break;
+ case 100: return "fstatfs"; break;
+ case 101: return "ioperm"; break;
+ case 102: return "socketcall"; break;
+ case 103: return "syslog"; break;
+ case 104: return "setitimer"; break;
+ case 105: return "getitimer"; break;
+ case 106: return "stat"; break;
+ case 107: return "lstat"; break;
+ case 108: return "fstat"; break;
+ case 109: return "olduname"; break;
+ case 110: return "iopl"; break;
+ case 111: return "vhangup"; break;
+ case 112: return "idle"; break;
+ case 113: return "vm86old"; break;
+ case 114: return "wait4"; break;
+ case 115: return "swapoff"; break;
+ case 116: return "sysinfo"; break;
+ case 117: return "ipc"; break;
+ case 118: return "fsync"; break;
+ case 119: return "sigreturn"; break;
+ case 120: return "clone"; break;
+ case 121: return "setdomainname"; break;
+ case 122: return "uname"; break;
+ case 123: return "modify_ldt"; break;
+ case 124: return "adjtimex"; break;
+ case 125: return "mprotect"; break;
+ case 126: return "sigprocmask"; break;
+ case 127: return "create_module"; break;
+ case 128: return "init_module"; break;
+ case 129: return "delete_module"; break;
+ case 130: return "get_kernel_syms"; break;
+ case 131: return "quotactl"; break;
+ case 132: return "getpgid"; break;
+ case 133: return "fchdir"; break;
+ case 134: return "bdflush"; break;
+ case 135: return "sysfs"; break;
+ case 136: return "personality"; break;
+ case 137: return "afs_syscall"; break;
+ case 138: return "setfsuid"; break;
+ case 139: return "setfsgid"; break;
+ case 140: return "_llseek"; break;
+ case 141: return "getdents"; break;
+ case 142: return "_newselect"; break;
+ case 143: return "flock"; break;
+ case 144: return "msync"; break;
+ case 145: return "readv"; break;
+ case 146: return "writev"; break;
+ case 147: return "getsid"; break;
+ case 148: return "fdatasync"; break;
+ case 149: return "_sysctl"; break;
+ case 150: return "mlock"; break;
+ case 151: return "munlock"; break;
+ case 152: return "mlockall"; break;
+ case 153: return "munlockall"; break;
+ case 154: return "sched_setparam"; break;
+ case 155: return "sched_getparam"; break;
+ case 156: return "sched_setscheduler"; break;
+ case 157: return "sched_getscheduler"; break;
+ case 158: return "sched_yield"; break;
+ case 159: return "sched_get_priority_max"; break;
+ case 160: return "sched_get_priority_min"; break;
+ case 161: return "sched_rr_get_interval"; break;
+ case 162: return "nanosleep"; break;
+ case 163: return "mremap"; break;
+ case 164: return "setresuid"; break;
+ case 165: return "getresuid"; break;
+ case 166: return "vm86"; break;
+ case 167: return "query_module"; break;
+ case 168: return "poll"; break;
+ case 169: return "nfsservctl"; break;
+ case 170: return "setresgid"; break;
+ case 171: return "getresgid"; break;
+ case 172: return "prctl"; break;
+ case 173: return "rt_sigreturn"; break;
+ case 174: return "rt_sigaction"; break;
+ case 175: return "rt_sigprocmask"; break;
+ case 176: return "rt_sigpending"; break;
+ case 177: return "rt_sigtimedwait"; break;
+ case 178: return "rt_sigqueueinfo"; break;
+ case 179: return "rt_sigsuspend"; break;
+ case 180: return "pread64"; break;
+ case 181: return "pwrite64"; break;
+ case 182: return "chown"; break;
+ case 183: return "getcwd"; break;
+ case 184: return "capget"; break;
+ case 185: return "capset"; break;
+ case 186: return "sigaltstack"; break;
+ case 187: return "sendfile"; break;
+ case 188: return "getpmsg"; break;
+ case 189: return "putpmsg"; break;
+ case 190: return "vfork"; break;
+ case 191: return "ugetrlimit"; break;
+ case 192: return "mmap2"; break;
+ case 193: return "truncate64"; break;
+ case 194: return "ftruncate64"; break;
+ case 195: return "stat64"; break;
+ case 196: return "lstat64"; break;
+ case 197: return "fstat64"; break;
+ case 198: return "lchown32"; break;
+ case 199: return "getuid32"; break;
+ case 200: return "getgid32"; break;
+ case 201: return "geteuid32"; break;
+ case 202: return "getegid32"; break;
+ case 203: return "setreuid32"; break;
+ case 204: return "setregid32"; break;
+ case 205: return "getgroups32"; break;
+ case 206: return "setgroups32"; break;
+ case 207: return "fchown32"; break;
+ case 208: return "setresuid32"; break;
+ case 209: return "getresuid32"; break;
+ case 210: return "setresgid32"; break;
+ case 211: return "getresgid32"; break;
+ case 212: return "chown32"; break;
+ case 213: return "setuid32"; break;
+ case 214: return "setgid32"; break;
+ case 215: return "setfsuid32"; break;
+ case 216: return "setfsgid32"; break;
+ case 217: return "pivot_root"; break;
+ case 218: return "mincore"; break;
+ case 219: return "madvise1"; break;
+ case 220: return "getdents64"; break;
+ case 221: return "fcntl64"; break;
+ case 224: return "gettid"; break;
+ case 225: return "readahead"; break;
+ case 226: return "setxattr"; break;
+ case 227: return "lsetxattr"; break;
+ case 228: return "fsetxattr"; break;
+ case 229: return "getxattr"; break;
+ case 230: return "lgetxattr"; break;
+ case 231: return "fgetxattr"; break;
+ case 232: return "listxattr"; break;
+ case 233: return "llistxattr"; break;
+ case 234: return "flistxattr"; break;
+ case 235: return "removexattr"; break;
+ case 236: return "lremovexattr"; break;
+ case 237: return "fremovexattr"; break;
+ case 238: return "tkill"; break;
+ case 239: return "sendfile64"; break;
+ case 240: return "futex"; break;
+ case 241: return "sched_setaffinity"; break;
+ case 242: return "sched_getaffinity"; break;
+ case 243: return "set_thread_area"; break;
+ case 244: return "get_thread_area"; break;
+ case 245: return "io_setup"; break;
+ case 246: return "io_destroy"; break;
+ case 247: return "io_getevents"; break;
+ case 248: return "io_submit"; break;
+ case 249: return "io_cancel"; break;
+ case 250: return "fadvise64"; break;
+ case 252: return "exit_group"; break;
+ case 253: return "lookup_dcookie"; break;
+ case 254: return "epoll_create"; break;
+ case 255: return "epoll_ctl"; break;
+ case 256: return "epoll_wait"; break;
+ case 257: return "remap_file_pages"; break;
+ case 258: return "set_tid_address"; break;
+ case 259: return "timer_create"; break;
+ case 260: return "timer_settime"; break;
+ case 261: return "timer_gettime"; break;
+ case 262: return "timer_getoverrun"; break;
+ case 263: return "timer_delete"; break;
+ case 264: return "clock_settime"; break;
+ case 265: return "clock_gettime"; break;
+ case 266: return "clock_getres"; break;
+ case 267: return "clock_nanosleep"; break;
+ case 268: return "statfs64"; break;
+ case 269: return "fstatfs64"; break;
+ case 270: return "tgkill"; break;
+ case 271: return "utimes"; break;
+ case 272: return "fadvise64_64"; break;
+ case 273: return "vserver"; break;
+ case 274: return "mbind"; break;
+ case 275: return "get_mempolicy"; break;
+ case 276: return "set_mempolicy"; break;
+ case 277: return "mq_open"; break;
+ case 278: return "mq_unlink"; break;
+ case 279: return "mq_timedsend"; break;
+ case 280: return "mq_timedreceive"; break;
+ case 281: return "mq_notify"; break;
+ case 282: return "mq_getsetattr"; break;
+ case 283: return "kexec_load"; break;
+ case 284: return "waitid"; break;
+ case 285: return "sys_setaltroot"; break;
+ case 286: return "add_key"; break;
+ case 287: return "request_key"; break;
+ case 288: return "keyctl"; break;
+ case 289: return "ioprio_set"; break;
+ case 290: return "ioprio_get"; break;
+ case 291: return "inotify_init"; break;
+ case 292: return "inotify_add_watch"; break;
+ case 293: return "inotify_rm_watch"; break;
+ case 294: return "migrate_pages"; break;
+ case 295: return "openat"; break;
+ case 296: return "mkdirat"; break;
+ case 297: return "mknodat"; break;
+ case 298: return "fchownat"; break;
+ case 299: return "futimesat"; break;
+ case 300: return "fstatat64"; break;
+ case 301: return "unlinkat"; break;
+ case 302: return "renameat"; break;
+ case 303: return "linkat"; break;
+ case 304: return "symlinkat"; break;
+ case 305: return "readlinkat"; break;
+ case 306: return "fchmodat"; break;
+ case 307: return "faccessat"; break;
+ case 308: return "pselect6"; break;
+ case 309: return "ppoll"; break;
+ case 310: return "unshare"; break;
+ case 311: return "set_robust_list"; break;
+ case 312: return "get_robust_list"; break;
+ case 313: return "splice"; break;
+ case 314: return "sync_file_range"; break;
+ case 315: return "tee"; break;
+ case 316: return "vmsplice"; break;
+ case 317: return "move_pages"; break;
+ case 318: return "getcpu"; break;
+ case 319: return "epoll_pwait"; break;
+ case 320: return "utimensat"; break;
+ case 321: return "signalfd"; break;
+ case 322: return "timerfd_create"; break;
+ case 323: return "eventfd"; break;
+ case 324: return "fallocate"; break;
+ case 325: return "timerfd_settime"; break;
+ case 326: return "timerfd_gettime"; break;
+ case 327: return "signalfd4"; break;
+ case 328: return "eventfd2"; break;
+ case 329: return "epoll_create1"; break;
+ case 330: return "dup3"; break;
+ case 331: return "pipe2"; break;
+ case 332: return "inotify_init1"; break;
+ case 333: return "preadv"; break;
+ case 334: return "pwritev"; break;
+ case 335: return "rt_tgsigqueueinfo"; break;
+ case 336: return "perf_event_open"; break;
+ default: return "UNKNOWN"; break;
+ }
+}
+
+
+static char * get_linux_syscall_name64 (uint_t syscall_nr) {
+
+ switch (syscall_nr) {
+
+ case 0: return "read"; break;
+ case 1: return "write"; break;
+ case 2: return "open"; break;
+ case 3: return "close"; break;
+ case 4: return "stat"; break;
+ case 5: return "fstat"; break;
+ case 6: return "lstat"; break;
+ case 7: return "poll"; break;
+ case 8: return "lseek"; break;
+ case 9: return "mmap"; break;
+ case 10: return "mprotect"; break;
+ case 11: return "munmap"; break;
+ case 12: return "brk"; break;
+ case 13: return "rt_sigaction"; break;
+ case 14: return "rt_sigprocmask"; break;
+ case 15: return "rt_sigreturn"; break;
+ case 16: return "ioctl"; break;
+ case 17: return "pread64"; break;
+ case 18: return "pwrite64"; break;
+ case 19: return "readv"; break;
+ case 20: return "writev"; break;
+ case 21: return "access"; break;
+ case 22: return "pipe"; break;
+ case 23: return "select"; break;
+ case 24: return "sched_yield"; break;
+ case 25: return "mremap"; break;
+ case 26: return "msync"; break;
+ case 27: return "mincore"; break;
+ case 28: return "madvise"; break;
+ case 29: return "shmget"; break;
+ case 30: return "shmat"; break;
+ case 31: return "shmctl"; break;
+ case 32: return "dup"; break;
+ case 33: return "dup2"; break;
+ case 34: return "pause"; break;
+ case 35: return "nanosleep"; break;
+ case 36: return "getitimer"; break;
+ case 37: return "alarm"; break;
+ case 38: return "setitimer"; break;
+ case 39: return "getpid"; break;
+ case 40: return "sendfile"; break;
+ case 41: return "socket"; break;
+ case 42: return "connect"; break;
+ case 43: return "accept"; break;
+ case 44: return "sendto"; break;
+ case 45: return "recvfrom"; break;
+ case 46: return "sendmsg"; break;
+ case 47: return "recvmsg"; break;
+ case 48: return "shutdown"; break;
+ case 49: return "bind"; break;
+ case 50: return "listen"; break;
+ case 51: return "getsockname"; break;
+ case 52: return "getpeername"; break;
+ case 53: return "socketpair"; break;
+ case 54: return "setsockopt"; break;
+ case 55: return "getsockopt"; break;
+ case 56: return "clone"; break;
+ case 57: return "fork"; break;
+ case 58: return "vfork"; break;
+ case 59: return "execve"; break;
+ case 60: return "exit"; break;
+ case 61: return "wait4"; break;
+ case 62: return "kill"; break;
+ case 63: return "uname"; break;
+ case 64: return "semget"; break;
+ case 65: return "semop"; break;
+ case 66: return "semctl"; break;
+ case 67: return "shmdt"; break;
+ case 68: return "msgget"; break;
+ case 69: return "msgsnd"; break;
+ case 70: return "msgrcv"; break;
+ case 71: return "msgctl"; break;
+ case 72: return "fcntl"; break;
+ case 73: return "flock"; break;
+ case 74: return "fsync"; break;
+ case 75: return "fdatasync"; break;
+ case 76: return "truncate"; break;
+ case 77: return "ftruncate"; break;
+ case 78: return "getdents"; break;
+ case 79: return "getcwd"; break;
+ case 80: return "chdir"; break;
+ case 81: return "fchdir"; break;
+ case 82: return "rename"; break;
+ case 83: return "mkdir"; break;
+ case 84: return "rmdir"; break;
+ case 85: return "creat"; break;
+ case 86: return "link"; break;
+ case 87: return "unlink"; break;
+ case 88: return "symlink"; break;
+ case 89: return "readlink"; break;
+ case 90: return "chmod"; break;
+ case 91: return "fchmod"; break;
+ case 92: return "chown"; break;
+ case 93: return "fchown"; break;
+ case 94: return "lchown"; break;
+ case 95: return "umask"; break;
+ case 96: return "gettimeofday"; break;
+ case 97: return "getrlimit"; break;
+ case 98: return "getrusage"; break;
+ case 99: return "sysinfo"; break;
+ case 100: return "times"; break;
+ case 101: return "ptrace"; break;
+ case 102: return "getuid"; break;
+ case 103: return "syslog"; break;
+ case 104: return "getgid"; break;
+ case 105: return "setuid"; break;
+ case 106: return "setgid"; break;
+ case 107: return "geteuid"; break;
+ case 108: return "getegid"; break;
+ case 109: return "setpgid"; break;
+ case 110: return "getppid"; break;
+ case 111: return "getpgrp"; break;
+ case 112: return "setsid"; break;
+ case 113: return "setreuid"; break;
+ case 114: return "setregid"; break;
+ case 115: return "getgroups"; break;
+ case 116: return "setgroups"; break;
+ case 117: return "setresuid"; break;
+ case 118: return "getresuid"; break;
+ case 119: return "setresgid"; break;
+ case 120: return "getresgid"; break;
+ case 121: return "getpgid"; break;
+ case 122: return "setfsuid"; break;
+ case 123: return "setfsgid"; break;
+ case 124: return "getsid"; break;
+ case 125: return "capget"; break;
+ case 126: return "capset"; break;
+ case 127: return "rt_sigpending"; break;
+ case 128: return "rt_sigtimedwait"; break;
+ case 129: return "rt_sigqueueinfo"; break;
+ case 130: return "rt_sigsuspend"; break;
+ case 131: return "sigaltstack"; break;
+ case 132: return "utime"; break;
+ case 133: return "mknod"; break;
+ case 134: return "uselib"; break;
+ case 135: return "personality"; break;
+ case 136: return "ustat"; break;
+ case 137: return "statfs"; break;
+ case 138: return "fstatfs"; break;
+ case 139: return "sysfs"; break;
+ case 140: return "getpriority"; break;
+ case 141: return "setpriority"; break;
+ case 142: return "sched_setparam"; break;
+ case 143: return "sched_getparam"; break;
+ case 144: return "sched_setscheduler"; break;
+ case 145: return "sched_getscheduler"; break;
+ case 146: return "sched_get_priority_max"; break;
+ case 147: return "sched_get_priority_min"; break;
+ case 148: return "sched_rr_get_interval"; break;
+ case 149: return "mlock"; break;
+ case 150: return "munlock"; break;
+ case 151: return "mlockall"; break;
+ case 152: return "munlockall"; break;
+ case 153: return "vhangup"; break;
+ case 154: return "modify_ldt"; break;
+ case 155: return "pivot_root"; break;
+ case 156: return "_sysctl"; break;
+ case 157: return "prctl"; break;
+ case 158: return "arch_prctl"; break;
+ case 159: return "adjtimex"; break;
+ case 160: return "setrlimit"; break;
+ case 161: return "chroot"; break;
+ case 162: return "sync"; break;
+ case 163: return "acct"; break;
+ case 164: return "settimeofday"; break;
+ case 165: return "mount"; break;
+ case 166: return "umount2"; break;
+ case 167: return "swapon"; break;
+ case 168: return "swapoff"; break;
+ case 169: return "reboot"; break;
+ case 170: return "sethostname"; break;
+ case 171: return "setdomainname"; break;
+ case 172: return "iopl"; break;
+ case 173: return "ioperm"; break;
+ case 174: return "create_module"; break;
+ case 175: return "init_module"; break;
+ case 176: return "delete_module"; break;
+ case 177: return "get_kernel_syms"; break;
+ case 178: return "query_module"; break;
+ case 179: return "quotactl"; break;
+ case 180: return "nfsservctl"; break;
+ case 181: return "getpmsg"; break;
+ case 182: return "putpmsg"; break;
+ case 183: return "afs_syscall"; break;
+ case 184: return "tuxcall"; break;
+ case 185: return "security"; break;
+ case 186: return "gettid"; break;
+ case 187: return "readahead"; break;
+ case 188: return "setxattr"; break;
+ case 189: return "lsetxattr"; break;
+ case 190: return "fsetxattr"; break;
+ case 191: return "getxattr"; break;
+ case 192: return "lgetxattr"; break;
+ case 193: return "fgetxattr"; break;
+ case 194: return "listxattr"; break;
+ case 195: return "llistxattr"; break;
+ case 196: return "flistxattr"; break;
+ case 197: return "removexattr"; break;
+ case 198: return "lremovexattr"; break;
+ case 199: return "fremovexattr"; break;
+ case 200: return "tkill"; break;
+ case 201: return "time"; break;
+ case 202: return "futex"; break;
+ case 203: return "sched_setaffinity"; break;
+ case 204: return "sched_getaffinity"; break;
+ case 205: return "set_thread_area"; break;
+ case 206: return "io_setup"; break;
+ case 207: return "io_destroy"; break;
+ case 208: return "io_getevents"; break;
+ case 209: return "io_submit"; break;
+ case 210: return "io_cancel"; break;
+ case 211: return "get_thread_area"; break;
+ case 212: return "lookup_dcookie"; break;
+ case 213: return "epoll_create"; break;
+ case 214: return "epoll_ctl_old"; break;
+ case 215: return "epoll_wait_old"; break;
+ case 216: return "remap_file_pages"; break;
+ case 217: return "getdents64"; break;
+ case 218: return "set_tid_address"; break;
+ case 219: return "restart_syscall"; break;
+ case 220: return "semtimedop"; break;
+ case 221: return "fadvise64"; break;
+ case 222: return "timer_create"; break;
+ case 223: return "timer_settime"; break;
+ case 224: return "timer_gettime"; break;
+ case 225: return "timer_getoverrun"; break;
+ case 226: return "timer_delete"; break;
+ case 227: return "clock_settime"; break;
+ case 228: return "clock_gettime"; break;
+ case 229: return "clock_getres"; break;
+ case 230: return "clock_nanosleep"; break;
+ case 231: return "exit_group"; break;
+ case 232: return "epoll_wait"; break;
+ case 233: return "epoll_ctl"; break;
+ case 234: return "tgkill"; break;
+ case 235: return "utimes"; break;
+ case 236: return "vserver"; break;
+ case 237: return "mbind"; break;
+ case 238: return "set_mempolicy"; break;
+ case 239: return "get_mempolicy"; break;
+ case 240: return "mq_open"; break;
+ case 241: return "mq_unlink"; break;
+ case 242: return "mq_timedsend"; break;
+ case 243: return "mq_timedreceive"; break;
+ case 244: return "mq_notify"; break;
+ case 245: return "mq_getsetattr"; break;
+ case 246: return "kexec_load"; break;
+ case 247: return "waitid"; break;
+ case 248: return "add_key"; break;
+ case 249: return "request_key"; break;
+ case 250: return "keyctl"; break;
+ case 251: return "ioprio_set"; break;
+ case 252: return "ioprio_get"; break;
+ case 253: return "inotify_init"; break;
+ case 254: return "inotify_add_watch"; break;
+ case 255: return "inotify_rm_watch"; break;
+ case 256: return "migrate_pages"; break;
+ case 257: return "openat"; break;
+ case 258: return "mkdirat"; break;
+ case 259: return "mknodat"; break;
+ case 260: return "fchownat"; break;
+ case 261: return "futimesat"; break;
+ case 262: return "newfstatat"; break;
+ case 263: return "unlinkat"; break;
+ case 264: return "renameat"; break;
+ case 265: return "linkat"; break;
+ case 266: return "symlinkat"; break;
+ case 267: return "readlinkat"; break;
+ case 268: return "fchmodat"; break;
+ case 269: return "faccessat"; break;
+ case 270: return "pselect6"; break;
+ case 271: return "ppoll"; break;
+ case 272: return "unshare"; break;
+ case 273: return "set_robust_list"; break;
+ case 274: return "get_robust_list"; break;
+ case 275: return "splice"; break;
+ case 276: return "tee"; break;
+ case 277: return "sync_file_range"; break;
+ case 278: return "vmsplice"; break;
+ case 279: return "move_pages"; break;
+ case 280: return "utimensat"; break;
+ case 281: return "epoll_pwait"; break;
+ case 282: return "signalfd"; break;
+ case 283: return "timerfd_create"; break;
+ case 284: return "eventfd"; break;
+ case 285: return "fallocate"; break;
+ case 286: return "timerfd_settime"; break;
+ case 287: return "timerfd_gettime"; break;
+ case 288: return "accept4"; break;
+ case 289: return "signalfd4"; break;
+ case 290: return "eventfd2"; break;
+ case 291: return "epoll_create1"; break;
+ case 292: return "dup3"; break;
+ case 293: return "pipe2"; break;
+ case 294: return "inotify_init1"; break;
+ case 295: return "preadv"; break;
+ case 296: return "pwritev"; break;
+ case 297: return "rt_tgsigqueueinfo"; break;
+ case 298: return "perf_event_open"; break;
+ default: return "UNKNOWN"; break;
+ }
+}
+
+#endif
break;
case V3_SOFTWARE_INTR:
guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
+
+#ifdef V3_CONFIG_DEBUG_INTERRUPTS
+ PrintDebug("Injecting software interrupt -- type: %d, vector: %d\n",
+ SVM_INJECTION_SOFT_INTR, info->intr_core_state.swintr_vector);
+#endif
+ guest_ctrl->EVENTINJ.vector = info->intr_core_state.swintr_vector;
+ guest_ctrl->EVENTINJ.valid = 1;
+
+ /* reset swintr state */
+ info->intr_core_state.swintr_posted = 0;
+ info->intr_core_state.swintr_vector = 0;
+
break;
case V3_VIRTUAL_IRQ:
guest_ctrl->EVENTINJ.type = SVM_INJECTION_IRQ;
#include <palacios/vmm_telemetry.h>
#endif
-
+#ifdef V3_CONFIG_EXT_SW_INTERRUPTS
+#include <interfaces/sw_intr.h>
+#endif
int v3_handle_svm_exit(struct guest_info * info, addr_t exit_code, addr_t exit_info1, addr_t exit_info2) {
// Force exit on other cores
break;
+#ifdef V3_CONFIG_EXT_SW_INTERRUPTS
+ case VMEXIT_SWINT:
+#ifdef V3_CONFIG_DEBUG_EXT_SW_INTERRUPTS
+ PrintDebug("Intercepted a software interrupt\n");
+#endif
+ if (v3_handle_swintr(info) == -1) {
+ PrintError("Error handling software interrupt\n");
+ return -1;
+ }
+ break;
+#endif
/* Exits Following this line are NOT HANDLED */
#include <palacios/vmm.h>
#include <palacios/vmm_paging.h>
+#ifndef V3_CONFIG_DEBUG_MEM_ERRORS
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
extern struct v3_os_hooks * os_hooks;
*hpa = (addr_t)(os_hooks)->vaddr_to_paddr((void *)hva);
if (*hpa == 0) {
- PrintError("In HVA->HPA: Invalid HVA(%p)->HPA lookup\n",
+ PrintDebug("In HVA->HPA: Invalid HVA(%p)->HPA lookup\n",
(void *)hva);
return -1;
}
} else {
- PrintError("In HVA->HPA: os_hooks not defined\n");
+ PrintDebug("In HVA->HPA: os_hooks not defined\n");
return -1;
}
return 0;
*hva = (addr_t)(os_hooks)->paddr_to_vaddr((void *)hpa);
if (*hva == 0) {
- PrintError("In HPA->HVA: Invalid HPA(%p)->HVA lookup\n",
+ PrintDebug("In HPA->HVA: Invalid HPA(%p)->HVA lookup\n",
(void *)hpa);
return -1;
}
} else {
- PrintError("In HPA->HVA: os_hooks not defined\n");
+ PrintDebug("In HPA->HVA: os_hooks not defined\n");
return -1;
}
return 0;
struct v3_mem_region * reg = v3_get_mem_region(info->vm_info, info->vcpu_id, gpa);
if (reg == NULL) {
- PrintError("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n",
+ PrintDebug("In GPA->HPA: Could not find address in shadow map (addr=%p) (NULL REGION)\n",
(void *)gpa);
return -1;
}
if (reg->flags.alloced == 0) {
- //PrintError("In GPA->HPA: Tried to translate physical address of non allocated page (addr=%p)\n",
+ //PrintDebug("In GPA->HPA: Tried to translate physical address of non allocated page (addr=%p)\n",
// (void *)gpa);
//v3_print_mem_map(info->vm_info);
return -1;
//
int v3_hpa_to_gpa(struct guest_info * guest_info, addr_t hpa, addr_t * gpa) {
*gpa = 0;
- PrintError("ERROR!!! HPA->GPA currently not implemented!!!\n");
+ PrintDebug("ERROR!!! HPA->GPA currently not implemented!!!\n");
return -1;
}
*gpa = 0;
if (v3_hva_to_hpa(hva, &hpa) != 0) {
- PrintError("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
+ PrintDebug("In HVA->GPA: Invalid HVA(%p)->HPA lookup\n",
(void *)hva);
return -1;
}
if (v3_hpa_to_gpa(guest_info, hpa, gpa) != 0) {
- PrintError("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
+ PrintDebug("In HVA->GPA: Invalid HPA(%p)->GPA lookup\n",
(void *)hpa);
return -1;
}
*hva = 0;
if (v3_gpa_to_hpa(guest_info, gpa, &hpa) != 0) {
- // PrintError("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
+ // PrintDebug("In GPA->HVA: Invalid GPA(%p)->HPA lookup\n",
// (void *)gpa);
return -1;
}
if (v3_hpa_to_hva(hpa, hva) != 0) {
- PrintError("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
+ PrintDebug("In GPA->HVA: Invalid HPA(%p)->HVA lookup\n",
(void *)hpa);
return -1;
}
*/
int v3_gpa_to_gva(struct guest_info * guest_info, addr_t gpa, addr_t * gva) {
*gva = 0;
- PrintError("ERROR!!: GPA->GVA Not Implemented!!\n");
+ PrintDebug("ERROR!!: GPA->GVA Not Implemented!!\n");
return -1;
}
*hpa = 0;
if (v3_gva_to_gpa(guest_info, gva, &gpa) != 0) {
- PrintError("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
+ PrintDebug("In GVA->HPA: Invalid GVA(%p)->GPA lookup\n",
(void *)gva);
return -1;
}
if (v3_gpa_to_hpa(guest_info, gpa, hpa) != 0) {
- PrintError("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
+ PrintDebug("In GVA->HPA: Invalid GPA(%p)->HPA lookup\n",
(void *)gpa);
return -1;
}
*gva = 0;
if (v3_hpa_to_gpa(guest_info, hpa, &gpa) != 0) {
- PrintError("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
+ PrintDebug("In HPA->GVA: Invalid HPA(%p)->GPA lookup\n",
(void *)hpa);
return -1;
}
if (v3_gpa_to_gva(guest_info, gpa, gva) != 0) {
- PrintError("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
+ PrintDebug("In HPA->GVA: Invalid GPA(%p)->GVA lookup\n",
(void *)gpa);
return -1;
}
*hva = 0;
if (v3_gva_to_gpa(guest_info, gva, &gpa) != 0) {
- PrintError("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
+ PrintDebug("In GVA->HVA: Invalid GVA(%p)->GPA lookup\n",
(void *)gva);
return -1;
}
if (v3_gpa_to_hpa(guest_info, gpa, &hpa) != 0) {
- PrintError("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
+ PrintDebug("In GVA->HVA: Invalid GPA(%p)->HPA lookup\n",
(void *)gpa);
return -1;
}
if (v3_hpa_to_hva(hpa, hva) != 0) {
- PrintError("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
+ PrintDebug("In GVA->HVA: Invalid HPA(%p)->HVA lookup\n",
(void *)hpa);
return -1;
}
*gva = 0;
if (v3_hva_to_hpa(hva, &hpa) != 0) {
- PrintError("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
+ PrintDebug("In HVA->GVA: Invalid HVA(%p)->HPA lookup\n",
(void *)hva);
return -1;
}
if (v3_hpa_to_gpa(guest_info, hpa, &gpa) != 0) {
- PrintError("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
+ PrintDebug("In HVA->GVA: Invalid HPA(%p)->GPA lookup\n",
(void *)hva);
return -1;
}
if (v3_gpa_to_gva(guest_info, gpa, gva) != 0) {
- PrintError("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
+ PrintDebug("In HVA->GVA: Invalid GPA(%p)->GVA lookup\n",
(void *)gpa);
return -1;
}
+int v3_raise_swintr (struct guest_info * core, uint8_t vector) {
+ struct v3_intr_core_state * intr_state = &(core->intr_core_state);
+
+ PrintDebug("Signaling software interrupt in v3_signal_swintr()\n");
+ PrintDebug("\tINT vector: %d\n", vector);
+
+ intr_state->swintr_posted = 1;
+ intr_state->swintr_vector = vector;
+ return 0;
+}
+
+
int v3_raise_virq(struct guest_info * info, int irq) {
struct v3_intr_core_state * intr_state = &(info->intr_core_state);
}
+
+
void v3_clear_pending_intr(struct guest_info * core) {
struct v3_intr_core_state * intr_state = &(core->intr_core_state);
}
}
}
+
+ /* for swintr injection */
+ if (intr_state->swintr_posted == 1) {
+ ret = V3_SOFTWARE_INTR;
+ }
v3_unlock_irqrestore(intr_state->irq_lock, irq_state);