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://palacios@newskysaw//home/palacios/palacios into devel
Jack Lange [Tue, 11 Aug 2009 21:49:11 +0000 (16:49 -0500)]
12 files changed:
palacios/include/palacios/vmcb.h
palacios/include/palacios/vmm_intr.h
palacios/src/devices/apic.c
palacios/src/devices/ide.c
palacios/src/devices/lnx_virtio_blk.c
palacios/src/devices/pci.c
palacios/src/palacios/svm.c
palacios/src/palacios/svm_halt.c
palacios/src/palacios/svm_handler.c
palacios/src/palacios/svm_io.c
palacios/src/palacios/vmm_intr.c
palacios/src/palacios/vmm_io.c

index 04dec0a..94e8d88 100644 (file)
@@ -179,8 +179,7 @@ struct Guest_Control {
     uint_t rsvd4      : 24;  // Should be 0
 } __attribute__((packed));
 
-#define SVM_INJECTION_EXTERNAL_INTR 0
-#define SVM_INJECTION_VIRTUAL_INTR  0
+#define SVM_INJECTION_IRQ  0
 #define SVM_INJECTION_NMI           2
 #define SVM_INJECTION_EXCEPTION     3
 #define SVM_INJECTION_SOFT_INTR     4
index 8dc5fd8..5f44b9e 100644 (file)
@@ -28,7 +28,7 @@
 #include <palacios/vmm_lock.h>
 
 
-typedef enum {INVALID_INTR, EXTERNAL_IRQ, NMI, SOFTWARE_INTR, VIRTUAL_INTR} intr_type_t;
+typedef enum {V3_INVALID_INTR, V3_EXTERNAL_IRQ, V3_VIRTUAL_IRQ, V3_NMI, V3_SOFTWARE_INTR} v3_intr_type_t;
 
 struct guest_info;
 struct v3_interrupt;
@@ -40,6 +40,7 @@ struct v3_irq_hook {
     void * priv_data;
 };
 
+#define MAX_IRQ 256
 
 
 
