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.


Merge branch 'devel' of ssh://newskysaw.cs.northwestern.edu//home/palacios/palacios...
Jack Lange [Thu, 16 Jun 2011 17:29:38 +0000 (13:29 -0400)]
40 files changed:
linux_module/Makefile
linux_module/iface-console.c [moved from linux_module/palacios-console.c with 99% similarity]
linux_module/iface-file.c [moved from linux_module/palacios-file.c with 100% similarity]
linux_module/iface-graphics-console.c [moved from linux_module/palacios-graphics-console.c with 99% similarity]
linux_module/iface-graphics-console.h [moved from linux_module/palacios-graphics-console.h with 100% similarity]
linux_module/iface-host-dev.c [moved from linux_module/palacios-host-dev.c with 99% similarity]
linux_module/iface-host-dev.h [moved from linux_module/palacios-host-dev-user.h with 100% similarity]
linux_module/iface-keyed-stream.c [moved from linux_module/palacios-keyed-stream.c with 99% similarity]
linux_module/iface-packet.c [moved from linux_module/palacios-packet.c with 93% similarity]
linux_module/iface-socket.c [moved from linux_module/palacios-socket.c with 100% similarity]
linux_module/iface-stream.c [moved from linux_module/palacios-stream.c with 98% similarity]
linux_module/iface-stream.h [new file with mode: 0644]
linux_module/inspector.c [moved from linux_module/palacios-inspector.c with 97% similarity]
linux_module/ioctls.txt [new file with mode: 0644]
linux_module/main.c [moved from linux_module/palacios-dev.c with 99% similarity]
linux_module/mm.c [moved from linux_module/palacios-mm.c with 100% similarity]
linux_module/mm.h [moved from linux_module/palacios-mm.h with 100% similarity]
linux_module/palacios-serial.h [deleted file]
linux_module/palacios-stubs.c [moved from linux_module/palacios.c with 99% similarity]
linux_module/palacios-vnet-ctrl.c
linux_module/palacios-vnet.c
linux_module/palacios-vnet.h
linux_module/palacios.h
linux_module/util-hashtable.c [moved from linux_module/palacios-hashtable.c with 99% similarity]
linux_module/util-hashtable.h [moved from linux_module/palacios-hashtable.h with 100% similarity]
linux_module/util-queue.c [moved from linux_module/palacios-queue.c with 98% similarity]
linux_module/util-queue.h [moved from linux_module/palacios-queue.h with 100% similarity]
linux_module/util-ringbuffer.c [moved from linux_module/palacios-ringbuffer.c with 95% similarity]
linux_module/util-ringbuffer.h [moved from linux_module/palacios-ringbuffer.h with 100% similarity]
linux_module/vm.c [moved from linux_module/palacios-vm.c with 98% similarity]
linux_module/vm.h [moved from linux_module/palacios-vm.h with 100% similarity]
linux_usr/v3_user_host_dev.h
palacios/include/palacios/vmm_instr_decoder.h
palacios/src/devices/8254.c
palacios/src/devices/apic.c
palacios/src/palacios/svm.c
palacios/src/palacios/vmm_halt.c
palacios/src/palacios/vmm_time.c
palacios/src/palacios/vmx.c
palacios/src/vnet/vnet_core.c

index bedce06..137674c 100644 (file)
@@ -9,44 +9,37 @@ endif
 EXTRA_CFLAGS  += -I$(PWD)/../palacios/include/ -include autoconf.h -DMODULE=1 -D__KERNEL__=1
 
 
-v3vee-y :=     palacios.o \
-               palacios-dev.o \
-               palacios-vm.o \
-               palacios-mm.o \
-               palacios-queue.o \
-               palacios-hashtable.o \
+v3vee-y :=     palacios-stubs.o \
+               main.o \
+               vm.o \
+               mm.o \
+               util-queue.o \
+               util-hashtable.o \
                linux-exts.o
 
-v3vee-$(V3_CONFIG_CONSOLE) += palacios-console.o
-v3vee-$(V3_CONFIG_FILE) += palacios-file.o
-v3vee-$(V3_CONFIG_STREAM) +=   palacios-stream.o \
-                               palacios-ringbuffer.o
-v3vee-$(V3_CONFIG_EXT_INSPECTOR) += palacios-inspector.o
-v3vee-$(V3_CONFIG_PACKET) += palacios-packet.o
-v3vee-$(V3_CONFIG_SOCKET) += palacios-socket.o
-v3vee-$(V3_CONFIG_KEYED_STREAMS) += palacios-keyed-stream.o
-v3vee-$(V3_CONFIG_HOST_DEVICE) += palacios-host-dev.o
-v3vee-$(V3_CONFIG_GRAPHICS_CONSOLE) += palacios-graphics-console.o
+v3vee-$(V3_CONFIG_CONSOLE) += iface-console.o
+v3vee-$(V3_CONFIG_FILE) += iface-file.o
+v3vee-$(V3_CONFIG_STREAM) +=   iface-stream.o \
+                               util-ringbuffer.o
+v3vee-$(V3_CONFIG_EXT_INSPECTOR) += inspector.o
+v3vee-$(V3_CONFIG_PACKET) += iface-packet.o
+v3vee-$(V3_CONFIG_SOCKET) += iface-socket.o
+v3vee-$(V3_CONFIG_KEYED_STREAMS) += iface-keyed-stream.o
+v3vee-$(V3_CONFIG_HOST_DEVICE) += iface-host-dev.o
+v3vee-$(V3_CONFIG_GRAPHICS_CONSOLE) += iface-graphics-console.o
 
 v3vee-$(V3_CONFIG_VNET) +=     palacios-vnet.o \
                                palacios-vnet-ctrl.o   \
                                palacios-vnet-brg.o
 
 
-
-
-
 v3vee-objs := $(v3vee-y) ../libv3vee.a
-
 obj-m := v3vee.o
 
 
-
 all:
        $(MAKE) -C $(V3_CONFIG_LINUX_KERN) M=$(PWD) modules
 
-
-
 clean:
        $(MAKE) -C $(V3_CONFIG_LINUX_KERN) M=$(PWD) clean
 
