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.


Basic HRT startup for HVM, plus assorted cleanup
[palacios.git] / linux_module / iface-host-dev.c
index b9d754d..9940ceb 100644 (file)
@@ -126,14 +126,14 @@ struct palacios_host_dev {
 #define DEEP_DEBUG    0
 #define SHALLOW_DEBUG 0
 
-#if DEEP_DEBUG
-#define DEEP_DEBUG_PRINT(fmt, args...) DEBUG((fmt), ##args)
+#if DEEP_DEBUG == 1
+#define DEEP_DEBUG_PRINT(fmt, args...) DEBUG(fmt, ##args)
 #else
 #define DEEP_DEBUG_PRINT(fmt, args...) 
 #endif
 
-#if SHALLOW_DEBUG
-#define SHALLOW_DEBUG_PRINT(fmt, args...) INFO((fmt), ##args)
+#if SHALLOW_DEBUG == 1
+#define SHALLOW_DEBUG_PRINT(fmt, args...) INFO(fmt, ##args)
 #else
 #define SHALLOW_DEBUG_PRINT(fmt, args...) 
 #endif
@@ -149,6 +149,7 @@ struct palacios_host_device_user {
     char     url[MAX_URL]; // what is the url describing the device
 
     v3_guest_dev_t guestdev; // what is the palacios-side device
+    v3_guest_dev_intr_t guestintr; // what is the palacios-side device interrupt info
 
     wait_queue_head_t  user_wait_queue; // user space processes waiting on us (should be only one)
     wait_queue_head_t  host_wait_queue; // host threads (should only be one) waiting on user space
@@ -434,11 +435,18 @@ static long host_dev_ioctl(struct file * fp, unsigned int val, unsigned long arg
                }
                    break;
 
-               case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_GUEST: {
+               case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_RAISE_GUEST: {
 
-                   DEEP_DEBUG_PRINT("palacios: hostdev: irq guest\n");
+                   DEEP_DEBUG_PRINT("palacios: hostdev: irq raise guest\n");
 
-                   return  v3_host_dev_raise_irq(dev, dev->guestdev, op.irq);
+                   return  v3_host_dev_raise_irq(dev, dev->guestdev, dev->guestintr, op.irq);
+               }
+                   break;
+               case PALACIOS_HOST_DEV_USER_REQUEST_IRQ_LOWER_GUEST: {
+
+                   DEEP_DEBUG_PRINT("palacios: hostdev: irq lower guest\n");
+
+                   return  v3_host_dev_lower_irq(dev, dev->guestdev, dev->guestintr, op.irq);
                }
                    break;
 
@@ -728,6 +736,7 @@ static int palacios_host_dev_rendezvous(struct palacios_host_device_user *dev)
 static v3_host_dev_t palacios_host_dev_open_deferred(char *url,
                                                     v3_bus_class_t bus,
                                                     v3_guest_dev_t gdev,
+                                                    v3_guest_dev_intr_t gintr,
                                                     void *host_priv_data)
 {
     struct v3_guest *guest= (struct v3_guest*)host_priv_data;
@@ -786,6 +795,8 @@ static v3_host_dev_t palacios_host_dev_open_deferred(char *url,
     
     dev->guestdev = gdev;
     
+    dev->guestintr = gintr;
+    
     dev->guest = guest;
 
     palacios_spinlock_init(&(dev->lock));
@@ -862,13 +873,13 @@ static uint64_t palacios_host_dev_read_io(v3_host_dev_t hostdev,
     DEEP_DEBUG_PRINT("palacios: hostdev: read io port 0x%x\n",port);
            
 
-    palacios_spinlock_lock_irqsave(&(dev->lock),f);
     
     if (palacios_host_dev_rendezvous(dev)) {
-       palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
+       //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
        return 0;
     }
+    palacios_spinlock_lock_irqsave(&(dev->lock),f);
 
     if (dev->waiting) { 
        palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
@@ -937,13 +948,13 @@ static uint64_t palacios_host_dev_read_mem(v3_host_dev_t hostdev,
 
     DEEP_DEBUG_PRINT("palacios: hostdev: read mem  0x%p\n",gpa);
 
-    palacios_spinlock_lock_irqsave(&(dev->lock),f);
     
     if (palacios_host_dev_rendezvous(dev)) {
-       palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
+       //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
        return 0;
     }
+    palacios_spinlock_lock_irqsave(&(dev->lock),f);
 
     if (dev->waiting) { 
        palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
@@ -1007,15 +1018,15 @@ static uint64_t palacios_host_dev_read_conf(v3_host_dev_t hostdev,
     unsigned long f;
     uint64_t op_len;
 
-    DEEP_DEBUG_PRINT("palacios: hostdev: read conf 0x%p\n",(void*)offset);
+    DEEP_DEBUG_PRINT("palacios: hostdev: read conf 0x%p (len=%lld)\n",(void*)offset, len);
 
-    palacios_spinlock_lock_irqsave(&(dev->lock),f);
     
     if (palacios_host_dev_rendezvous(dev)) {
-       palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
+       //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
        return 0;
     }
+    palacios_spinlock_lock_irqsave(&(dev->lock),f);
 
     if (dev->waiting) { 
        palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
@@ -1082,13 +1093,13 @@ static uint64_t palacios_host_dev_write_io(v3_host_dev_t hostdev,
 
     DEEP_DEBUG_PRINT("palacios: hostdev: write io port 0x%x \n",port);
 
-    palacios_spinlock_lock_irqsave(&(dev->lock),f);
     
     if (palacios_host_dev_rendezvous(dev)) {
-       palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
+       //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
        return 0;
     }
+    palacios_spinlock_lock_irqsave(&(dev->lock),f);
 
     if (dev->waiting) { 
        palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
@@ -1155,14 +1166,15 @@ static uint64_t palacios_host_dev_write_mem(v3_host_dev_t hostdev,
 
     DEEP_DEBUG_PRINT("palacios: hostdev: write mem 0x%p\n",gpa);
 
-    palacios_spinlock_lock_irqsave(&(dev->lock),f);
     
     if (palacios_host_dev_rendezvous(dev)) {
-       palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
+       //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
        return 0;
     }
 
+    palacios_spinlock_lock_irqsave(&(dev->lock),f);
+
     if (dev->waiting) { 
        palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: guest issued memory write request with host device \"%s\" in wrong state (waiting=%d, connected=%d)\n",dev->url,dev->waiting,dev->connected);
@@ -1230,13 +1242,13 @@ static uint64_t palacios_host_dev_write_conf(v3_host_dev_t hostdev,
 
     DEEP_DEBUG_PRINT("palacios: hostdev: write conf 0x%p\n",(void*)offset);
 
-    palacios_spinlock_lock_irqsave(&(dev->lock),f);
     
     if (palacios_host_dev_rendezvous(dev)) {
-       palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
+       //palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
        ERROR("palacios: ignoring request as user side is not connected (and did not rendezvous) for host device \"%s\"\n",dev->url);
        return 0;
     }
+    palacios_spinlock_lock_irqsave(&(dev->lock),f);
 
     if (dev->waiting) { 
        palacios_spinlock_unlock_irqrestore(&(dev->lock),f);
@@ -1323,6 +1335,11 @@ static int host_dev_init( void ) {
 }
 
 
+static int host_dev_deinit(void) { 
+    // nothing to do
+    return 0;
+}
+
 static int host_dev_guest_init(struct v3_guest * guest, void ** vm_data ) {
     struct palacios_host_dev * host_dev = palacios_alloc(sizeof(struct palacios_host_dev));
 
@@ -1347,6 +1364,7 @@ static int host_dev_guest_init(struct v3_guest * guest, void ** vm_data ) {
 static int host_dev_guest_deinit(struct v3_guest * guest, void * vm_data) {
 
     struct palacios_host_dev * host_dev = (struct palacios_host_dev *) vm_data;
+    remove_guest_ctrl(guest, V3_VM_HOST_DEV_CONNECT);
     palacios_spinlock_deinit(&(host_dev->lock));
     palacios_free(host_dev);
     return 0;
@@ -1358,7 +1376,7 @@ static int host_dev_guest_deinit(struct v3_guest * guest, void * vm_data) {
 static struct linux_ext host_dev_ext = {
     .name = "HOST_DEVICE_INTERFACE",
     .init = host_dev_init,
-    .deinit = NULL,
+    .deinit = host_dev_deinit,
     .guest_init = host_dev_guest_init,
     .guest_deinit = host_dev_guest_deinit
 };