@@ -52,6 +53,8 @@ struct v3_intr_state {
     uint_t irq_started;
     uint_t irq_vector;
 
+    uint8_t virq_map[MAX_IRQ / 8];
+
     v3_lock_t irq_lock;
 
     /* some way to get the [A]PIC intr */
@@ -64,6 +67,9 @@ struct v3_intr_state {
 void v3_init_interrupt_state(struct guest_info * info);
 
 
+int v3_raise_virq(struct guest_info * info, int irq);
+int v3_lower_virq(struct guest_info * info, int irq);
+
 int v3_raise_irq(struct guest_info * info, int irq);
 int v3_lower_irq(struct guest_info * info, int irq);
 
@@ -81,11 +87,12 @@ struct intr_ctrl_ops {
 
 void v3_register_intr_controller(struct guest_info * info, struct intr_ctrl_ops * ops, void * state);
 
-int v3_intr_pending(struct guest_info * info);
-uint_t v3_get_intr_number(struct guest_info * info);
-intr_type_t v3_get_intr_type(struct guest_info * info);
+v3_intr_type_t v3_intr_pending(struct guest_info * info);
+uint32_t v3_get_intr(struct guest_info * info);
+
+//intr_type_t v3_get_intr_type(struct guest_info * info);
 
-int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type);
+int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type);
 
 /*
   int start_irq(struct vm_intr * intr);
index d4343d2..2ce9225 100644 (file)
@@ -333,7 +333,7 @@ static int apic_do_eoi(struct apic_state * apic) {
        uchar_t flag = 0x1 << minor_offset;
        uchar_t * svc_location = apic->int_svc_reg + major_offset;
        
-       PrintDebug("Received APIC EOI\n");
+       PrintDebug("Received APIC EOI for IRQ %d\n", isr_irq);
        
        *svc_location &= ~flag;
 
@@ -979,7 +979,7 @@ static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv
     }
 
     tmr_ticks = cpu_cycles >> shift_num;
-    PrintDebug("Timer Ticks: %p\n", (void *)tmr_ticks);
+    //    PrintDebug("Timer Ticks: %p\n", (void *)tmr_ticks);
 
     if (tmr_ticks < apic->tmr_cur_cnt) {
        apic->tmr_cur_cnt -= tmr_ticks;
@@ -991,6 +991,10 @@ static void apic_update_time(ullong_t cpu_cycles, ullong_t cpu_freq, void * priv
        PrintDebug("Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n", 
                   apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num);
 
+       if (apic_intr_pending(priv_data)) {
+           PrintDebug("Overriding pending IRQ %d\n", apic_get_intr_number(priv_data));
+       }
+
        if (activate_internal_irq(apic, APIC_TMR_INT) == -1) {
            PrintError("Could not raise Timer interrupt\n");
        }
@@ -1066,4 +1070,4 @@ static int apic_init(struct guest_info * vm, void * cfg_data) {
 
 
 
-device_register("LAPIC", &apic_init)
+device_register("LAPIC", apic_init)
index 60be9de..8349f70 100644 (file)
@@ -1554,7 +1554,8 @@ static int ide_init(struct guest_info * vm, void * cfg_data) {
        }
 
        bars[4].type = PCI_BAR_IO;
-       bars[4].default_base_port = PRI_DEFAULT_DMA_PORT;
+       //      bars[4].default_base_port = PRI_DEFAULT_DMA_PORT;
+       bars[4].default_base_port = -1;
        bars[4].num_ports = 16;
 
        bars[4].io_read = read_dma_port;
index 17352ac..b3ea47b 100644 (file)
 #include <palacios/vm_guest_mem.h>
 
 #include <devices/pci.h>
+#include <palacios/vmm_io.h>
 
-
+/*
 #ifndef DEBUG_VIRTIO_BLK
 #undef PrintDebug
 #define PrintDebug(fmt, args...)
 #endif
+*/
 
 #define BLK_CAPACITY_PORT     20
 #define BLK_MAX_SIZE_PORT     28
@@ -611,6 +613,8 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) {
            bars[i].type = PCI_BAR_NONE;
        }
 
+       PrintDebug("Virtio-BLK io_range_size = %d\n", virtio_state->io_range_size);
+
        bars[0].type = PCI_BAR_IO;
        bars[0].default_base_port = -1;
        bars[0].num_ports = virtio_state->io_range_size;
index ab85aea..ef4f485 100644 (file)
@@ -41,6 +41,7 @@
 #define CONFIG_ADDR_PORT    0x0cf8
 #define CONFIG_DATA_PORT    0x0cfc
 
+#define PCI_DEV_IO_PORT_BASE 0xc000
 
 #define PCI_BUS_COUNT 1
 