similarity index 99%
rename from linux_module/palacios-console.c
rename to linux_module/iface-console.c
index d0c85ba..02d9761 100644 (file)
@@ -16,9 +16,9 @@
 #include <interfaces/vmm_console.h>
 #include <palacios/vmm_host_events.h>
 
-#include "palacios-vm.h"
+#include "vm.h"
 #include "palacios.h"
-#include "palacios-queue.h"
+#include "util-queue.h"
 #include "linux-exts.h"
 
 typedef enum { CONSOLE_CURS_SET = 1,
similarity index 99%
rename from linux_module/palacios-graphics-console.c
rename to linux_module/iface-graphics-console.c
index e1d9216..227e90e 100644 (file)
 
 #include <interfaces/vmm_console.h>
 #include <palacios/vmm_host_events.h>
-#include "palacios-graphics-console.h"
+#include "iface-graphics-console.h"
 
 
 #include "palacios.h"
 #include "linux-exts.h"
-#include "palacios-vm.h"
+#include "vm.h"
 
 #include <linux/vmalloc.h>
 
similarity index 99%
rename from linux_module/palacios-host-dev.c
rename to linux_module/iface-host-dev.c
index 927b5ad..6744d66 100644 (file)
@@ -17,9 +17,9 @@
 #include <interfaces/vmm_host_dev.h>
 
 #include "palacios.h"
-#include "palacios-host-dev-user.h"
+#include "iface-host-dev.h"
 #include "linux-exts.h"
-#include "palacios-vm.h"
+#include "vm.h"
 
 /*
   There are two things in this file:
similarity index 99%
rename from linux_module/palacios-keyed-stream.c
rename to linux_module/iface-keyed-stream.c
index ef185a5..792066a 100644 (file)
@@ -1,5 +1,5 @@
 #include "palacios.h"
-#include "palacios-hashtable.h"
+#include "util-hashtable.h"
 #include "linux-exts.h"
 
 #define sint64_t int64_t
similarity index 93%
rename from linux_module/palacios-packet.c
rename to linux_module/iface-packet.c
index d51c7e7..d72306e 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "palacios.h"
 #include "linux-exts.h"
+
 struct palacios_packet_state {
     struct socket * raw_sock;
     uint8_t inited;
@@ -66,35 +67,38 @@ static int palacios_packet_add_recver(const char * mac,
 }
 
 static int palacios_packet_del_recver(const char * mac,
-                                        struct v3_vm_info * vm){
+                                     struct v3_vm_info * vm){
 
     return 0;
 }
 
-static int init_raw_socket (const char * eth_dev){
+static int init_raw_socket(const char * eth_dev){
     int err;
     struct sockaddr_ll sock_addr;
     struct ifreq if_req;
     int dev_idx;
 
     err = sock_create(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL), &(packet_state.raw_sock)); 
+
     if (err < 0) {
        printk(KERN_WARNING "Could not create a PF_PACKET Socket, err %d\n", err);
        return -1;
     }
 
-    if(eth_dev == NULL){
+    if (eth_dev == NULL){
        eth_dev = "eth0"; /* default "eth0" */
     }
 
     memset(&if_req, 0, sizeof(if_req));
     strncpy(if_req.ifr_name, eth_dev, IFNAMSIZ);  //sizeof(if_req.ifr_name));
+
     err = packet_state.raw_sock->ops->ioctl(packet_state.raw_sock, SIOCGIFINDEX, (long)&if_req);