@@ -75,6 +76,7 @@ struct pci_bus {
     // Bitmap of the allocated device numbers
     uint8_t dev_map[MAX_BUS_DEVICES / 8];
 
+
     int (*raise_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev);
     int (*lower_pci_irq)(struct vm_device * dev, struct pci_device * pci_dev);
     struct vm_device * irq_bridge_dev;
@@ -86,6 +88,9 @@ struct pci_internal {
     // Configuration address register
     struct pci_addr_reg addr_reg;
 
+    // Base IO Port which PCI devices will register with...
+    uint16_t dev_io_base; 
+
     // Attached Busses
     struct pci_bus bus_list[PCI_BUS_COUNT];
 };
@@ -380,23 +385,36 @@ static inline int is_cfg_reg_writable(uchar_t header_type, int reg_num) {
 static int bar_update(struct pci_device * pci, int bar_num, uint32_t new_val) {
     struct v3_pci_bar * bar = &(pci->bar[bar_num]);
 
-    PrintDebug("Updating BAR Register  (Dev=%s) (bar=%d) (old_val=%x) (new_val=%x)\n", 
+    PrintError("Updating BAR Register  (Dev=%s) (bar=%d) (old_val=0x%x) (new_val=0x%x)\n", 
               pci->name, bar_num, bar->val, new_val);
 
     switch (bar->type) {
        case PCI_BAR_IO: {
            int i = 0;
 
-               PrintDebug("\tRehooking %d IO ports from base %x to %x\n",
-                          bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val));
+           PrintError("\tRehooking %d IO ports from base 0x%x to 0x%x for %d ports\n",
+                      bar->num_ports, PCI_IO_BASE(bar->val), PCI_IO_BASE(new_val),
+                      bar->num_ports);
                
            // only do this if pci device is enabled....
+           if (!(pci->config_header.status & 0x1)) {
+               PrintError("PCI Device IO space not enabled\n");
+           }
+
            for (i = 0; i < bar->num_ports; i++) {
 
+               PrintError("Rehooking PCI IO port (old port=%u) (new port=%u)\n",  
+                          PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
+
                v3_dev_unhook_io(pci->vm_dev, PCI_IO_BASE(bar->val) + i);
 
-               v3_dev_hook_io(pci->vm_dev, PCI_IO_BASE(new_val) + i, 
-                              bar->io_read, bar->io_write);
+               if (v3_dev_hook_io(pci->vm_dev, PCI_IO_BASE(new_val) + i, 
+                                  bar->io_read, bar->io_write) == -1) {
+
+                   PrintError("Could not hook PCI IO port (old port=%u) (new port=%u)\n",  
+                              PCI_IO_BASE(bar->val) + i, PCI_IO_BASE(new_val) + i);
+                   return -1;
+               }
            }
 
            bar->val = new_val;
@@ -616,6 +634,7 @@ static int pci_init(struct guest_info * vm, void * cfg_data) {
 
     
     pci_state->addr_reg.val = 0; 
+    pci_state->dev_io_base = PCI_DEV_IO_PORT_BASE;
 
     init_pci_busses(pci_state);
     
@@ -643,7 +662,12 @@ static inline int init_bars(struct pci_device * pci_dev) {
            int j = 0;
            pci_dev->bar[i].mask = (~((pci_dev->bar[i].num_ports) - 1)) | 0x01;
 
-           pci_dev->bar[i].val = pci_dev->bar[i].default_base_port & pci_dev->bar[i].mask;
+           if (pci_dev->bar[i].default_base_port != 0xffff) {
+               pci_dev->bar[i].val = pci_dev->bar[i].default_base_port & pci_dev->bar[i].mask;
+           } else {
+               pci_dev->bar[i].val = 0;
+           }
+
            pci_dev->bar[i].val |= 0x00000001;
 
            for (j = 0; j < pci_dev->bar[i].num_ports; j++) {
@@ -663,7 +687,11 @@ static inline int init_bars(struct pci_device * pci_dev) {
            pci_dev->bar[i].mask = ~((pci_dev->bar[i].num_pages << 12) - 1);
            pci_dev->bar[i].mask |= 0xf; // preserve the configuration flags
 
-           pci_dev->bar[i].val = pci_dev->bar[i].default_base_addr & pci_dev->bar[i].mask;
+           if (pci_dev->bar[i].default_base_addr != 0xffffffff) {
+               pci_dev->bar[i].val = pci_dev->bar[i].default_base_addr & pci_dev->bar[i].mask;
+           } else {
+               pci_dev->bar[i].val = 0;
+           }
 
            // hook memory
            if (pci_dev->bar[i].mem_read) {
@@ -814,7 +842,16 @@ struct pci_device * v3_pci_register_device(struct vm_device * pci,
 
        if (pci_dev->bar[i].type == PCI_BAR_IO) {
            pci_dev->bar[i].num_ports = bars[i].num_ports;
-           pci_dev->bar[i].default_base_port = bars[i].default_base_port;
+
+           // This is a horrible HACK becaues the BIOS is supposed to set the PCI base ports 
+           // And if the BIOS doesn't, Linux just happily overlaps device port assignments
+           if (bars[i].default_base_port != (uint16_t)-1) {
+               pci_dev->bar[i].default_base_port = bars[i].default_base_port;
+           } else {
+               pci_dev->bar[i].default_base_port = pci_state->dev_io_base;
+               pci_state->dev_io_base += ( 0x100 * ((bars[i].num_ports / 0x100) + 1) );
+           }
+
            pci_dev->bar[i].io_read = bars[i].io_read;
            pci_dev->bar[i].io_write = bars[i].io_write;
        } else if (pci_dev->bar[i].type == PCI_BAR_MEM32) {
index 5fadae1..d2444ac 100644 (file)
@@ -293,7 +293,6 @@ static int start_svm_guest(struct guest_info *info) {
        */
 
        // disable global interrupts for vm state transition
-
        v3_clgi();
 
 
@@ -311,6 +310,11 @@ static int start_svm_guest(struct guest_info *info) {
        // reenable global interrupts after vm exit
        v3_stgi();
 
+
+       // Conditionally yield the CPU if the timeslice has expired
+       v3_yield_cond(info);
+
+
        v3_update_time(info, tmp_tsc - info->time_state.cached_host_tsc);
        num_exits++;
        
@@ -322,10 +326,6 @@ static int start_svm_guest(struct guest_info *info) {
            }
        }
 
-     
-       // Conditionally yield the CPU if the timeslice has expired
-       v3_yield_cond(info);
-
        if (v3_handle_svm_exit(info) != 0) {
            vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data));
            addr_t host_addr;
index 16239e8..2e6f9e2 100644 (file)
@@ -30,7 +30,7 @@
 
 
 //
-// This should trigger a #GP if cpl!=0, otherwise, yield to host
+// This should trigger a #GP if cpl != 0, otherwise, yield to host
 //
 
 int v3_handle_svm_halt(struct guest_info * info) {
@@ -39,8 +39,8 @@ int v3_handle_svm_halt(struct guest_info * info) {
        v3_raise_exception(info, GPF_EXCEPTION);
     } else {
     
-       ullong_t yield_start = 0;
-       ullong_t yield_stop = 0;
+       uint64_t yield_start = 0;
+       uint64_t yield_stop = 0;
        uint32_t gap = 0;
        
        PrintDebug("CPU Yield\n");
@@ -53,7 +53,18 @@ int v3_handle_svm_halt(struct guest_info * info) {
        //v3_update_time(info, yield_stop - yield_start);
        gap = yield_stop - yield_start;
 
-       v3_raise_irq(info, 0);
+       /*  WARNING!!! WARNING!!!
+        *  
+        * DO NOT REMOVE THIS CONDITIONAL!!!
+        *
+        * It is common for an OS to issue an IO op, and then sit in a halt loop
+        * waiting for the device to complete and raise an irq.
+        * If you remove this then the timer interrupt will ALWAYS subvert the completion 
+        * interrupt and stall the guest.
+        */
+       if (!v3_intr_pending(info)) {
+           v3_raise_irq(info, 0);
+       }
 
        
        PrintDebug("CPU Yield Done (%d cycles)\n", gap);
index a981c96..f7fd96e 100644 (file)
@@ -79,7 +79,7 @@ int v3_handle_svm_exit(struct guest_info * info) {
        info->intr_state.irq_started = 1;
        info->intr_state.irq_pending = 0;
 
-       v3_injecting_intr(info, info->intr_state.irq_vector, EXTERNAL_IRQ);
+       v3_injecting_intr(info, info->intr_state.irq_vector, V3_EXTERNAL_IRQ);
     }
 
     if ((info->intr_state.irq_started == 1) && (guest_ctrl->exit_int_info.valid == 0)) {
@@ -97,42 +97,6 @@ int v3_handle_svm_exit(struct guest_info * info) {
     }
 
 
-    // Disable printing io exits due to bochs debug messages
-    //if (!((exit_code == VMEXIT_IOIO) && ((ushort_t)(guest_ctrl->exit_info1 >> 16) == 0x402))) {
-
-    if ((0) && (exit_code <= VMEXIT_EXCP14)) {
-       uchar_t instr[32];
-       int ret;
-       // Dump out the instr stream
-
-       //PrintDebug("RIP: %x\n", guest_state->rip);
-       PrintDebug("\n\n\nRIP Linear: %p\n", (void *)get_addr_linear(info, info->rip, &(info->segments.cs)));
-
-       v3_print_GPRs(info);
-       v3_print_ctrl_regs(info);
-
-
-       // OK, now we will read the instruction
-       // The only difference between PROTECTED and PROTECTED_PG is whether we read
-       // from guest_pa or guest_va
-       if (info->mem_mode == PHYSICAL_MEM) { 
-           // The real rip address is actually a combination of the rip + CS base 
-           ret = read_guest_pa_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
-       } else { 
-           ret = read_guest_va_memory(info, get_addr_linear(info, info->rip, &(info->segments.cs)), 32, instr);
-       }
-
-
-       if (ret != 32) {
-           // I think we should inject a GPF into the guest
-           PrintDebug("Could not read instruction (ret=%d)\n", ret);
-       } else {
-           PrintDebug("Instr Stream:\n");
-           PrintTraceMemDump(instr, 32);
-       }
-    }
-
-
 
     if (info->enable_profiler) {
        rdtscll(info->profiler.start_time);
@@ -362,7 +326,6 @@ int v3_handle_svm_exit(struct guest_info * info) {
     }
 
 
-
     if (v3_excp_pending(info)) {
        uint_t excp = v3_get_excp_number(info);
        
@@ -394,15 +357,11 @@ int v3_handle_svm_exit(struct guest_info * info) {
        guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
        guest_ctrl->guest_ctrl.V_INTR_PRIO = 0xf;
 
-    } else if (v3_intr_pending(info)) {
+    } else {
+       switch (v3_intr_pending(info)) {
+           case V3_EXTERNAL_IRQ: {
+               uint32_t irq = v3_get_intr(info);
 
-       switch (v3_get_intr_type(info)) {
-           case EXTERNAL_IRQ: {
-               uint_t irq = v3_get_intr_number(info);
-                   
-               // check to see if ==-1 (non exists)
-                   
-                   
                guest_ctrl->guest_ctrl.V_IRQ = 1;
                guest_ctrl->guest_ctrl.V_INTR_VECTOR = irq;
                guest_ctrl->guest_ctrl.V_IGN_TPR = 1;
@@ -416,27 +375,24 @@ int v3_handle_svm_exit(struct guest_info * info) {
 
                info->intr_state.irq_pending = 1;
                info->intr_state.irq_vector = irq;
-                   
+               
                break;
            }
-           case NMI:
+           case V3_NMI:
                guest_ctrl->EVENTINJ.type = SVM_INJECTION_NMI;
                break;
-           case SOFTWARE_INTR:
+           case V3_SOFTWARE_INTR:
                guest_ctrl->EVENTINJ.type = SVM_INJECTION_SOFT_INTR;
                break;
-           case VIRTUAL_INTR:
-               guest_ctrl->EVENTINJ.type = SVM_INJECTION_VIRTUAL_INTR;
+           case V3_VIRTUAL_IRQ:
+               guest_ctrl->EVENTINJ.type = SVM_INJECTION_IRQ;
                break;
-               
-           case INVALID_INTR: 
+
+           case V3_INVALID_INTR:
            default:
-               PrintError("Attempted to issue an invalid interrupt\n");
-               return -1;
+               break;
        }
        
-    } else {
-       //PrintDebug("Not interrupts or exceptions pending\n");
     }
 
 
index 4c85ec7..3f71bc1 100644 (file)
@@ -65,7 +65,7 @@ int v3_handle_svm_io_in(struct guest_info * info) {
     int read_size = 0;
 
     if (hook == NULL) {
-       PrintError("Hook Not present for in on port %x\n", io_info->port);
+       PrintError("Hook Not present for in on port 0x%x\n", io_info->port);
        // error, we should not have exited on this port
        return -1;
     }
@@ -83,7 +83,7 @@ int v3_handle_svm_io_in(struct guest_info * info) {
 
     if (hook->read(io_info->port, &(info->vm_regs.rax), read_size, hook->priv_data) != read_size) {
        // not sure how we handle errors.....
-       PrintError("Read Failure for in on port %x\n", io_info->port);
+       PrintError("Read Failure for in on port 0x%x\n", io_info->port);
        return -1;
     }
 
@@ -126,7 +126,7 @@ int v3_handle_svm_io_ins(struct guest_info * info) {
 
 
     if (hook == NULL) {
-       PrintError("Hook Not present for ins on port %x\n", io_info->port);
+       PrintError("Hook Not present for ins on port 0x%x\n", io_info->port);
        // error, we should not have exited on this port
        return -1;
     }
@@ -217,7 +217,7 @@ int v3_handle_svm_io_ins(struct guest_info * info) {
 
        if (hook->read(io_info->port, (char *)host_addr, read_size, hook->priv_data) != read_size) {
            // not sure how we handle errors.....
-           PrintError("Read Failure for ins on port %x\n", io_info->port);
+           PrintError("Read Failure for ins on port 0x%x\n", io_info->port);
            return -1;
        }
 
@@ -245,7 +245,7 @@ int v3_handle_svm_io_out(struct guest_info * info) {
     int write_size = 0;
 
     if (hook == NULL) {
-       PrintError("Hook Not present for out on port %x\n", io_info->port);
+       PrintError("Hook Not present for out on port 0x%x\n", io_info->port);
        // error, we should not have exited on this port
        return -1;
     }
@@ -263,7 +263,7 @@ int v3_handle_svm_io_out(struct guest_info * info) {
 
     if (hook->write(io_info->port, &(info->vm_regs.rax), write_size, hook->priv_data) != write_size) {
        // not sure how we handle errors.....
-       PrintError("Write Failure for out on port %x\n", io_info->port);
+       PrintError("Write Failure for out on port 0x%x\n", io_info->port);
        return -1;
     }
 
@@ -304,7 +304,7 @@ int v3_handle_svm_io_outs(struct guest_info * info) {
 
 
     if (hook == NULL) {
-       PrintError("Hook Not present for outs on port %x\n", io_info->port);
+       PrintError("Hook Not present for outs on port 0x%x\n", io_info->port);
        // error, we should not have exited on this port
        return -1;
     }
@@ -390,7 +390,7 @@ int v3_handle_svm_io_outs(struct guest_info * info) {
 
        if (hook->write(io_info->port, (char*)host_addr, write_size, hook->priv_data) != write_size) {
            // not sure how we handle errors.....
-           PrintError("Write Failure for outs on port %x\n", io_info->port);
+           PrintError("Write Failure for outs on port 0x%x\n", io_info->port);
            return -1;
        }
 
index b65dfef..358b307 100644 (file)
@@ -146,8 +146,25 @@ int v3_deliver_irq(struct guest_info * info, struct v3_interrupt * intr) {
 
 
 
+int v3_raise_virq(struct guest_info * info, int irq) {
+    struct v3_intr_state * intr_state = &(info->intr_state);
+    int major = irq / 8;
+    int minor = irq % 8;
+
+    intr_state->virq_map[major] |= (1 << minor);
+   
+    return 0;
+}
+
+int v3_lower_virq(struct guest_info * info, int irq) {
+    struct v3_intr_state * intr_state = &(info->intr_state);
+    int major = irq / 8;
+    int minor = irq % 8;
 
+    intr_state->virq_map[major] &= ~(1 << minor);
 
+    return 0;
+}
 
 
 int v3_lower_irq(struct guest_info * info, int irq) {
@@ -184,68 +201,95 @@ int v3_raise_irq(struct guest_info * info, int irq) {
 
 
 
-int v3_intr_pending(struct guest_info * info) {
+v3_intr_type_t v3_intr_pending(struct guest_info * info) {
     struct v3_intr_state * intr_state = &(info->intr_state);
     struct intr_controller * ctrl = NULL;
-    int ret = 0;
+    int ret = V3_INVALID_INTR;
+    int i = 0;
 
     //  PrintDebug("[intr_pending]\n");
-    addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);    
+    addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);
 
-    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-       if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
-           ret = 1;
+    // VIRQs have priority
+    for (i = 0; i < MAX_IRQ / 8; i++) {
+       if (intr_state->virq_map[i] != 0) {   
+           ret = V3_VIRTUAL_IRQ;
            break;
        }
     }
 
+    if (ret == V3_INVALID_INTR) {
+       list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+           if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
+               ret = V3_EXTERNAL_IRQ;
+               break;
+           }
+       }
+    }
+
     v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
 
     return ret;
 }
 
 
-uint_t v3_get_intr_number(struct guest_info * info) {
+uint32_t v3_get_intr(struct guest_info * info) {
     struct v3_intr_state * intr_state = &(info->intr_state);
     struct intr_controller * ctrl = NULL;
     uint_t ret = 0;
+    int i = 0;
+    int j = 0;
 
     addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);    
 
-    list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
-       if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
-           uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
-           
-           //  PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
-           ret = intr_num;
+    // virqs have priority
+    for (i = 0; i < MAX_IRQ / 8; i++) {
+       if (intr_state->virq_map[i] != 0) {
+           for (j = 0; j < 8; j++) {
+               if (intr_state->virq_map[i] & (1 << j)) {
+                   ret = (i * 8) + j;
+                   break;
+               }
+           }
            break;
        }
     }
 
-    v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
+    if (!ret) {
+       list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
+           if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data)) {
+               uint_t intr_num = ctrl->ctrl_ops->get_intr_number(ctrl->priv_data);
+               
+               //      PrintDebug("[get_intr_number] intr_number = %d\n", intr_num);
+               ret = intr_num;
+               break;
+           }
+       }
+    }
 
+    v3_unlock_irqrestore(intr_state->irq_lock, irq_state);
 
     return ret;
 }
 
-
+/*
 intr_type_t v3_get_intr_type(struct guest_info * info) {
     struct v3_intr_state * intr_state = &(info->intr_state);
     struct intr_controller * ctrl = NULL;
-    intr_type_t type = INVALID_INTR;
+    intr_type_t type = V3_INVALID_INTR;
 
     addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock);  
 
     list_for_each_entry(ctrl, &(intr_state->controller_list), ctrl_node) {
        if (ctrl->ctrl_ops->intr_pending(ctrl->priv_data) == 1) {
            //PrintDebug("[get_intr_type] External_irq\n");
-           type = EXTERNAL_IRQ;
+           type = V3_EXTERNAL_IRQ;         
            break;
        }
     }
 
 #ifdef DEBUG_INTERRUPTS
-    if (type == INVALID_INTR) {
+    if (type == V3_INVALID_INTR) {
        PrintError("[get_intr_type] Invalid_Intr\n");
     }
 #endif
@@ -254,16 +298,16 @@ intr_type_t v3_get_intr_type(struct guest_info * info) {
 
     return type;
 }
+*/
 
 
 
 
 
-
-int v3_injecting_intr(struct guest_info * info, uint_t intr_num, intr_type_t type) {
+int v3_injecting_intr(struct guest_info * info, uint_t intr_num, v3_intr_type_t type) {
     struct v3_intr_state * intr_state = &(info->intr_state);
 
-    if (type == EXTERNAL_IRQ) {
+    if (type == V3_EXTERNAL_IRQ) {
        struct intr_controller * ctrl = NULL;
 
        addr_t irq_state = v3_lock_irqsave(intr_state->irq_lock); 
index 9f44fbd..793a0f3 100644 (file)
@@ -129,16 +129,18 @@ int v3_hook_io_port(struct guest_info * info, uint_t port,
   io_hook->priv_data = priv_data;
 
   if (insert_io_hook(info, io_hook)) {
-    V3_Free(io_hook);
-    return -1;
+      PrintError("Could not insert IO hook for port %d\n", port);
+      V3_Free(io_hook);
+      return -1;
   }
 
 
   if (info->io_map.update_map(info, port, 
                              ((read == NULL) ? 0 : 1), 
                              ((write == NULL) ? 0 : 1)) == -1) {
-    V3_Free(io_hook);
-    return -1;
+      PrintError("Could not update IO map for port %d\n", port);
+      V3_Free(io_hook);
+      return -1;
   }