-    if(err < 0){
-       printk(KERN_WARNING "Palacios Packet: Unable to get index for device %s, error %d\n", if_req.ifr_name, err);
+
+    if (err < 0){
+       printk(KERN_WARNING "Palacios Packet: Unable to get index for device %s, error %d\n", 
+              if_req.ifr_name, err);
        dev_idx = 2; /* match ALL  2:"eth0" */
-    }
-    else{
+    } else {
        dev_idx = if_req.ifr_ifindex;
     }
 
@@ -105,7 +109,10 @@ static int init_raw_socket (const char * eth_dev){
     sock_addr.sll_protocol = htons(ETH_P_ALL);
     sock_addr.sll_ifindex = dev_idx;
 
-    err = packet_state.raw_sock->ops->bind(packet_state.raw_sock, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
+    err = packet_state.raw_sock->ops->bind(packet_state.raw_sock, 
+                                          (struct sockaddr *)&sock_addr, 
+                                          sizeof(sock_addr));
+
     if (err < 0){
        printk(KERN_WARNING "Error binding raw packet to device %s, %d\n", eth_dev, err);
        return -1;
@@ -208,6 +215,7 @@ static int packet_server(void * arg) {
 
     while (!kthread_should_stop()) {
        size = recv_pkt(pkt, ETHERNET_PACKET_LEN);
+
        if (size < 0) {
            printk(KERN_WARNING "Palacios raw packet receive error, Server terminated\n");
            break;
@@ -223,7 +231,8 @@ static int packet_server(void * arg) {
 
 
        vm = (struct v3_vm_info *)v3_htable_search(packet_state.mac_vm_cache, (addr_t)pkt);
-       if(vm != NULL){
+
+       if (vm != NULL){
            printk("Find destinated VM 0x%p\n", vm);
            send_raw_packet_to_palacios(pkt, size, vm);
        }
@@ -237,10 +246,10 @@ static int packet_init( void ) {
 
     const char * eth_dev = NULL;
 
-    if(packet_state.inited == 0){
+    if (packet_state.inited == 0){
        packet_state.inited = 1;
 
-       if(init_raw_socket(eth_dev) == -1){
+       if (init_raw_socket(eth_dev) == -1){
            printk("Error to initiate palacios packet interface\n");
            return -1;
        }
@@ -253,7 +262,7 @@ static int packet_init( void ) {
     }
        
 
-    // REGISTER GLOBAL CONTROL to add devices...
+    // REGISTER GLOBAL CONTROL to add interfaces...
 
     return 0;
 }
similarity index 98%
rename from linux_module/palacios-stream.c
rename to linux_module/iface-stream.c
index 411c119..7f03994 100644 (file)
 
 #include <interfaces/vmm_stream.h>
 #include "linux-exts.h"
-#include "palacios-ringbuffer.h"
-#include "palacios-vm.h"
+#include "util-ringbuffer.h"
+#include "vm.h"
+#include "iface-stream.h"
 
 #define STREAM_BUF_SIZE 1024
-#define STREAM_NAME_LEN 128
+
 
 
 
@@ -186,6 +187,8 @@ static int stream_connect(struct v3_guest * guest, unsigned int cmd, unsigned lo
        return -EFAULT;
     }
     
+
+
     printk("ERROR: Opening Streams is currently not implemented...\n");
 
     return -EFAULT;
diff --git a/linux_module/iface-stream.h b/linux_module/iface-stream.h
new file mode 100644 (file)
index 0000000..10a3353
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __IFACE_STREAM_H__
+#define __IFACE_STREAM_H__
+
+
+// Stream Connection IOCTL number
+#define V3_VM_STREAM_CONNECT 21
+
+// Buffer size of the stream name being connected to
+#define STREAM_NAME_LEN 128
+
+
+#endif 
similarity index 97%
rename from linux_module/palacios-inspector.c
rename to linux_module/inspector.c
index 340821b..b6cfc1a 100644 (file)
 #include <interfaces/inspector.h>
 
 #include "palacios.h"
-#include "palacios-vm.h"
+#include "vm.h"
 #include "linux-exts.h"
 
-struct dentry * v3_dir = NULL;
+static struct dentry * v3_dir = NULL;
 
 
 
diff --git a/linux_module/ioctls.txt b/linux_module/ioctls.txt
new file mode 100644 (file)
index 0000000..ee0e32d
--- /dev/null
@@ -0,0 +1,23 @@
+Registry of ioctl numbers currently in use
+To add a new ioctl find an available number and add it to this list.
+
+Global commands (/dev/v3vee)
+
+10 -- (VMM) Start guest
+
+50 -- (VMM) Add physical memory to VMM manager
+
+
+
+VM Commands (/dev/v3-vm*)
+
+20 -- (IFACE) Connect CGA Console
+21 -- (IFACE) Connect Stream
+22 -- (VMM) Stop Guest
+
+30 -- (EXT) Activate Inspector
+
+257 -- (IFACE) VGA Console Framebuf Input
+258 -- (IFACE) VGA Console Framebuf Query
+
+10245 -- (IFACE) Connect Host Device
\ No newline at end of file
similarity index 99%
rename from linux_module/palacios-dev.c
rename to linux_module/main.c
index f640403..621ab58 100644 (file)
@@ -19,8 +19,8 @@
 #include <linux/kthread.h>
 
 #include "palacios.h"
-#include "palacios-mm.h"
-#include "palacios-vm.h"
+#include "mm.h"
+#include "vm.h"
 
 #include "linux-exts.h"
 
similarity index 100%
rename from linux_module/palacios-mm.c
rename to linux_module/mm.c
similarity index 100%
rename from linux_module/palacios-mm.h
rename to linux_module/mm.h
diff --git a/linux_module/palacios-serial.h b/linux_module/palacios-serial.h
deleted file mode 100644 (file)
index e9fa8a0..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Palacios VM Stream Serial interface
- * (c) Jack Lange, 2010
- */
-
-#ifndef __PALACIOS_SERIAL_H__
-#define __PALACIOS_SERIAL_H__
-
-int open_serial(char * name);
-
-#endif
similarity index 99%
rename from linux_module/palacios.c
rename to linux_module/palacios-stubs.c
index fc64360..be06001 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/kthread.h>
 #include <asm/uaccess.h>
 #include <linux/smp.h>
-#include <linux/smp_lock.h>
 
 #include <palacios/vmm.h>
 #include <palacios/vmm_host_events.h>
@@ -23,7 +22,7 @@
 
 
 
-#include "palacios-mm.h"
+#include "mm.h"
 
 
 u32 pg_allocs = 0;
@@ -158,11 +157,9 @@ static int lnx_thread_target(void * arg) {
     struct lnx_thread_arg * thread_info = (struct lnx_thread_arg *)arg;
 
     /*
-      lock_kernel();
       printk("Daemonizing new Palacios thread (name=%s)\n", thread_info->name);
 
       daemonize(thread_info->name);
-      unlock_kernel();
       allow_signal(SIGKILL);
     */
 
index f0bbac5..4cd1c15 100644 (file)
@@ -611,7 +611,8 @@ route_write(struct file * file,
        } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
            char * idx_str = NULL;
            uint32_t d_idx;
-           
+           struct vnet_route_iter * route = NULL;
+
            idx_str = strsep(&buf_iter, " ");
            
            if (!idx_str) {
@@ -621,10 +622,14 @@ route_write(struct file * file,
 
            d_idx = simple_strtoul(idx_str, &idx_str, 10);
 
-           v3_vnet_del_route(d_idx);
-               
-           printk("VNET Control: One route deleted\n");                
+           printk("VNET: deleting route %d\n", d_idx);
 
+           list_for_each_entry(route, &(vnet_ctrl_s.route_list), node) {
+               if (route->idx == d_idx) {
+                   delete_route(route);
+                   break;
+               }
+           }
        } else {
            printk("Invalid Route command string\n");
        }
index 1584ab1..7070c6d 100644 (file)
@@ -14,8 +14,9 @@
 #include <linux/timer.h>
 
 #include <vnet/vnet.h>
-#include "palacios-mm.h"
+#include "mm.h"
 #include "palacios-vnet.h"
+#include "linux-exts.h"
 
 static void host_print(const char *    fmt, ...) {
 
index 56ac9f1..6acf6c9 100644 (file)
@@ -8,8 +8,6 @@
 
 #include <vnet/vnet.h>
 
-int  palacios_vnet_init(void);
-void palacios_vnet_deinit(void);
 
 typedef enum {UDP, TCP, RAW, NONE} vnet_brg_proto_t;
 
@@ -26,6 +24,8 @@ void vnet_brg_delete_link(uint32_t idx);
 uint32_t vnet_brg_add_link(uint32_t ip, uint16_t port, vnet_brg_proto_t proto);
 int vnet_brg_link_stats(uint32_t link_idx, struct nic_statistics * stats);
 int vnet_brg_stats(struct vnet_brg_stats * stats);
+
+
 int  vnet_bridge_init(void);
 void vnet_bridge_deinit(void);
 
index df9aabe..56d5abf 100644 (file)
 /* Global Control IOCTLs */
 #define V3_START_GUEST 10
 #define V3_ADD_MEMORY 50
-#define V3_START_NETWORK 60
 
 /* VM Specific IOCTLs */
 #define V3_VM_CONSOLE_CONNECT 20
-#define V3_VM_STREAM_CONNECT 21
+
 #define V3_VM_STOP 22
 
 #define V3_VM_INSPECT 30
similarity index 99%
rename from linux_module/palacios-hashtable.c
rename to linux_module/util-hashtable.c
index 6c025fc..52fc594 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/preempt.h>
 #include <linux/sched.h>
  
-#include "palacios-hashtable.h"
+#include "util-hashtable.h"
 
 
 struct hash_entry {
similarity index 98%
rename from linux_module/palacios-queue.c
rename to linux_module/util-queue.c
index 3e0249b..58221a6 100644 (file)
@@ -19,7 +19,7 @@
 
 #include <linux/slab.h>
 
-#include "palacios-queue.h"
+#include "util-queue.h"
 
 void init_queue(struct gen_queue * queue, unsigned int max_entries) {
     queue->num_entries = 0;
similarity index 95%
rename from linux_module/palacios-ringbuffer.c
rename to linux_module/util-ringbuffer.c
index 2ab5b50..53071e8 100644 (file)
@@ -1,29 +1,29 @@
-/* 
+/* \r
  * Ringbuffer Routines for VM\r
- * (c) Lei Xia, 2010
+ * (c) Lei Xia, 2010\r
  */\r
-#include <linux/errno.h>
-#include <linux/percpu.h>
+#include <linux/errno.h>\r
+#include <linux/percpu.h>\r
 #include <linux/sched.h>\r
 \r
 #include "palacios.h"\r
-#include "palacios-ringbuffer.h"\r
-
+#include "util-ringbuffer.h"\r
+\r
 void init_ringbuf(struct ringbuf * ring, unsigned int size) {\r
     ring->buf = kmalloc(size, GFP_KERNEL);\r
-    ring->size = size;
-  
-    ring->start = 0;
-    ring->end = 0;
-    ring->current_len = 0;
-}
+    ring->size = size;\r
+  \r
+    ring->start = 0;\r
+    ring->end = 0;\r
+    ring->current_len = 0;\r
+}\r
 \r
 struct ringbuf * create_ringbuf(unsigned int size) {\r
     struct ringbuf * ring = (struct ringbuf *)kmalloc(sizeof(struct ringbuf), GFP_KERNEL);\r
     init_ringbuf(ring, size);\r
-
-    return ring;
-}
+\r
+    return ring;\r
+}\r
 \r
 void free_ringbuf(struct ringbuf * ring) {\r
     kfree(ring->buf);\r
@@ -32,147 +32,147 @@ void free_ringbuf(struct ringbuf * ring) {
 \r
 static inline unsigned char * get_read_ptr(struct ringbuf * ring) {\r
     return (unsigned char *)(ring->buf + ring->start);\r
-}
-
+}\r
+\r
 \r
 static inline unsigned char * get_write_ptr(struct ringbuf * ring) {\r
     return (unsigned char *)(ring->buf + ring->end);\r
 }\r
 \r
 static inline int get_read_section_size(struct ringbuf * ring) {\r
-    return ring->size - ring->start;
-}
-
+    return ring->size - ring->start;\r
+}\r
+\r
 \r
 static inline int get_write_section_size(struct ringbuf * ring) {\r
-    return ring->size - ring->end;
-}
-
+    return ring->size - ring->end;\r
+}\r
+\r
 \r
 static inline int is_read_loop(struct ringbuf * ring, unsigned int len) {\r
-    if ((ring->start >= ring->end) && (ring->current_len > 0)) {
-       // end is past the end of the buffer
-       if (get_read_section_size(ring) < len) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
+    if ((ring->start >= ring->end) && (ring->current_len > 0)) {\r
+       // end is past the end of the buffer\r
+       if (get_read_section_size(ring) < len) {\r
+           return 1;\r
+       }\r
+    }\r
+    return 0;\r
+}\r
+\r
 \r
 static inline int is_write_loop(struct ringbuf * ring, unsigned int len) {\r
-    if ((ring->end >= ring->start) && (ring->current_len < ring->size)) {
-       // end is past the end of the buffer
-       if (get_write_section_size(ring) < len) {
-           return 1;
-       }
-    }
-    return 0;
-}
-
+    if ((ring->end >= ring->start) && (ring->current_len < ring->size)) {\r
+       // end is past the end of the buffer\r
+       if (get_write_section_size(ring) < len) {\r
+           return 1;\r
+       }\r
+    }\r
+    return 0;\r
+}\r
+\r
 \r
 static inline int ringbuf_avail_space(struct ringbuf * ring) {\r
-    return ring->size - ring->current_len;
-}
-
+    return ring->size - ring->current_len;\r
+}\r
+\r
 \r
 int ringbuf_data_len(struct ringbuf * ring) {\r
-    return ring->current_len;
-}
-
+    return ring->current_len;\r
+}\r
+\r
 \r
 static inline int ringbuf_capacity(struct ringbuf * ring) {\r
-    return ring->size;
-}
-
+    return ring->size;\r
+}\r
+\r
 \r
 int ringbuf_read(struct ringbuf * ring, unsigned char * dst, unsigned int len) {\r
-    int read_len = 0;
-    int ring_data_len = ring->current_len;
-
-    read_len = (len > ring_data_len) ? ring_data_len : len;
-
-    if (is_read_loop(ring, read_len)) {
-       int section_len = get_read_section_size(ring);
-
-       memcpy(dst, get_read_ptr(ring), section_len);
-       memcpy(dst + section_len, ring->buf, read_len - section_len);
-    
-       ring->start = read_len - section_len;
-    } else {
-       memcpy(dst, get_read_ptr(ring), read_len);
-    
-       ring->start += read_len;
-    }
-
-    ring->current_len -= read_len;
-
-    return read_len;
-}
-
+    int read_len = 0;\r
+    int ring_data_len = ring->current_len;\r
+\r
+    read_len = (len > ring_data_len) ? ring_data_len : len;\r
+\r
+    if (is_read_loop(ring, read_len)) {\r
+       int section_len = get_read_section_size(ring);\r
+\r
+       memcpy(dst, get_read_ptr(ring), section_len);\r
+       memcpy(dst + section_len, ring->buf, read_len - section_len);\r
+    \r
+       ring->start = read_len - section_len;\r
+    } else {\r
+       memcpy(dst, get_read_ptr(ring), read_len);\r
+    \r
+       ring->start += read_len;\r
+    }\r
+\r
+    ring->current_len -= read_len;\r
+\r
+    return read_len;\r
+}\r
+\r
 \r
 #if 0\r
 \r
 static int ringbuf_peek(struct ringbuf * ring, unsigned char * dst, unsigned int len) {\r
-    int read_len = 0;
-    int ring_data_len = ring->current_len;
-
-    read_len = (len > ring_data_len) ? ring_data_len : len;
-
-    if (is_read_loop(ring, read_len)) {
-       int section_len = get_read_section_size(ring);
-
-       memcpy(dst, get_read_ptr(ring), section_len);
-       memcpy(dst + section_len, ring->buf, read_len - section_len);
-    } else {
-       memcpy(dst, get_read_ptr(ring), read_len);
-    }
-
-    return read_len;
-}
-
+    int read_len = 0;\r
+    int ring_data_len = ring->current_len;\r
+\r
+    read_len = (len > ring_data_len) ? ring_data_len : len;\r
+\r
+    if (is_read_loop(ring, read_len)) {\r
+       int section_len = get_read_section_size(ring);\r
+\r
+       memcpy(dst, get_read_ptr(ring), section_len);\r
+       memcpy(dst + section_len, ring->buf, read_len - section_len);\r
+    } else {\r
+       memcpy(dst, get_read_ptr(ring), read_len);\r
+    }\r
+\r
+    return read_len;\r
+}\r
+\r
 \r
 static int ringbuf_delete(struct ringbuf * ring, unsigned int len) {\r
-    int del_len = 0;
-    int ring_data_len = ring->current_len;
-
-    del_len = (len > ring_data_len) ? ring_data_len : len;
-
-    if (is_read_loop(ring, del_len)) {
-       int section_len = get_read_section_size(ring);
-       ring->start = del_len - section_len;
-    } else {
-       ring->start += del_len;
-    }
-
-    ring->current_len -= del_len;
-    return del_len;
-}
+    int del_len = 0;\r
+    int ring_data_len = ring->current_len;\r
+\r
+    del_len = (len > ring_data_len) ? ring_data_len : len;\r
+\r
+    if (is_read_loop(ring, del_len)) {\r
+       int section_len = get_read_section_size(ring);\r
+       ring->start = del_len - section_len;\r
+    } else {\r
+       ring->start += del_len;\r
+    }\r
+\r
+    ring->current_len -= del_len;\r
+    return del_len;\r
+}\r
 #endif\r
 \r
 int ringbuf_write(struct ringbuf * ring, unsigned char * src, unsigned int len) {\r
-    int write_len = 0;
-    int ring_avail_space = ring->size - ring->current_len;
-  
+    int write_len = 0;\r
+    int ring_avail_space = ring->size - ring->current_len;\r
+  \r
     write_len = (len > ring_avail_space) ? ring_avail_space : len;\r
-
-    if (is_write_loop(ring, write_len)) {
-       int section_len = get_write_section_size(ring);
+\r
+    if (is_write_loop(ring, write_len)) {\r
+       int section_len = get_write_section_size(ring);\r
     \r
-       memcpy(get_write_ptr(ring), src, section_len);
-       ring->end = 0;
-
-       memcpy(get_write_ptr(ring), src + section_len, write_len - section_len);
-
-       ring->end += write_len - section_len;
+       memcpy(get_write_ptr(ring), src, section_len);\r
+       ring->end = 0;\r
+\r
+       memcpy(get_write_ptr(ring), src + section_len, write_len - section_len);\r
+\r
+       ring->end += write_len - section_len;\r
     } else {\r
-       memcpy(get_write_ptr(ring), src, write_len);
-
-       ring->end += write_len;
-    }
-
-    ring->current_len += write_len;
-
-    return write_len;
-}
+       memcpy(get_write_ptr(ring), src, write_len);\r
+\r
+       ring->end += write_len;\r
+    }\r
+\r
+    ring->current_len += write_len;\r
+\r
+    return write_len;\r
+}\r
 \r
similarity index 98%
rename from linux_module/palacios-vm.c
rename to linux_module/vm.c
index 04b338a..852733c 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/anon_inodes.h>
 #include <linux/sched.h>
 
-#include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/spinlock.h>
 #include <linux/rbtree.h>
@@ -21,7 +20,7 @@
 #include <palacios/vmm.h>
 
 #include "palacios.h"
-#include "palacios-vm.h"
+#include "vm.h"
 #include "linux-exts.h"
 
 
@@ -189,10 +188,10 @@ int start_palacios_vm(void * arg)  {
     struct v3_guest * guest = (struct v3_guest *)arg;
     int err;
 
-    lock_kernel();
+
     daemonize(guest->name);
     // allow_signal(SIGKILL);
-    unlock_kernel();
+
     
     init_vm_extensions(guest);
 
similarity index 100%
rename from linux_module/palacios-vm.h
rename to linux_module/vm.h
index 523150f..b761773 100644 (file)
@@ -2,7 +2,7 @@
 #define _V3_USER_HOST_DEV_
 
 #include <stdint.h>
-#include "palacios-host-dev-user.h"
+#include "iface-host-dev.h"
 
 int v3_user_host_dev_rendezvous(char *vmdev, char *url); // returns devfd for use in poll/select
 int v3_user_host_dev_depart(int devfd);
index ebab425..1cce578 100644 (file)
@@ -482,9 +482,7 @@ static inline int decode_cr(struct guest_info * core,
  */
 #define MASK_DISPLACEMENT(reg, mode) ({                                        \
            sint64_t val = 0;                                           \
-           if (mode == DISP0) {                                        \
-               val = reg;                                              \
-           } else if (mode == DISP8) {                                 \
+           if (mode == DISP8) {                                        \
                val = (sint8_t)(reg & 0xff);                            \
            } else if (mode == DISP16) {                                \
                val = (sint16_t)(reg & 0xffff);                         \
@@ -501,9 +499,6 @@ static inline int decode_cr(struct guest_info * core,
 #define ADDR_MASK(val, length) ({                            \
             ullong_t mask = 0x0LL;                           \
             switch (length) {                                \
-               case 1:                                       \
-                   mask = 0x0000000000000ffLL;               \
-                   break;                                    \
                 case 2:                                              \
                     mask = 0x00000000000fffffLL;             \
                     break;                                   \
index 4b30a67..9a9ee99 100644 (file)
@@ -133,7 +133,8 @@ static int handle_crystal_tics(struct pit * pit, struct channel * ch, uint_t osc
     uint_t channel_cycles = 0;
     uint_t output_changed = 0;
   
-    // PrintDebug("8254 PIT: %d crystal tics\n", oscillations);
+    //    PrintDebug("8254 PIT (channel %d): %d crystal tics\n", 
+    //        ch - pit->ch0, oscillations);
     if (ch->run_state == PENDING) {
        oscillations--;
        ch->counter = ch->reload_value;
@@ -158,6 +159,8 @@ static int handle_crystal_tics(struct pit * pit, struct channel * ch, uint_t osc
 
     if (ch->counter > oscillations) {
        ch->counter -= oscillations;
+       //PrintDebug("8254 PIT: Counter at %u after %u oscillations.\n", 
+       //   (unsigned int)ch->counter, oscillations);
        return output_changed;
     } else {
        ushort_t reload_val = ch->reload_value; 
@@ -184,23 +187,33 @@ static int handle_crystal_tics(struct pit * pit, struct channel * ch, uint_t osc
        oscillations = oscillations % reload_val;
 
        ch->counter = reload_val - oscillations;
+       //      PrintDebug("8254 PIT: Counter reset to %u.\n", 
+       //   (unsigned int)ch->counter);
+
     }
 
-    //  PrintDebug("8254 PIT: Channel Cycles: %d\n", channel_cycles);
+    //PrintDebug("8254 PIT: Channel %ld (mode = %u) Cycles: %d\n", 
+              //(ch - &pit->ch_0), ch->op_mode, channel_cycles);
   
-
-
     switch (ch->op_mode) {
        case IRQ_ON_TERM_CNT:
-           if ((channel_cycles > 0) && (ch->output_pin == 0)) {
-               ch->output_pin = 1; 
-               output_changed = 1;
+           if (channel_cycles > 0) {
+               if (ch->output_pin == 0) {
+                   ch->output_pin = 1; 
+                   output_changed = 1;
+               } else {
+                  // PrintDebug("8254: Output not changed in TERM_CNT mode.\n");
+               }
            }
            break;
        case ONE_SHOT:
-           if ((channel_cycles > 0) && (ch->output_pin == 0)) {
-               ch->output_pin = 1; 
-               output_changed = 1;
+           if (channel_cycles > 0) {
+               if ((ch->output_pin == 0)) {
+                   ch->output_pin = 1; 
+                   output_changed = 1;
+               } else {
+                   // PrintDebug("8254: Output not changed in ONE_SHOT mode.\n");
+               }
            }
            break;
        case RATE_GEN:
@@ -216,6 +229,7 @@ static int handle_crystal_tics(struct pit * pit, struct channel * ch, uint_t osc
                output_changed = 1;
            }
 
+
            break;
        case SW_STROBE:
 
@@ -300,21 +314,19 @@ static void pit_update_timer(struct guest_info * info, ullong_t cpu_cycles, ullo
        state->pit_counter = state->pit_reload - cpu_cycles;    
 
        if (oscillations) {
-           PrintDebug("8254 PIT: Handling %d crystal tics\n", oscillations);
-       }
+           //    PrintDebug("8254 PIT: Handling %d crystal tics\n", oscillations);
 
-       if (handle_crystal_tics(state, &(state->ch_0), oscillations) == 1) {
-           // raise interrupt
-           // PrintDebug("8254 PIT: Injecting Timer interrupt to guest\n");
-           v3_raise_irq(info->vm_info, 0);
-       }
+           if (handle_crystal_tics(state, &(state->ch_0), oscillations) == 1) {
+               // raise interrupt
+               PrintDebug("8254 PIT: Injecting Timer interrupt to guest (run_state = %d)\n",
+                          state->ch_0.run_state);
+               v3_raise_irq(info->vm_info, 0);
+           }
 
-       //handle_crystal_tics(state, &(state->ch_1), oscillations);
-       handle_crystal_tics(state, &(state->ch_2), oscillations);
+           //handle_crystal_tics(state, &(state->ch_1), oscillations);
+           handle_crystal_tics(state, &(state->ch_2), oscillations);
+       }
     }
-  
-
-
  
     return;
 }
@@ -431,12 +443,20 @@ static int handle_speaker_write(uint8_t *speaker, struct channel * ch, char val)
 
 static int handle_channel_cmd(struct channel * ch, struct pit_cmd_word cmd) {
 
-    ch->access_mode = cmd.access_mode;
+    if (cmd.op_mode != ch->op_mode) {
+       PrintDebug("8254 PIT: Changing channel from op mode %d to op mode %d.\n", 
+                  ch->op_mode, cmd.op_mode);
+    }
 
-    if (ch->access_mode != 0) {
-       ch->op_mode = cmd.op_mode;
+    if (cmd.access_mode != 0) {
+      ch->op_mode = cmd.op_mode;
     }
 
+    if (cmd.access_mode != ch->access_mode) {
+       PrintDebug("8254 PIT: Changing channel from access mode %d to access mode %d.\n", 
+                  ch->access_mode, cmd.access_mode);
+    }
+    ch->access_mode = cmd.access_mode;
 
     switch (cmd.access_mode) {
        case LATCH_COUNT:
index 5d6da5e..508f221 100644 (file)
@@ -1357,6 +1357,8 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
            apic->tmr_cur_cnt = op_val;
            break;
        case TMR_DIV_CFG_OFFSET:
+           PrintDebug("apic %u: core %u: setting tmr_div_cfg to 0x%x\n",
+                      apic->lapic_id.val, core->vcpu_id, op_val);
            apic->tmr_div_cfg.val = op_val;
            break;
 
@@ -1650,6 +1652,19 @@ static void apic_update_time(struct guest_info * core,
        }
     
        if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) {
+           static unsigned int nexits = 0;
+           static unsigned int missed_ints = 0;
+
+           nexits++;
+           missed_ints += tmr_ticks / apic->tmr_init_cnt;
+
+           if ((missed_ints > 0) && (nexits >= 5000)) {
+               V3_Print("apic %u: core %u: missed %u timer interrupts total in last %u exits.\n",
+                        apic->lapic_id.val, core->vcpu_id, missed_ints, nexits); 
+               missed_ints = 0;
+               nexits = 0;
+           }
+
            tmr_ticks = tmr_ticks % apic->tmr_init_cnt;
            apic->tmr_cur_cnt = apic->tmr_init_cnt - tmr_ticks;
        }
index dffbdb8..7d7b43c 100644 (file)
@@ -463,7 +463,9 @@ int v3_svm_enter(struct guest_info * info) {
     // disable global interrupts for vm state transition
     v3_clgi();
 
-    // Update timer devices prior to entering VM.
+    // Update timer devices after being in the VM, with interupts
+    // disabled, but before doing IRQ updates, so that any interrupts they 
+    //raise get seen immediately.
     v3_update_timers(info);
 
     // Synchronize the guest state to the VMCB
@@ -548,13 +550,11 @@ int v3_svm_enter(struct guest_info * info) {
     info->mem_mode = v3_get_vm_mem_mode(info);
     /* ** */
 
-
     // save exit info here
     exit_code = guest_ctrl->exit_code;
     exit_info1 = guest_ctrl->exit_info1;
     exit_info2 = guest_ctrl->exit_info2;
 
-
 #ifdef V3_CONFIG_SYMCALL
     if (info->sym_core_state.symcall_state.sym_call_active == 0) {
        update_irq_exit_state(info);
@@ -563,16 +563,12 @@ int v3_svm_enter(struct guest_info * info) {
     update_irq_exit_state(info);
 #endif
 
-
     // reenable global interrupts after vm exit
     v3_stgi();
-
  
     // Conditionally yield the CPU if the timeslice has expired
     v3_yield_cond(info);
 
-
-
     if (v3_handle_svm_exit(info, exit_code, exit_info1, exit_info2) != 0) {
        PrintError("Error in SVM exit handler\n");
        PrintError("  last exit was %d\n", v3_last_exit);
index fc6d3d5..bb4a46a 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <palacios/vmm_halt.h>
 #include <palacios/vmm_intr.h>
-
+#include <palacios/vmm_lowlevel.h> 
 
 #ifndef V3_CONFIG_DEBUG_HALT
 #undef PrintDebug
@@ -42,18 +42,25 @@ int v3_handle_halt(struct guest_info * info) {
 
        while (!v3_intr_pending(info)) {
            /* Since we're in an exit, time is already paused here, so no need to pause again. */
+         //        V3_Print("palacios: halt->yield\n");
+
            v3_yield(info);
-           v3_update_timers(info);
            
+           v3_disable_ints();
+           v3_update_timers(info);
+           v3_enable_ints();
+           
            /* At this point, we either have some combination of 
               interrupts, including perhaps a timer interrupt, or 
               no interrupt.
            */
            if (!v3_intr_pending(info)) {
                /* if no interrupt, then we do halt */
-               asm("hlt");
+               /* asm("hlt"); */
            }
        }
+
+       /* V3_Print("palacios: done with halt\n"); */
        
        info->rip += 1;
     }
index fc2e37e..781bae7 100644 (file)
@@ -104,23 +104,44 @@ int v3_offset_time( struct guest_info * info, sint64_t offset )
     return 0;
 }
 
-// Control guest time in relation to host time so that the two stay 
-// appropriately synchronized to the extent possible. 
-int v3_adjust_time(struct guest_info * info) {
+static uint64_t compute_target_host_time(struct guest_info * info)
+{
+    struct vm_time * time_state = &(info->time_state);
+    uint64_t guest_elapsed, desired_elapsed;
+    
+    guest_elapsed = (v3_get_guest_time(time_state) - time_state->initial_time);
+    desired_elapsed = (guest_elapsed * time_state->host_cpu_freq) / time_state->guest_cpu_freq;
+    return time_state->initial_time + desired_elapsed;
+}
+
+static uint64_t compute_target_guest_time(struct guest_info *info)
+{
+    struct vm_time * time_state = &(info->time_state);
+    uint64_t host_elapsed, desired_elapsed;
+
+    host_elapsed = v3_get_host_time(time_state) - time_state->initial_time;
+    desired_elapsed = (host_elapsed * time_state->guest_cpu_freq) / time_state->host_cpu_freq;
+
+    return time_state->initial_time + desired_elapsed;
+
+} 
+
+/* Yield time in the host to deal with a guest that wants to run slower than 
+ * the native host cycle frequency */
+static int yield_host_time(struct guest_info * info) {
     struct vm_time * time_state = &(info->time_state);
     uint64_t host_time, target_host_time;
-    uint64_t guest_time, target_guest_time, old_guest_time;
-    uint64_t guest_elapsed, host_elapsed, desired_elapsed;
+    uint64_t guest_time, old_guest_time;
 
     /* Compute the target host time given how much time has *already*
      * passed in the guest */
-    guest_time = v3_get_guest_time(time_state);
-    guest_elapsed = (guest_time - time_state->initial_time);
-    desired_elapsed = (guest_elapsed * time_state->host_cpu_freq) / time_state->guest_cpu_freq;
-    target_host_time = time_state->initial_time + desired_elapsed;
-
+    target_host_time = compute_target_host_time(info);
+    
     /* Now, let the host run while the guest is stopped to make the two
-     * sync up. */
+     * sync up. Note that this doesn't assume that guest time is stopped;
+     * the offsetting in the next step will change add an offset to guest
+     * time to account for the time paused even if the geust isn't 
+     * usually paused in the VMM. */
     host_time = v3_get_host_time(time_state);
     old_guest_time = v3_get_guest_time(time_state);
 
@@ -131,38 +152,60 @@ int v3_adjust_time(struct guest_info * info) {
 
     guest_time = v3_get_guest_time(time_state);
 
-    // We do *not* assume the guest timer was paused in the VM. If it was
-    // this offseting is 0. If it wasn't we need this.
+    /* We do *not* assume the guest timer was paused in the VM. If it was
+     * this offseting is 0. If it wasn't, we need this. */
     v3_offset_time(info, (sint64_t)old_guest_time - (sint64_t)guest_time);
 
+    return 0;
+}
+
+static int skew_guest_time(struct guest_info * info) {
+    struct vm_time * time_state = &(info->time_state);
+    uint64_t target_guest_time, guest_time;
     /* Now the host may have gotten ahead of the guest because
      * yielding is a coarse grained thing. Figure out what guest time
      * we want to be at, and use the use the offsetting mechanism in 
      * the VMM to make the guest run forward. We limit *how* much we skew 
      * it forward to prevent the guest time making large jumps, 
      * however. */
-    host_elapsed = host_time - time_state->initial_time;
-    desired_elapsed = (host_elapsed * time_state->guest_cpu_freq) / time_state->host_cpu_freq;
-    target_guest_time = time_state->initial_time + desired_elapsed;
+    target_guest_time = compute_target_guest_time(info);
+    guest_time = v3_get_guest_time(time_state);
 
     if (guest_time < target_guest_time) {
        uint64_t max_skew, desired_skew, skew;
 
        if (time_state->enter_time) {
-           max_skew = (time_state->exit_time - time_state->enter_time) / 10;
+           /* Limit forward skew to 10% of the amount the guest has
+            * run since we last could skew time */
+           max_skew = (guest_time - time_state->enter_time) / 10;
        } else {
            max_skew = 0;
        }
 
        desired_skew = target_guest_time - guest_time;
        skew = desired_skew > max_skew ? max_skew : desired_skew;
-/*     PrintDebug("Guest %llu cycles behind where it should be.\n",
+       PrintDebug("Guest %llu cycles behind where it should be.\n",
                   desired_skew);
        PrintDebug("Limit on forward skew is %llu. Skewing forward %llu.\n",
-                  max_skew, skew); */
+                  max_skew, skew); 
        
        v3_offset_time(info, skew);
     }
+
+    return 0;
+}
+
+// Control guest time in relation to host time so that the two stay 
+// appropriately synchronized to the extent possible. 
+int v3_adjust_time(struct guest_info * info) {
+
+    /* First deal with yielding if we want to slow down the guest */
+    yield_host_time(info);
+
+    /* Now, if the guest is too slow, (either from excess yielding above,
+     * or because the VMM is doing something that takes a long time to emulate)
+     * allow guest time to jump forward a bit */
+    skew_guest_time(info);
     
     return 0;
 }
@@ -190,11 +233,6 @@ v3_time_enter_vm( struct guest_info * info )
     time_state->enter_time = host_time;
     time_state->guest_host_offset = guest_time - host_time;
 
-    // Because we just modified the offset - shouldn't matter as this should be 
-    // the last time-related call prior to entering the VMM, but worth it 
-    // just in case.
-    time_state->exit_time = host_time; 
-
     return 0;
 }
        
@@ -232,7 +270,9 @@ void v3_update_timers(struct guest_info * info) {
 
     time_state->last_update = v3_get_guest_time(time_state);
     cycles = time_state->last_update - old_time;
+    V3_ASSERT(cycles >= 0);
 
+    //    V3_Print("Updating timers with %lld elapsed cycles.\n", cycles);
     list_for_each_entry(tmp_timer, &(time_state->timers), timer_link) {
        tmp_timer->ops->update_timer(info, cycles, time_state->guest_cpu_freq, tmp_timer->private_data);
     }
index 106239f..5963d93 100644 (file)
@@ -746,18 +746,19 @@ int v3_vmx_enter(struct guest_info * info) {
     // Perform any additional yielding needed for time adjustment
     v3_adjust_time(info);
 
-    // Update timer devices prior to entering VM.
-    v3_update_timers(info);
-
     // disable global interrupts for vm state transition
     v3_disable_ints();
 
+    // Update timer devices late after being in the VM so that as much 
+    // of hte time in the VM is accounted for as possible. Also do it before
+    // updating IRQ entry state so that any interrupts the timers raise get 
+    // handled on the next VM entry. Must be done with interrupts disabled.
+    v3_update_timers(info);
 
     if (vmcs_store() != vmx_info->vmcs_ptr_phys) {
        vmcs_load(vmx_info->vmcs_ptr_phys);
     }
 
-
     v3_vmx_restore_vmcs(info);
 
 
@@ -842,7 +843,6 @@ int v3_vmx_enter(struct guest_info * info) {
 
     exit_log[info->num_exits % 10] = exit_info;
 
-
 #ifdef V3_CONFIG_SYMCALL
     if (info->sym_core_state.symcall_state.sym_call_active == 0) {
        update_irq_exit_state(info);
index 3a1ad38..b82c905 100644 (file)
@@ -147,10 +147,9 @@ static void print_route(struct v3_vnet_route * route){
 static void dump_routes(){
     struct vnet_route_info *route;
 
-    int i = 0;
     Vnet_Debug("\n========Dump routes starts ============\n");
     list_for_each_entry(route, &(vnet_state.routes), node) {
-       Vnet_Debug("\nroute %d:\n", i++);
+       Vnet_Debug("\nroute %d:\n", route->idx);
                
        print_route(&(route->route_def));
        if (route->route_def.dst_type == LINK_INTERFACE) {
@@ -302,14 +301,20 @@ void v3_vnet_del_route(uint32_t route_idx){
     flags = vnet_lock_irqsave(vnet_state.lock);
 
     list_for_each_entry(route, &(vnet_state.routes), node) {
+       V3_Print("v3_vnet_del_route, route idx: %d\n", route->idx);
        if(route->idx == route_idx){
            list_del(&(route->node));
-           list_del(&(route->match_node));
-           Vnet_Free(route);    
+           Vnet_Free(route);
+           break;    
        }
     }
 
     vnet_unlock_irqrestore(vnet_state.lock, flags);
+    clear_hash_cache();
+
+#ifdef V3_CONFIG_DEBUG_VNET
+    dump_routes();
+#endif 
 }