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.cs.northwestern.edu//home/palacios...
Peter Dinda [Tue, 5 Oct 2010 22:14:04 +0000 (17:14 -0500)]
Conflicts:

palacios/include/palacios/vm_guest.h
palacios/src/devices/apic.c
palacios/src/devices/io_apic.c
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_direct_paging_64.h
palacios/src/palacios/vmm_mem.c
utils/guest_creator/default.xml

55 files changed:
Kconfig
palacios/include/palacios/vm_guest.h
palacios/include/palacios/vmm.h
palacios/include/palacios/vmm_file.h [new file with mode: 0644]
palacios/include/palacios/vmm_mem.h
palacios/include/palacios/vmm_symspy.h
palacios/src/devices/8254.c
palacios/src/devices/8259a.c
palacios/src/devices/Kconfig
palacios/src/devices/Makefile
palacios/src/devices/apic.c
palacios/src/devices/bochs_debug.c
palacios/src/devices/cga.c
palacios/src/devices/cirrus_gfx_card.c
palacios/src/devices/curses_cons.c
palacios/src/devices/disk_model.c
palacios/src/devices/filedisk.c [new file with mode: 0644]
palacios/src/devices/generic.c
palacios/src/devices/i440fx.c
palacios/src/devices/icc_bus.c
palacios/src/devices/ide.c
palacios/src/devices/io_apic.c
palacios/src/devices/keyboard.c
palacios/src/devices/lnx_virtio_balloon.c
palacios/src/devices/lnx_virtio_blk.c
palacios/src/devices/lnx_virtio_nic.c
palacios/src/devices/lnx_virtio_sym.c
palacios/src/devices/lnx_virtio_symmod.c
palacios/src/devices/lnx_virtio_vnet.c
palacios/src/devices/netdisk.c
palacios/src/devices/nvram.c
palacios/src/devices/os_debug.c
palacios/src/devices/para_net.c
palacios/src/devices/pci.c
palacios/src/devices/pci_passthrough.c
palacios/src/devices/piix3.c
palacios/src/devices/ramdisk.c
palacios/src/devices/serial.c
palacios/src/devices/swapbypass_cache.c
palacios/src/devices/swapbypass_cache2.c
palacios/src/devices/telnet_cons.c
palacios/src/devices/tmpdisk.c
palacios/src/devices/vnet_nic.c
palacios/src/palacios/Makefile
palacios/src/palacios/mmu/vmm_shdw_pg_tlb_32.h
palacios/src/palacios/mmu/vmm_shdw_pg_tlb_64.h
palacios/src/palacios/svm_io.c
palacios/src/palacios/vmm_config.c
palacios/src/palacios/vmm_direct_paging_64.h
palacios/src/palacios/vmm_file.c [new file with mode: 0644]
palacios/src/palacios/vmm_mem.c
palacios/src/palacios/vmm_vnet.c
palacios/src/palacios/vmx_assist.c
palacios/src/palacios/vmx_ctrl_regs.c
utils/guest_creator/default.xml

diff --git a/Kconfig b/Kconfig
index 246c640..0e87296 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -21,6 +21,7 @@ config LINUX
        bool "Linux 2.6"
        select BUILT_IN_STDLIB
        select BUILT_IN_ATOI
+       select FILE
        help
          This enables the necessary options to compile Palacios with Linux 2.6
           Currently, this is in development, and only 2.6.32 is verified to work
@@ -81,6 +82,12 @@ config MAX_CPUS
          Specifies the maximum number of hardware CPUs supported by the OS
          For uniprocessor environments, set this to 1
 
+config FILE
+       bool "Host Support for file operations"
+       default n
+       help
+         Select this if your host OS supports file operatoins and you want Palacios to be able to use them.
+
 
 config CONSOLE
        bool "Host Support for VM console"
index c8bc2e0..322f390 100644 (file)
@@ -65,11 +65,21 @@ struct guest_info {
     v3_paging_mode_t shdw_pg_mode;
     struct v3_shdw_pg_state shdw_pg_state;
     addr_t direct_map_pt;
+    
+
+    union {
+       uint32_t flags;
+       struct {
+           uint8_t use_large_pages        : 1;    /* Enable virtual page tables to use large pages */
+           uint32_t rsvd                  : 31;
+       } __attribute__((packed));
+    } __attribute__((packed));
 
-    // This structure is how we get interrupts for the guest
+
+    /* This structure is how we get interrupts for the guest */
     struct v3_intr_core_state intr_core_state;
 
-    // This structure is how we get exceptions for the guest
+    /* This structure is how we get exceptions for the guest */
     struct v3_excp_state excp_state;
 
 
@@ -94,19 +104,19 @@ struct guest_info {
 #endif
 
 
-    // struct v3_core_dev_mgr core_dev_mgr;
+    /* struct v3_core_dev_mgr core_dev_mgr; */
 
     void * decoder_state;
 
 #ifdef CONFIG_SYMBIOTIC
-    // Symbiotic state
+    /* Symbiotic state */
     struct v3_sym_core_state sym_core_state;
 #endif
 
 
     struct v3_vm_info * vm_info;
 
-    // the logical cpu on which this core runs
+    /* the logical cpu on which this core runs */
     uint32_t cpu_id;
 };
 
@@ -116,7 +126,8 @@ struct guest_info {
 struct v3_vm_info {
     v3_vm_class_t vm_class;
 
-    addr_t mem_size; // In bytes for now
+    addr_t mem_size; /* In bytes for now */
+    uint32_t mem_align;
     struct v3_mem_map mem_map;
 
     v3_paging_size_t paging_size; // for nested paging
@@ -133,7 +144,8 @@ struct v3_vm_info {
 
 
     struct v3_intr_routers intr_routers;
-    // device_map
+
+    /* device_map */
     struct vmm_dev_mgr  dev_mgr;
 
     struct v3_host_events host_event_hooks;
@@ -143,7 +155,7 @@ struct v3_vm_info {
     v3_vm_operating_mode_t run_state;
 
 #ifdef CONFIG_SYMBIOTIC
-    // Symbiotic state
+    /* Symbiotic state */
     struct v3_sym_vm_state sym_vm_state;
 #endif
 
@@ -184,6 +196,6 @@ void v3_print_GPRs(struct guest_info * info);
 
 void v3_print_stack(struct guest_info * info);
 
-#endif // ! __V3VEE__
+#endif /* ! __V3VEE__ */
 
 #endif
index f37ad83..7a466a9 100644 (file)
@@ -261,7 +261,6 @@ struct v3_os_hooks {
     void *(*vaddr_to_paddr)(void *addr);
 
     int (*hook_interrupt)(struct v3_vm_info * vm, unsigned int irq);
-
     int (*ack_irq)(int irq);
 
     unsigned int (*get_cpu_khz)(void);
@@ -301,8 +300,9 @@ struct v3_interrupt {
 void Init_V3(struct v3_os_hooks * hooks,  int num_cpus);
 
 
-int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask);
 struct v3_vm_info * v3_create_vm(void * cfg);
+int v3_start_vm(struct v3_vm_info * vm, unsigned int cpu_mask);
+
 
 int v3_deliver_irq(struct v3_vm_info * vm, struct v3_interrupt * intr);
 
diff --git a/palacios/include/palacios/vmm_file.h b/palacios/include/palacios/vmm_file.h
new file mode 100644 (file)
index 0000000..20718c3
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * 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) 2010, Peter Dinda (pdinda@cs.northwestern.edu> 
+ * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@cs.northwestern.edu>
+ *
+ * This is free software.  You are permitted to use,
+ * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
+ */
+
+
+#ifndef __VMM_FILE_H__
+#define __VMM_FILE_H__
+
+#include <palacios/vmm.h>
+
+
+#ifdef __V3VEE__
+
+#define V3_FileOpen(path, mode)                                                \
+    ({                                                                 \
+       extern struct v3_file_hooks *file_hooks;                                \
+       ((file_hooks) && (file_hooks)->file_open) ?                             \
+           (file_hooks)->file_open((path), (mode)) : -1 ;              \
+    })
+
+#define V3_FileClose(fd)                                               \
+    ({                                                                 \
+       extern struct v3_file_hooks *file_hooks;                                \
+       ((file_hooks) && (file_hooks)->file_close) ?                            \
+           (file_hooks)->file_close((fd))  :  -1 ;     \
+    })
+
+#define V3_FileSize(fd)                                                \
+    ({                                                                 \
+       extern struct v3_file_hooks *file_hooks;                                \
+       ((file_hooks) && (file_hooks)->file_size) ?                             \
+           (file_hooks)->file_size((fd))  : -1 ;       \
+    })
+
+#define V3_FileRead(fd,start,buf,len)                                  \
+    ({                                                                 \
+       extern struct v3_file_hooks *file_hooks;                                \
+       ((file_hooks) && (file_hooks)->file_read) ?                             \
+           (file_hooks)->file_read((fd),(start),(buf),(len)) : -1 ;  \
+    })
+
+#define V3_FileWrite(fd,start,buf,len)                                 \
+    ({                                                                 \
+       extern struct v3_file_hooks *file_hooks;                                \
+       ((file_hooks) && (file_hooks)->file_write) ?                            \
+           (file_hooks)->file_write((fd),(start),(buf),(len)) : -1 ;  \
+    })
+
+
+#endif
+
+#define FILE_OPEN_MODE_READ    (1 << 0)
+#define FILE_OPEN_MODE_WRITE   (1 << 1)
+
+struct v3_file_hooks {
+
+    int (*file_open)(const char *path, int mode);
+    int (*file_close)(int fd);
+
+    long long (*file_size)(int fd);
+
+    // blocking reads and writes
+    long long  (*file_read)(int fd,  long long start, void *buffer, long long length);
+    long long  (*file_write)(int fd, long long start, void *buffer, long long length);
+
+};
+
+
+extern void V3_Init_File(struct v3_file_hooks * hooks);
+
+#endif
index a8e776a..32d6ae6 100644 (file)
@@ -109,8 +109,8 @@ struct v3_mem_region * v3_get_next_mem_region(struct v3_vm_info * vm, uint16_t c
 
 void v3_print_mem_map(struct v3_vm_info * vm);
 
-
-
+uint32_t v3_get_max_page_size(struct guest_info * core, addr_t fault_addr, uint32_t req_size);
+uint32_t v3_compute_page_alignment(addr_t addr);
 
 
 #endif // ! __V3VEE__
index b2def67..50209ac 100644 (file)
@@ -34,6 +34,7 @@ struct v3_symspy_global_page {
        struct {
            uint8_t pci_map_valid      : 1;
            uint8_t symmod_enabled     : 1;
+           uint8_t sec_symmod_enabled : 1;
        } __attribute__((packed));
     } __attribute__((packed));
     
index a7c7398..51c3f04 100644 (file)
 #define CHANNEL1_PORT 0x41
 #define CHANNEL2_PORT 0x42
 #define COMMAND_PORT 0x43
+#define SPEAKER_PORT 0x61
 
 
 #define PIT_INTR_NUM 0
+#define PIT_SPEAKER_GATE 0x01
 
 /* The order of these typedefs is important because the numerical values correspond to the 
  * values coming from the io ports
@@ -88,6 +90,7 @@ struct pit {
     struct channel ch_0;
     struct channel ch_1;
     struct channel ch_2;
+    uint8_t speaker;
 };
 
 
@@ -301,7 +304,7 @@ static void pit_update_time(struct guest_info * info, ullong_t cpu_cycles, ullon
        }
 
        //handle_crystal_tics(dev, &(state->ch_1), oscillations);
-       //handle_crystal_tics(dev, &(state->ch_2), oscillations);
+       handle_crystal_tics(dev, &(state->ch_2), oscillations);
     }
   
 
@@ -413,9 +416,20 @@ static int handle_channel_read(struct channel * ch, char * val) {
 
 }
 
+static int handle_speaker_read(uint8_t *speaker, struct channel * ch, char * val) {
+    *val = *speaker;
 
+    if ((*speaker & PIT_SPEAKER_GATE)) {
+       *val |= (ch->output_pin << 5);
+    }
+    
+    return 0;
+}
 
-
+static int handle_speaker_write(uint8_t *speaker, struct channel * ch, char val) {
+    *speaker = (val & ~0x20);
+    return 0;
+}
 
 static int handle_channel_cmd(struct channel * ch, struct pit_cmd_word cmd) {
     ch->op_mode = cmd.op_mode;
@@ -499,6 +513,12 @@ static int pit_read_channel(struct guest_info * core, ushort_t port, void * dst,
                return -1;
            }
            break;
+       case SPEAKER_PORT:
+           if (handle_speaker_read(&state->speaker, &(state->ch_2), val) == -1) {
+               PrintError("SPEAKER read error\n");
+               return -1;
+           }
+           break;
        default:
            PrintError("8254 PIT: Read from invalid port (%d)\n", port);
            return -1;
@@ -540,6 +560,12 @@ static int pit_write_channel(struct guest_info * core, ushort_t port, void * src
                return -1;
            }
            break;
+       case SPEAKER_PORT:
+           if (handle_speaker_write(&state->speaker, &(state->ch_2), val) == -1) {
+               PrintError("SPEAKER write error\n");
+               return -1;
+           }
+           break;
        default:
            PrintError("8254 PIT: Write to invalid port (%d)\n", port);
            return -1;
@@ -643,7 +669,7 @@ static struct v3_device_ops dev_ops = {
 static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pit * pit_state = NULL;
     struct vm_device * dev = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
     
     // PIT is only usable in non-multicore environments
     // just hardcode the core context
@@ -654,11 +680,12 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     pit_state = (struct pit *)V3_Malloc(sizeof(struct pit));
     V3_ASSERT(pit_state != NULL);
+    pit_state->speaker = 0;
 
-    dev = v3_allocate_device(name, &dev_ops, pit_state);
+    dev = v3_allocate_device(dev_id, &dev_ops, pit_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
@@ -666,6 +693,7 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     v3_dev_hook_io(dev, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel);
     v3_dev_hook_io(dev, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel);
     v3_dev_hook_io(dev, COMMAND_PORT, NULL, &pit_write_command);
+    v3_dev_hook_io(dev, SPEAKER_PORT, &pit_read_channel, &pit_write_channel);
 
 #ifdef CONFIG_DEBUG_PIT
     PrintDebug("8254 PIT: OSC_HZ=%d, reload_val=", OSC_HZ);
index 498ab76..c13292e 100644 (file)
@@ -746,7 +746,7 @@ static struct v3_device_ops dev_ops = {
 static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pic_internal * state = NULL;
     state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     // PIC is only usable in non-multicore environments
     // just hardcode the core context
@@ -754,10 +754,10 @@ static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     V3_ASSERT(state != NULL);
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 9a07e71..7bcc256 100644 (file)
@@ -3,7 +3,7 @@ menu "Virtual Devices"
 config APIC
        bool "APIC" 
        default y
-       depends on ICC_BUS
+       depends on ICC_BUS && EXPERIMENTAL
        help 
          Includes the Virtual APIC device
 
@@ -19,7 +19,7 @@ config DEBUG_APIC
 
 config IO_APIC
        bool "IOAPIC"
-       depends on ICC_BUS
+       depends on ICC_BUS && EXPERIMENTAL
        default y
        help 
          Includes the Virtual IO APIC
@@ -35,6 +35,7 @@ config DEBUG_IO_APIC
 config ICC_BUS
        bool "ICC BUS"
        default y
+       depends on EXPERIMENTAL
        help 
          The ICC Bus for APIC/IOAPIC communication
 
@@ -271,6 +272,13 @@ config DEBUG_PIT
        help 
          Enable debugging for the PIT  
 
+config FILEDISK
+       bool "FILEDISK storage backend"
+       default y
+       depends on FILE && (IDE || LINUX_VIRTIO_BLOCK)
+       help
+         Includes the file based disk backend
+
 
 config NETDISK
        bool "NETDISK storage backend"
index 18d0159..817645d 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_NE2K) += ne2k.o
 obj-$(CONFIG_TMPDISK) += tmpdisk.o
 obj-$(CONFIG_RAMDISK) += ramdisk.o 
 obj-$(CONFIG_NETDISK) += netdisk.o 
+obj-$(CONFIG_FILEDISK) += filedisk.o
 
 obj-$(CONFIG_CGA) += cga.o
 obj-$(CONFIG_TELNET_CONSOLE) += telnet_cons.o
index a0d17df..f7cf5e6 100644 (file)
@@ -43,7 +43,7 @@ typedef enum { APIC_TMR_INT, APIC_THERM_INT, APIC_PERF_INT,
 #define APIC_EXTINT_DELIVERY 0x7
 
 
-#define BASE_ADDR_MSR 0x0000001B
+#define BASE_ADDR_MSR     0x0000001B
 #define DEFAULT_BASE_ADDR 0xfee00000
 
 #define APIC_ID_OFFSET                    0x020
@@ -124,12 +124,12 @@ struct apic_msr {
     union {
        uint64_t value;
        struct {
-           uchar_t rsvd;
-           uint_t bootstrap_cpu : 1;
-           uint_t rsvd2         : 2;
-           uint_t apic_enable   : 1;
-           ullong_t base_addr   : 40;
-           uint_t rsvd3         : 12;
+           uint8_t rsvd;
+           uint8_t bootstrap_cpu : 1;
+           uint8_t rsvd2         : 2;
+           uint8_t apic_enable   : 1;
+           uint64_t base_addr   : 40;
+           uint32_t rsvd3         : 12;
        } __attribute__((packed));
     } __attribute__((packed));
 } __attribute__((packed));
@@ -176,10 +176,10 @@ struct apic_state {
     uint32_t rem_rd_data;
 
 
-    uchar_t int_req_reg[32];
-    uchar_t int_svc_reg[32];
-    uchar_t int_en_reg[32];
-    uchar_t trig_mode_reg[32];
+    uint8_t int_req_reg[32];
+    uint8_t int_svc_reg[32];
+    uint8_t int_en_reg[32];
+    uint8_t trig_mode_reg[32];
   
     uint32_t eoi;
 
@@ -197,7 +197,8 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
 
 static void init_apic_state(struct apic_state * apic, uint32_t id, struct vm_device * icc) {
     apic->base_addr = DEFAULT_BASE_ADDR;
-    if (id==0) { 
+
+    if (id == 0) { 
        // boot processor, enabled
        apic->base_addr_msr.value = 0x0000000000000900LL;
     } else {
@@ -261,7 +262,7 @@ static int read_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t * dst, v
     struct apic_state * apics = (struct apic_state *)(dev->private_data);
     struct apic_state * apic = &(apics[core->cpu_id]);
 
-    PrintDebug("apic %u: core %u: MSR read\n",apic->lapic_id.val,core->cpu_id);
+    PrintDebug("apic %u: core %u: MSR read\n", apic->lapic_id.val, core->cpu_id);
     v3_lock(apic->lock);
     dst->value = apic->base_addr;
     v3_unlock(apic->lock);
@@ -280,7 +281,8 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo
 
     if (old_reg == NULL) {
        // uh oh...
-       PrintError("apic %u: core %u: APIC Base address region does not exit...\n",apic->lapic_id.val,core->cpu_id);
+       PrintError("apic %u: core %u: APIC Base address region does not exit...\n",
+                  apic->lapic_id.val, core->cpu_id);
        return -1;
     }
     
@@ -291,7 +293,8 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo
     apic->base_addr = src.value;
 
     if (v3_hook_full_mem(dev->vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, dev) == -1) {
-       PrintError("apic %u: core %u: Could not hook new APIC Base address\n",apic->lapic_id.val,core->cpu_id);
+       PrintError("apic %u: core %u: Could not hook new APIC Base address\n",
+                  apic->lapic_id.val, core->cpu_id);
        v3_unlock(apic->lock);
        return -1;
     }
@@ -305,22 +308,19 @@ static int write_apic_msr(struct guest_info * core, uint_t msr, v3_msr_t src, vo
 static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) {
     int major_offset = (irq_num & ~0x00000007) >> 3;
     int minor_offset = irq_num & 0x00000007;
-    uchar_t * req_location = apic->int_req_reg + major_offset;
-    uchar_t * en_location = apic->int_en_reg + major_offset;
-    uchar_t flag = 0x1 << minor_offset;
+    uint8_t * req_location = apic->int_req_reg + major_offset;
+    uint8_t * en_location = apic->int_en_reg + major_offset;
+    uint8_t flag = 0x1 << minor_offset;
 
 
-#if 1
 
     if (irq_num <= 15) {
-       PrintError("apic %u: core ?: Attempting to raise an invalid interrupt: %d\n", apic->lapic_id.val,irq_num);
+//     PrintError("apic %u: core ?: Attempting to raise an invalid interrupt: %d\n", apic->lapic_id.val,irq_num);
        return -1;
     }
 
-#endif
-
 
-    PrintDebug("apic %u: core ?: Raising APIC IRQ %d\n", apic->lapic_id.val,irq_num);
+    PrintDebug("apic %u: core ?: Raising APIC IRQ %d\n", apic->lapic_id.val, irq_num);
 
     if (*req_location & flag) {
        //V3_Print("Interrupts coallescing\n");
@@ -329,7 +329,8 @@ static int activate_apic_irq(struct apic_state * apic, uint32_t irq_num) {
     if (*en_location & flag) {
        *req_location |= flag;
     } else {
-       PrintDebug("apic %u: core ?: Interrupt  not enabled... %.2x\n", apic->lapic_id.val, *en_location);
+       PrintDebug("apic %u: core ?: Interrupt  not enabled... %.2x\n", 
+                  apic->lapic_id.val, *en_location);
        return 0;
     }
 
@@ -343,11 +344,11 @@ static int get_highest_isr(struct apic_state * apic) {
 
     // We iterate backwards to find the highest priority
     for (i = 31; i >= 0; i--) {
-       uchar_t  * svc_major = apic->int_svc_reg + i;
+       uint8_t  * svc_major = apic->int_svc_reg + i;
     
        if ((*svc_major) & 0xff) {
            for (j = 7; j >= 0; j--) {
-               uchar_t flag = 0x1 << j;
+               uint8_t flag = 0x1 << j;
                if ((*svc_major) & flag) {
                    return ((i * 8) + j);
                }
@@ -365,11 +366,11 @@ static int get_highest_irr(struct apic_state * apic) {
 
     // We iterate backwards to find the highest priority
     for (i = 31; i >= 0; i--) {
-       uchar_t  * req_major = apic->int_req_reg + i;
+       uint8_t  * req_major = apic->int_req_reg + i;
     
        if ((*req_major) & 0xff) {
            for (j = 7; j >= 0; j--) {
-               uchar_t flag = 0x1 << j;
+               uint8_t flag = 0x1 << j;
                if ((*req_major) & flag) {
                    return ((i * 8) + j);
                }
@@ -389,8 +390,8 @@ static int apic_do_eoi(struct apic_state * apic) {
     if (isr_irq != -1) {
        int major_offset = (isr_irq & ~0x00000007) >> 3;
        int minor_offset = isr_irq & 0x00000007;
-       uchar_t flag = 0x1 << minor_offset;
-       uchar_t * svc_location = apic->int_svc_reg + major_offset;
+       uint8_t flag = 0x1 << minor_offset;
+       uint8_t * svc_location = apic->int_svc_reg + major_offset;
        
        PrintDebug("apic %u: core ?: Received APIC EOI for IRQ %d\n", apic->lapic_id.val,isr_irq);
        
@@ -400,7 +401,7 @@ static int apic_do_eoi(struct apic_state * apic) {
        
        if ((isr_irq == 238) || 
            (isr_irq == 239)) {
-           PrintError("apic %u: core ?: Acking IRQ %d\n", apic->lapic_id.val,isr_irq);
+           PrintDebug("apic %u: core ?: Acking IRQ %d\n", apic->lapic_id.val,isr_irq);
        }
        
        if (isr_irq == 238) {
@@ -453,13 +454,13 @@ static int activate_internal_irq(struct apic_state * apic, apic_irq_type_t int_t
            masked = apic->err_vec_tbl.mask;
            break;
        default:
-           PrintError("apic %u: core ?: Invalid APIC interrupt type\n",apic->lapic_id.val);
+           PrintError("apic %u: core ?: Invalid APIC interrupt type\n", apic->lapic_id.val);
            return -1;
     }
 
     // interrupt is masked, don't send
     if (masked == 1) {
-       PrintDebug("apic %u: core ?: Inerrupt is masked\n",apic->lapic_id.val);
+       PrintDebug("apic %u: core ?: Inerrupt is masked\n", apic->lapic_id.val);
        return 0;
     }
 
@@ -467,7 +468,7 @@ static int activate_internal_irq(struct apic_state * apic, apic_irq_type_t int_t
        //PrintDebug("Activating internal APIC IRQ %d\n", vec_num);
        return activate_apic_irq(apic, vec_num);
     } else {
-       PrintError("apic %u: core ?: Unhandled Delivery Mode\n",apic->lapic_id.val);
+       PrintError("apic %u: core ?: Unhandled Delivery Mode\n", apic->lapic_id.val);
        return -1;
     }
 }
@@ -480,10 +481,12 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui
     uint32_t val = 0;
 
 
-    PrintDebug("apic %u: core %u: at %p: Read apic address space (%p)\n",apic->lapic_id.val,core->cpu_id, apic, (void *)guest_addr);
+    PrintDebug("apic %u: core %u: at %p: Read apic address space (%p)\n",
+              apic->lapic_id.val, core->cpu_id, apic, (void *)guest_addr);
 
     if (msr->apic_enable == 0) {
-       PrintError("apic %u: core %u: Read from APIC address space with disabled APIC, apic msr=0x%llx\n",apic->lapic_id.val,core->cpu_id,apic->base_addr_msr.value);
+       PrintError("apic %u: core %u: Read from APIC address space with disabled APIC, apic msr=0x%llx\n",
+                  apic->lapic_id.val, core->cpu_id, apic->base_addr_msr.value);
 
        return -1;
     }
@@ -696,9 +699,9 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui
        case SEOI_OFFSET:
 
        default:
-           PrintError("apic %u: core %u: Read from Unhandled APIC Register: %x (getting zero)\n", apic->lapic_id.val,core->cpu_id, (uint32_t)reg_addr);
-           //      return -1;
-           val=0;
+           PrintError("apic %u: core %u: Read from Unhandled APIC Register: %x (getting zero)\n", 
+                      apic->lapic_id.val, core->cpu_id, (uint32_t)reg_addr);
+           return -1;
     }
 
 
@@ -719,11 +722,13 @@ static int apic_read(struct guest_info * core, addr_t guest_addr, void * dst, ui
        *val_ptr = val;
 
     } else {
-       PrintError("apic %u: core %u: Invalid apic read length (%d)\n", apic->lapic_id.val,core->cpu_id, length);
+       PrintError("apic %u: core %u: Invalid apic read length (%d)\n", 
+                  apic->lapic_id.val, core->cpu_id, length);
        return -1;
     }
 
-    PrintDebug("apic %u: core %u: Read finished (val=%x)\n", apic->lapic_id.val,core->cpu_id, *(uint32_t *)dst);
+    PrintDebug("apic %u: core %u: Read finished (val=%x)\n", 
+              apic->lapic_id.val, core->cpu_id, *(uint32_t *)dst);
 
     return length;
 }
@@ -738,18 +743,22 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
     struct apic_msr * msr = (struct apic_msr *)&(apic->base_addr_msr.value);
     uint32_t op_val = *(uint32_t *)src;
 
-    PrintDebug("apic %u: core %u: at %p and priv_data is at %p: Write to address space (%p) (val=%x)\n", 
-              apic->lapic_id.val, core->cpu_id, apic,priv_data,
+    PrintDebug("apic %u: core %u: at %p and priv_data is at %p\n",
+              apic->lapic_id.val, core->cpu_id, apic, priv_data);
+
+    PrintDebug("Write to address space (%p) (val=%x)\n", 
               (void *)guest_addr, *(uint32_t *)src);
 
     if (msr->apic_enable == 0) {
-       PrintError("apic %u: core %u: Write to APIC address space with disabled APIC, apic msr=0x%llx\n",apic->lapic_id.val,core->cpu_id,apic->base_addr_msr.value);
+       PrintError("apic %u: core %u: Write to APIC address space with disabled APIC, apic msr=0x%llx\n",
+                  apic->lapic_id.val, core->cpu_id, apic->base_addr_msr.value);
        return -1;
     }
 
 
     if (length != 4) {
-       PrintError("apic %u: core %u: Invalid apic write length (%d)\n", apic->lapic_id.val, length,core->cpu_id);
+       PrintError("apic %u: core %u: Invalid apic write length (%d)\n", 
+                  apic->lapic_id.val, length, core->cpu_id);
        return -1;
     }
 
@@ -783,17 +792,18 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
        case TRIG_OFFSET7:
        case PPR_OFFSET:
        case EXT_APIC_FEATURE_OFFSET:
-#if 1
-           PrintError("apic %u: core %u: Attempting to write to read only register %p (ignored)\n", apic->lapic_id.val,core->cpu_id, (void *)reg_addr);
-#else   
-           PrintError("apic %u: core %u: Attempting to write to read only register %p (error)\n", apic->lapic_id.val,core->cpu_id, (void *)reg_addr);
+
+           PrintError("apic %u: core %u: Attempting to write to read only register %p (error)\n", 
+                      apic->lapic_id.val, core->cpu_id, (void *)reg_addr);
            return -1;
-#endif
+
            break;
 
            // Data registers
        case APIC_ID_OFFSET:
-           PrintDebug("apic %u: core %u: my id is being changed to %u\n",apic->lapic_id.val,core->cpu_id,op_val);
+           PrintDebug("apic %u: core %u: my id is being changed to %u\n", 
+                      apic->lapic_id.val, core->cpu_id, op_val);
+
            apic->lapic_id.val = op_val;
            break;
        case TPR_OFFSET:
@@ -889,26 +899,32 @@ static int apic_write(struct guest_info * core, addr_t guest_addr, void * src, u
 
        case INT_CMD_LO_OFFSET:
            apic->int_cmd.lo = op_val;
+
            // ICC???
-           PrintDebug("apic %u: core %u: sending cmd 0x%llx to apic %u\n",apic->lapic_id.val,core->cpu_id,
+           PrintDebug("apic %u: core %u: sending cmd 0x%llx to apic %u\n", 
+                      apic->clapic_id.val, core->cpu_id,
                       apic->int_cmd.val, apic->int_cmd.dst);
            if (v3_icc_send_ipi(apic->icc_bus, apic->lapic_id.val, apic->int_cmd.val,apic->dst_fmt.val,0)==-1) { 
                return -1;
            }
            break;
+
        case INT_CMD_HI_OFFSET:
            apic->int_cmd.hi = op_val;
            break;
-           // Unhandled Registers
 
+
+       // Unhandled Registers
        case EXT_APIC_CMD_OFFSET:
        case SEOI_OFFSET:
        default:
-           PrintError("apic %u: core %u: Write to Unhandled APIC Register: %x (ignored)\n", apic->lapic_id.val,core->cpu_id, (uint32_t)reg_addr);
-           //      return -1;
+           PrintError("apic %u: core %u: Write to Unhandled APIC Register: %x (ignored)\n", 
+                      apic->lapic_id.val, core->cpu_id, (uint32_t)reg_addr);
+
+           return -1;
     }
 
-    PrintDebug("apic %u: core %u: Write finished\n",apic->lapic_id.val,core->cpu_id);
+    PrintDebug("apic %u: core %u: Write finished\n", apic->lapic_id.val, core->cpu_id);
 
     return length;
 }
@@ -960,9 +976,9 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq
     struct apic_state * apic = (struct apic_state *)private_data;
     int major_offset = (irq & ~0x00000007) >> 3;
     int minor_offset = irq & 0x00000007;
-    uchar_t * req_location = apic->int_req_reg + major_offset;
-    uchar_t * svc_location = apic->int_svc_reg + major_offset;
-    uchar_t flag = 0x01 << minor_offset;
+    uint8_t * req_location = apic->int_req_reg + major_offset;
+    uint8_t * svc_location = apic->int_svc_reg + major_offset;
+    uint8_t flag = 0x01 << minor_offset;
 
     if (*req_location & flag) {
        // we will only pay attention to a begin irq if we
@@ -972,11 +988,9 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq
     } else {
        // do nothing... 
        PrintDebug("apic %u: core %u: begin irq for %d ignored since I don't own it\n",
-                  apic->lapic_id.val,info->cpu_id,irq);
+                  apic->lapic_id.val, info->cpu_id, irq);
     }
 
-
-
     return 0;
 }
 
@@ -984,7 +998,9 @@ static int apic_begin_irq(struct guest_info * info, void * private_data, int irq
 
 
 /* Timer Functions */
-static void apic_update_time(struct guest_info * info, ullong_t cpu_cycles, ullong_t cpu_freq, void * priv_data) {
+static void apic_update_time(struct guest_info * info, 
+                            uint64_t cpu_cycles, uint64_t cpu_freq, 
+                            void * priv_data) {
     struct apic_state * apic = (struct apic_state *)(priv_data);
     // The 32 bit GCC runtime is a pile of shit
 #ifdef __V3_64BIT__
@@ -993,7 +1009,7 @@ static void apic_update_time(struct guest_info * info, ullong_t cpu_cycles, ullo
     uint32_t tmr_ticks = 0;
 #endif
 
-    uchar_t tmr_div = *(uchar_t *)&(apic->tmr_div_cfg.val);
+    uint8_t tmr_div = *(uint8_t *)&(apic->tmr_div_cfg.val);
     uint_t shift_num = 0;
 
 
@@ -1034,7 +1050,8 @@ static void apic_update_time(struct guest_info * info, ullong_t cpu_cycles, ullo
            shift_num = 7;
            break;
        default:
-           PrintError("apic %u: core %u: Invalid Timer Divider configuration\n",apic->lapic_id.val,info->cpu_id);
+           PrintError("apic %u: core %u: Invalid Timer Divider configuration\n",
+                      apic->lapic_id.val, info->cpu_id);
            return;
     }
 
@@ -1048,15 +1065,19 @@ static void apic_update_time(struct guest_info * info, ullong_t cpu_cycles, ullo
        apic->tmr_cur_cnt = 0;
 
        // raise irq
-       PrintDebug("apic %u: core %u: Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n", apic->lapic_id.val,info->cpu_id,
+       PrintDebug("apic %u: core %u: Raising APIC Timer interrupt (periodic=%d) (icnt=%d) (div=%d)\n",
+                  apic->lapic_id.val, info->cpu_id,
                   apic->tmr_vec_tbl.tmr_mode, apic->tmr_init_cnt, shift_num);
 
        if (apic_intr_pending(info, priv_data)) {
-           PrintDebug("apic %u: core %u: Overriding pending IRQ %d\n", apic->lapic_id.val,info->cpu_id, apic_get_intr_number(info, priv_data));
+           PrintDebug("apic %u: core %u: Overriding pending IRQ %d\n", 
+                      apic->lapic_id.val, info->cpu_id, 
+                      apic_get_intr_number(info, priv_data));
        }
 
        if (activate_internal_irq(apic, APIC_TMR_INT) == -1) {
-           PrintError("apic %u: core %u: Could not raise Timer interrupt\n",apic->lapic_id.val,info->cpu_id);
+           PrintError("apic %u: core %u: Could not raise Timer interrupt\n",
+                      apic->lapic_id.val, info->cpu_id);
        }
     
        if (apic->tmr_vec_tbl.tmr_mode == APIC_TMR_PERIODIC) {
@@ -1139,13 +1160,13 @@ static struct v3_icc_ops icc_ops = {
 
 static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("apic: creating an APIC for each core\n");
-    char * name = v3_cfg_val(cfg, "name");
-    char * icc_name = v3_cfg_val(cfg,"bus");
-    struct vm_device * icc = v3_find_dev(vm, icc_name);
+    char * dev_id = v3_cfg_val(cfg, "ID");
+    char * icc_bus_id = v3_cfg_val(cfg, "bus");
+    struct vm_device * icc = v3_find_dev(vm, icc_bus_id);
     int i;
 
     if (!icc) {
-        PrintError("apic: Cannot find ICC Bus (%s)\n", icc_name);
+        PrintError("apic: Cannot find ICC Bus (%s)\n", icc_bus_id);
         return -1;
     }
 
@@ -1154,10 +1175,10 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     // 0..num_cores-1   at num_cores is the ioapic (one only)
     struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state) * vm->num_cores);
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, apic);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, apic);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("apic: Could not attach device %s\n", name);
+       PrintError("apic: Could not attach device %s\n", dev_id);
        return -1;
     }
 
@@ -1175,14 +1196,15 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
        v3_icc_register_apic(core, icc, i, &icc_ops, &(apic[i]));
 
-       PrintDebug("apic %u: (setup device): done, my id is %u\n",i,apic[i].lapic_id.val);
+       PrintDebug("apic %u: (setup device): done, my id is %u\n", i, apic[i].lapic_id.val);
 
     }
 
-    for (i=0;i<vm->num_cores;i++) {
+    for (i = 0; i < vm->num_cores; i++) {
        PrintDebug("apic: sanity check: apic %u (at %p) has id %u and msr value %llx\n",
                   i, &(apic[i]), apic[i].lapic_id.val, apic[i].base_addr_msr.value);
     }
+
     PrintDebug("apic: priv_data is at %p\n", apic);
 
     v3_hook_msr(vm, BASE_ADDR_MSR, read_apic_msr, write_apic_msr, dev);
index cced2eb..a240988 100644 (file)
@@ -136,17 +136,17 @@ static struct v3_device_ops dev_ops = {
 
 static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct debug_state * state = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
 
     V3_ASSERT(state != NULL);
 
     PrintDebug("Creating Bochs Debug Device\n");
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 6c82c58..ec75d53 100644 (file)
@@ -115,7 +115,7 @@ static void passthrough_out(uint16_t port, void * src, uint_t length) {
     }
 }
 
-static int video_write_mem(addr_t guest_addr, void * dest, uint_t length, void * priv_data) {
+static int video_write_mem(struct guest_info * core, addr_t guest_addr, void * dest, uint_t length, void * priv_data) {
     struct vm_device * dev = (struct vm_device *)priv_data;
     struct video_internal * state = (struct video_internal *)dev->private_data;
     uint_t fb_offset = guest_addr - START_ADDR;
@@ -148,7 +148,7 @@ static int video_write_mem(addr_t guest_addr, void * dest, uint_t length, void *
     return length;
 }
 
-static int video_read_port(uint16_t port, void * dest, uint_t length, struct vm_device * dev) {
+static int video_read_port(struct guest_info * core, uint16_t port, void * dest, uint_t length, struct vm_device * dev) {
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
 
 
@@ -163,7 +163,7 @@ static int video_read_port(uint16_t port, void * dest, uint_t length, struct vm_
 
 
 
-static int video_write_port(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
+static int video_write_port(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) {
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
 
 
@@ -178,7 +178,7 @@ static int video_write_port(uint16_t port, void * src, uint_t length, struct vm_
 
 
 
-static int crtc_data_write(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
+static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) {
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
     uint8_t val = *(uint8_t *)src;
     uint_t index = video_state->crtc_index_reg;
@@ -257,7 +257,7 @@ static int crtc_data_write(uint16_t port, void * src, uint_t length, struct vm_d
 }
 
 
-static int crtc_index_write(uint16_t port, void * src, uint_t length, struct vm_device * dev) {
+static int crtc_index_write(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) {
     struct video_internal * video_state = (struct video_internal *)dev->private_data;
     
     if (length > 2) {
@@ -276,7 +276,7 @@ static int crtc_index_write(uint16_t port, void * src, uint_t length, struct vm_
     }
 
     if (length == 2) {
-       if (crtc_data_write(port + 1, src + 1, length - 1, dev) != (length - 1)) {
+       if (crtc_data_write(core, port + 1, src + 1, length - 1, dev) != (length - 1)) {
            PrintError("could not handle implicit crtc data write\n");
            return -1;
        }
@@ -302,7 +302,7 @@ int v3_cons_get_fb(struct vm_device * frontend_dev, uint8_t * dst, uint_t offset
 
 
 static int free_device(struct vm_device * dev) {
-    v3_unhook_mem(dev->vm, START_ADDR);
+    v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR);
     return 0;
 }
 
@@ -315,20 +315,20 @@ static struct v3_device_ops dev_ops = {
     .stop = NULL,
 };
 
-static int cga_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
     addr_t frame_buf_pa = 0;
     int enable_passthrough = 0;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     enable_passthrough = (strcasecmp(v3_cfg_val(cfg, "passthrough"), "enable") == 0) ? 1 : 0;
 
     PrintDebug("video: init_device\n");
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, video_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
@@ -347,11 +347,11 @@ static int cga_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     if (enable_passthrough) {
        PrintDebug("Enabling CGA Passthrough\n");
 
-       if (v3_hook_write_mem(vm, START_ADDR, END_ADDR, START_ADDR, &video_write_mem, dev) == -1) {
+       if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, START_ADDR, &video_write_mem, dev) == -1) {
            PrintDebug("\n\nVideo Hook failed.\n\n");
        }
     } else {
-       if (v3_hook_write_mem(vm, START_ADDR, END_ADDR, frame_buf_pa, &video_write_mem, dev) == -1) {
+       if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, frame_buf_pa, &video_write_mem, dev) == -1) {
            PrintDebug("\n\nVideo Hook failed.\n\n");
        }
     }
index 25bf720..d3b09c3 100644 (file)
@@ -423,12 +423,12 @@ static struct v3_device_ops dev_ops = {
 static int cirrus_gfx_card_init(struct guest_info * vm, v3_cfg_tree_t * cfg){
     struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal));
     struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data);
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
-    struct vm_device * dev = v3_allocate_device("TEXT_GFX_CARD", &dev_ops, video_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", "TEXT_GFX_CARD");
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index b18b9d9..b30ee02 100644 (file)
@@ -170,28 +170,25 @@ static struct v3_device_ops dev_ops = {
     .stop = NULL,
 };
 
-static int cons_init(struct guest_info * vm, v3_cfg_tree_t * cfg) 
+static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) 
 {
-       struct cons_state * state;
-       v3_cfg_tree_t * frontend_cfg;
-       const char *frontend_tag;
-       struct vm_device * frontend;
-       char *name, *ttypath;
+       struct cons_state * state = NULL;
+       v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+       const char * frontend_tag = v3_cfg_val(frontend_cfg, "tag");
+       struct vm_device * frontend = v3_find_dev(vm, frontend_tag);
+       char * dev_id = v3_cfg_val(cfg, "ID");
+       char * ttypath = v3_cfg_val(cfg, "tty");
 
        /* read configuration */
-       frontend_cfg = v3_cfg_subtree(cfg, "frontend");
        V3_ASSERT(frontend_cfg);
-       frontend_tag = v3_cfg_val(frontend_cfg, "tag");
        V3_ASSERT(frontend_tag);
-       frontend = v3_find_dev(vm, frontend_tag);
        V3_ASSERT(frontend);
-       name = v3_cfg_val(cfg, "name");
+
 
        /* allocate state */
-       state = (struct cons_state *) V3_Malloc(sizeof(struct cons_state));
+       state = (struct cons_state *)V3_Malloc(sizeof(struct cons_state));
        V3_ASSERT(state);
        state->frontend_dev = frontend;
-       ttypath = v3_cfg_val(cfg, "tty");
        V3_ASSERT(ttypath);
 
        /* open tty for screen display */
@@ -203,12 +200,12 @@ static int cons_init(struct guest_info * vm, v3_cfg_tree_t * cfg)
        }
 
        /* allocate device */
-       struct vm_device *dev = v3_allocate_device(name, &dev_ops, state);
+       struct vm_device *dev = v3_allocate_device(dev_id, &dev_ops, state);
        V3_ASSERT(dev);
 
        /* attach device to virtual machine */
        if (v3_attach_device(vm, dev) == -1) {
-               PrintError("Could not attach device %s\n", name);
+               PrintError("Could not attach device %s\n", dev_id);
                V3_Free(state);
                return -1;
        }
index 0eec5bf..4bc4433 100644 (file)
@@ -107,17 +107,17 @@ static int connect_fn(struct v3_vm_info * vm,
 
 static int model_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, NULL);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, NULL);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
-    if (v3_dev_add_blk_frontend(vm, name, connect_fn, NULL) == -1) {
-       PrintError("Could not register %s as block frontend\n", name);
+    if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, NULL) == -1) {
+       PrintError("Could not register %s as block frontend\n", dev_id);
        return -1;
     }
 
diff --git a/palacios/src/devices/filedisk.c b/palacios/src/devices/filedisk.c
new file mode 100644 (file)
index 0000000..6e9e5d7
--- /dev/null
@@ -0,0 +1,134 @@
+/* 
+ * 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) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
+ * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Jack Lange <jarusl@cs.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_dev_mgr.h>
+
+#include <palacios/vmm_file.h>
+
+#ifndef CONFIG_DEBUG_FILEDISK
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
+struct disk_state {
+    uint64_t capacity; // in bytes
+
+    int fd;
+};
+
+
+static int read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
+
+    PrintDebug("Reading %d bytes from %p to %p\n", (uint32_t)num_bytes, (uint8_t *)(disk->disk_image + lba), buf);
+
+    V3_FileRead(disk->fd, lba, buf, num_bytes);
+
+    return 0;
+}
+
+
+static int write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
+
+    PrintDebug("Writing %d bytes from %p to %p\n", (uint32_t)num_bytes,  buf, (uint8_t *)(disk->disk_image + lba));
+
+    V3_FileWrite(disk->fd, lba, buf, num_bytes);
+
+    return 0;
+}
+
+
+static uint64_t get_capacity(void * private_data) {
+    struct disk_state * disk = (struct disk_state *)private_data;
+
+    PrintDebug("Querying RAMDISK capacity %d\n", 
+              (uint32_t)(disk->capacity));
+
+    return disk->capacity;
+}
+
+static struct v3_dev_blk_ops blk_ops = {
+    .read = read, 
+    .write = write,
+    .get_capacity = get_capacity,
+};
+
+
+
+
+static int disk_free(struct vm_device * dev) {
+    return 0;
+}
+
+static struct v3_device_ops dev_ops = {
+    .free = disk_free,
+    .reset = NULL,
+    .start = NULL,
+    .stop = NULL,
+};
+
+
+
+
+static int disk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+    struct disk_state * disk = NULL;
+    char * path = v3_cfg_val(cfg, "path");
+    char * dev_id = v3_cfg_val(cfg, "ID");
+    char * filename = v3_cfg_val(cfg, "file");
+
+
+    v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+
+    disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state));
+    memset(disk, 0, sizeof(struct disk_state));
+
+
+    if (!path) {
+       PrintError("Missing path (%s) for %s\n", path, dev_id);
+       return -1;
+    }
+    
+    disk->fd = V3_FileOpen(path, 0);
+    disk->capacity = V3_FileSize(disk->fd);
+
+    PrintDebug("Registering RAMDISK at %p (size=%d)\n", 
+              (void *)file->data, (uint32_t)file->size);
+
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk);
+
+    if (v3_attach_device(vm, dev) == -1) {
+       PrintError("Could not attach device %s\n", dev_id);
+       return -1;
+    }
+
+    if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
+                          &blk_ops, frontend_cfg, disk) == -1) {
+       PrintError("Could not connect %s to frontend %s\n", 
+                  dev_id, v3_cfg_val(frontend_cfg, "tag"));
+       return -1;
+    }
+    
+
+    return 0;
+}
+
+
+device_register("FILEDISK", disk_init)
index b30098f..924de7c 100644 (file)
@@ -254,7 +254,7 @@ static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, gene
 
 static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct generic_internal * state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     v3_cfg_tree_t * port_cfg = v3_cfg_subtree(cfg, "ports");
 
@@ -263,10 +263,10 @@ static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     state->num_port_ranges = 0;
 
     
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 618a8ca..ddd169c 100644 (file)
@@ -63,7 +63,7 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     int i;
     struct i440_state * state = NULL;
     struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     if (!pci) {
        PrintError("could not find PCI Device\n");
@@ -74,10 +74,10 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     state->pci = pci;
        
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 3606be1..c78190b 100644 (file)
@@ -173,17 +173,17 @@ static int deliver(uint32_t src_apic, struct apic_data *dest_apic, struct int_cm
            // So the selector needs to be VV00
            // and the base needs to be VV000
            //
-           core->rip=0;
-           core->segments.cs.selector = icr->vec<<8;
-           core->segments.cs.limit= 0xffff;
-           core->segments.cs.base = icr->vec<<12;
+           core->rip = 0;
+           core->segments.cs.selector = icr->vec << 8;
+           core->segments.cs.limit = 0xffff;
+           core->segments.cs.base = icr->vec << 12;
 
            PrintDebug("icc_bus: SIPI delivery (0x%x -> 0x%x:0x0) to core %u\n",
                       icr->vec, core->segments.cs.selector, core->cpu_id);
            // Maybe need to adjust the APIC?
            
            // We transition the target core to SIPI state
-           core->cpu_mode=REAL;  // note: locking should not be needed here
+           core->cpu_mode = REAL;  // note: locking should not be needed here
 
            // As with INIT, we should not need to do anything else
 
@@ -404,15 +404,15 @@ int v3_icc_register_ioapic(struct v3_vm_info *vm, struct vm_device * icc_bus, ui
 static int icc_bus_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("icc_bus: Creating ICC_BUS\n");
 
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     struct icc_bus_state * icc_bus = (struct icc_bus_state *)V3_Malloc(sizeof(struct icc_bus_state));
     memset(icc_bus, 0, sizeof(struct icc_bus_state));
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, icc_bus);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, icc_bus);
 
     if (v3_attach_device(vm, dev) == -1) {
-        PrintError("icc_bus: Could not attach device %s\n", name);
+        PrintError("icc_bus: Could not attach device %s\n", dev_id);
         return -1;
     }
 
index 67a8928..a31aec2 100644 (file)
@@ -1521,7 +1521,7 @@ static int connect_fn(struct v3_vm_info * vm,
 
 static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct ide_internal * ide  = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal));  
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("IDE: Initializing IDE\n");
     memset(ide, 0, sizeof(struct ide_internal));
@@ -1542,10 +1542,10 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     PrintDebug("IDE: Creating IDE bus x 2\n");
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, ide);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ide);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
@@ -1660,8 +1660,8 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     }
 
-    if (v3_dev_add_blk_frontend(vm, name, connect_fn, (void *)ide) == -1) {
-       PrintError("Could not register %s as frontend\n", name);
+    if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)ide) == -1) {
+       PrintError("Could not register %s as frontend\n", dev_id);
        return -1;
     }
     
@@ -1694,6 +1694,3 @@ int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_n
 
     return 0;
 }
-
-
-
index dbbab94..00587ef 100644 (file)
@@ -146,7 +146,7 @@ static void init_ioapic_state(struct io_apic_state * ioapic, uint32_t id) {
     ioapic->base_addr = IO_APIC_BASE_ADDR;
     ioapic->index_reg = 0;
 
-    ioapic->ioapic_id.val = id;
+    ioapic->ioapic_id.id = id;
     ioapic->ioapic_ver.val = 0x00170011;
     ioapic->ioapic_arb_id.val = 0x00000000;
 
@@ -168,7 +168,7 @@ static int ioapic_read(struct guest_info * core, addr_t guest_addr, void * dst,
     uint32_t reg_tgt = guest_addr - ioapic->base_addr;
     uint32_t * op_val = (uint32_t *)dst;
 
-    PrintDebug("ioapic %u: IOAPIC Read at %p\n", ioapic->ioapic_id.val, (void *)guest_addr);
+    PrintDebug("ioapic %u: IOAPIC Read at %p\n", ioapic->ioapic_id.id, (void *)guest_addr);
 
     if (reg_tgt == 0x00) {
        *op_val = ioapic->index_reg;
@@ -184,25 +184,25 @@ static int ioapic_read(struct guest_info * core, addr_t guest_addr, void * dst,
            case IOAPIC_ARB_REG:
                *op_val = ioapic->ioapic_arb_id.val;
                break;
-           default:
-               {
-                   uint_t redir_index = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) >> 1;
-                   uint_t hi_val = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) % 1;
-
-                   if (redir_index > 0x3f) {
-                       PrintError("ioapic %u: Invalid redirection table entry %x\n", ioapic->ioapic_id.val, (uint32_t)redir_index);
-                       return -1;
-                   }
-                   if (hi_val) {
-                       *op_val = ioapic->redir_tbl[redir_index].hi;
-                   } else {
-                       *op_val = ioapic->redir_tbl[redir_index].lo;
-                   }
+           default: {
+               uint_t redir_index = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) >> 1;
+               uint_t hi_val = (ioapic->index_reg - IOAPIC_REDIR_BASE_REG) % 1;
+               
+               if (redir_index > 0x3f) {
+                   PrintError("ioapic %u: Invalid redirection table entry %x\n", ioapic->ioapic_id.id, (uint32_t)redir_index);
+                   return -1;
+               }
+               
+               if (hi_val) {
+                   *op_val = ioapic->redir_tbl[redir_index].hi;
+               } else {
+                   *op_val = ioapic->redir_tbl[redir_index].lo;
                }
+           }
        }
     }
 
-    PrintDebug("ioapic %u: IOAPIC Read at %p gave value 0x%x\n", ioapic->ioapic_id.val, (void *)guest_addr, *op_val);
+    PrintDebug("ioapic %u: IOAPIC Read at %p gave value 0x%x\n", ioapic->ioapic_id.id, (void *)guest_addr, *op_val);
 
     return length;
 }
@@ -214,7 +214,7 @@ static int ioapic_write(struct guest_info * core, addr_t guest_addr, void * src,
     uint32_t reg_tgt = guest_addr - ioapic->base_addr;
     uint32_t op_val = *(uint32_t *)src;
 
-    PrintDebug("ioapic %u: IOAPIC Write at %p (val = %d)\n",  ioapic->ioapic_id.val, (void *)guest_addr, *(uint32_t *)src);
+    PrintDebug("ioapic %u: IOAPIC Write at %p (val = %d)\n",  ioapic->ioapic_id.id, (void *)guest_addr, *(uint32_t *)src);
 
     if (reg_tgt == 0x00) {
        ioapic->index_reg = op_val;
@@ -222,11 +222,12 @@ static int ioapic_write(struct guest_info * core, addr_t guest_addr, void * src,
        // IOWIN register
        switch (ioapic->index_reg) {
            case IOAPIC_ID_REG:
+               // What does this do to our relationship with the ICC bus?
                ioapic->ioapic_id.val = op_val;
                break;
            case IOAPIC_VER_REG:
                // GPF/PageFault/Ignore?
-               PrintError("ioapic %u: Writing to read only IOAPIC register\n", ioapic->ioapic_id.val);
+               PrintError("ioapic %u: Writing to read only IOAPIC register\n", ioapic->ioapic_id.id);
                return -1;
            case IOAPIC_ARB_REG:
                ioapic->ioapic_arb_id.val = op_val;
@@ -240,14 +241,14 @@ static int ioapic_write(struct guest_info * core, addr_t guest_addr, void * src,
 
 
                    if (redir_index > 0x3f) {
-                       PrintError("ioapic %u: Invalid redirection table entry %x\n", ioapic->ioapic_id.val, (uint32_t)redir_index);
+                       PrintError("ioapic %u: Invalid redirection table entry %x\n", ioapic->ioapic_id.id, (uint32_t)redir_index);
                        return -1;
                    }
                    if (hi_val) {
                        PrintDebug("ioapic %u: Writing to hi of pin %d\n", ioapic->ioapic_id.val, redir_index);
                        ioapic->redir_tbl[redir_index].hi = op_val;
                    } else {
-                       PrintDebug("ioapic %u: Writing to lo of pin %d\n", ioapic->ioapic_id.val, redir_index);
+                       PrintDebug("ioapic %u: Writing to lo of pin %d\n", ioapic->ioapic_id.id, redir_index);
                        op_val &= REDIR_LO_MASK;
                        ioapic->redir_tbl[redir_index].lo &= ~REDIR_LO_MASK;
                        ioapic->redir_tbl[redir_index].lo |= op_val;
@@ -266,7 +267,7 @@ static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq
     struct redir_tbl_entry * irq_entry = NULL;
 
     if (irq > 24) {
-       PrintDebug("ioapic %u: IRQ out of range of IO APIC\n", ioapic->ioapic_id.val);
+       PrintDebug("ioapic %u: IRQ out of range of IO APIC\n", ioapic->ioapic_id.id);
        return -1;
     }
 
@@ -274,7 +275,7 @@ static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq
 
     if (irq_entry->mask == 0) {
 
-       PrintDebug("ioapic %u: IOAPIC Signalling APIC to raise INTR %d\n", ioapic->ioapic_id.val, irq_entry->vec);
+       PrintDebug("ioapic %u: IOAPIC Signalling APIC to raise INTR %d\n", ioapic->ioapic_id.id, irq_entry->vec);
 
 
        // the format of the redirection table entry is just slightly 
@@ -293,7 +294,9 @@ static int ioapic_raise_irq(struct v3_vm_info * vm, void * private_data, int irq
 
        // Note: 0 yhere is "cluster model", but it should be irrelevant
        // since we are sending this as a physical destination
-       v3_icc_send_ipi(ioapic->icc_bus, ioapic->ioapic_id.val,icr.val, 0, irq);
+       PrintDebug("io apic %u: raising irq %u on ICC bus.\n",
+                  ioapic->ioapic_id.id, irq);
+       v3_icc_send_ipi(ioapic->icc_bus, ioapic->ioapic_id.id,icr.val, 0, irq);
     }
 
     return 0;
@@ -330,7 +333,7 @@ static struct v3_device_ops dev_ops = {
 
 static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * icc_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     if (!icc_bus) {
        PrintError("ioapic: Could not locate ICC BUS device (%s)\n", v3_cfg_val(cfg, "bus"));
@@ -343,11 +346,11 @@ static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     ioapic->icc_bus = icc_bus;
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, ioapic);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ioapic);
 
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("ioapic: Could not attach device %s\n", name);
+       PrintError("ioapic: Could not attach device %s\n", dev_id);
        return -1;
     }
 
@@ -356,7 +359,7 @@ static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     init_ioapic_state(ioapic,vm->num_cores);
 
-    v3_icc_register_ioapic(vm,icc_bus,ioapic->ioapic_id.val);
+    v3_icc_register_ioapic(vm,icc_bus,ioapic->ioapic_id.id);
 
     v3_hook_full_mem(vm, V3_MEM_CORE_ANY, ioapic->base_addr, ioapic->base_addr + PAGE_SIZE_4KB, 
                     ioapic_read, ioapic_write, dev);
index 2935c43..375a625 100644 (file)
@@ -1015,7 +1015,7 @@ static struct v3_device_ops dev_ops = {
 
 static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct keyboard_internal * keyboard_state = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("keyboard: init_device\n");
 
@@ -1031,10 +1031,10 @@ static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     keyboard_state->mouse_enabled = 0;
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, keyboard_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, keyboard_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 2e2cee1..de25807 100644 (file)
@@ -418,7 +418,7 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_balloon_state * virtio_state = NULL;
     struct pci_device * pci_dev = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("Initializing VIRTIO Balloon device\n");
 
@@ -432,9 +432,9 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     memset(virtio_state, 0, sizeof(struct virtio_balloon_state));
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 5651b7e..ffb8c24 100644 (file)
@@ -606,7 +606,7 @@ static int connect_fn(struct v3_vm_info * vm,
 static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_dev_state * virtio_state = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("Initializing VIRTIO Block device\n");
 
@@ -623,14 +623,14 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     virtio_state->pci_bus = pci_bus;
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
-    if (v3_dev_add_blk_frontend(vm, name, connect_fn, (void *)virtio_state) == -1) {
-       PrintError("Could not register %s as block frontend\n", name);
+    if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) {
+       PrintError("Could not register %s as block frontend\n", dev_id);
        return -1;
     }
 
index 8721962..8993066 100644 (file)
@@ -686,9 +686,9 @@ static int connect_fn(struct v3_vm_info * info,
 static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_dev_state * virtio_state = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
-    PrintDebug("Virtio NIC: Initializing VIRTIO Network device: %s\n", name);
+    PrintDebug("Virtio NIC: Initializing VIRTIO Network device: %s\n", dev_id);
 
     if (pci_bus == NULL) {
        PrintError("Virtio NIC: VirtIO devices require a PCI Bus");
@@ -702,14 +702,14 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     virtio_state->pci_bus = pci_bus;
     virtio_state->vm = vm;
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Virtio NIC: Could not attach device %s\n", name);
+       PrintError("Virtio NIC: Could not attach device %s\n", dev_id);
        return -1;
     }
 
-    if (v3_dev_add_net_frontend(vm, name, connect_fn, (void *)virtio_state) == -1) {
-       PrintError("Virtio NIC: Could not register %s as net frontend\n", name);
+    if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) {
+       PrintError("Virtio NIC: Could not register %s as net frontend\n", dev_id);
        return -1;
     }
        
index 0acd87f..6bd3ff4 100644 (file)
@@ -354,7 +354,7 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_sym_state * virtio_state = NULL;
     struct pci_device * pci_dev = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("Initializing VIRTIO Symbiotic device\n");
 
@@ -368,9 +368,9 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     memset(virtio_state, 0, sizeof(struct virtio_sym_state));
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 3a27ca4..4e55c79 100644 (file)
@@ -607,7 +607,7 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct virtio_sym_state * virtio_state = NULL;
     struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state);
     struct pci_device * pci_dev = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("SYMMOD: Initializing VIRTIO Symbiotic Module device\n");
 
@@ -625,10 +625,10 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 215e664..4569bc7 100644 (file)
@@ -63,7 +63,13 @@ struct virtio_vnet_state {
     int io_range_size;
     v3_lock_t lock;
 
-    ulong_t pkt_sent, pkt_recv, pkt_drop, tx_exit, rx_exit, total_exit;
+    uint32_t pkt_sent;
+    uint32_t pkt_recv;
+    uint32_t pkt_drop;
+    uint32_t tx_exit;
+    uint32_t rx_exit;
+    uint32_t total_exit;
+
     int ready;
 };
 
@@ -143,7 +149,8 @@ static int handle_cmd_kick(struct guest_info * core, struct virtio_vnet_state *
        uint8_t status = 0;
 
 
-       PrintDebug("VNET Bridge: CMD: Descriptor Count=%d, index=%d, desc_idx=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
+       PrintDebug("VNET Bridge: CMD: Descriptor Count=%d, index=%d, desc_idx=%d\n", 
+                  desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
 
        if (desc_cnt < 3) {
            PrintError("VNET Bridge cmd must include at least 3 descriptors (cnt=%d)\n", desc_cnt);
@@ -228,23 +235,25 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pk
     int ret_val = -1;
     unsigned long flags;
     uint16_t sent;
-    struct v3_vnet_pkt *pkt;
+    struct v3_vnet_pkt * pkt = NULL;
 
-    if(pkt_num <= 0)
+    if (pkt_num <= 0) {
        return 0;
+    }
 
     flags = v3_lock_irqsave(vnet_state->lock);
        
     if (q->ring_avail_addr == 0) {
        PrintError("Queue is not set\n");
-       goto exit;
+       v3_unlock_irqrestore(vnet_state->lock, flags);
+       return ret_val;
     }
 
     PrintDebug("VNET Bridge: RX: running on cpu: %d, num of pkts: %d\n", V3_Get_CPU(), pkt_num);
 
-    for(sent = 0; sent < pkt_num; sent ++) {
+    for (sent = 0; sent < pkt_num; sent++) {
        pkt = &vnet_pkts[sent];
-       vnet_state->pkt_recv ++;
+       vnet_state->pkt_recv++;
 
        if (q->cur_avail_idx != q->avail->index) {
            uint16_t pkt_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
@@ -256,7 +265,8 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pk
 
            if (v3_gpa_to_hva(&(vm->cores[0]), pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
                PrintError("Could not translate buffer address\n");
-               goto exit;
+               v3_unlock_irqrestore(vnet_state->lock, flags);
+               return ret_val;
            }
 
            PrintDebug("VNET Bridge: RX: pkt sent to guest pkt size: %d, dst link: %d\n", pkt->size, pkt->dst_id);
@@ -272,13 +282,14 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pk
            q->used->index++;
            q->cur_avail_idx++;
        } else {
-           vnet_state->pkt_drop ++;
+           vnet_state->pkt_drop++;
            v3_vnet_disable_bridge();
        }
     }
 
-    if(sent == 0){
-       goto exit;
+    if (sent == 0) {
+       v3_unlock_irqrestore(vnet_state->lock, flags);
+       return ret_val;
     }
 
     if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
@@ -293,37 +304,37 @@ static int vnet_pkt_input_cb(struct v3_vm_info * vm,  struct v3_vnet_pkt vnet_pk
 #ifdef CONFIG_VNET_PROFILE
     if (vnet_state->pkt_recv % 200000 == 0)
        PrintError("Vnet Bridge: sent: %ld, rxed: %ld, dropped: %ld, total exit: %ld, tx exit: %ld, rx exit: %ld\n",
-                       vnet_state->pkt_sent,
-                       vnet_state->pkt_recv,
-                       vnet_state->pkt_drop, 
-                       vnet_state->total_exit,
-                       vnet_state->tx_exit,
-                       vnet_state->rx_exit);
+                  vnet_state->pkt_sent,
+                  vnet_state->pkt_recv,
+                  vnet_state->pkt_drop, 
+                  vnet_state->total_exit,
+                  vnet_state->tx_exit,
+                  vnet_state->rx_exit);
 #endif
 
-exit:
-
     v3_unlock_irqrestore(vnet_state->lock, flags);
+
     return ret_val;
+
 }
 
-static void vnet_pkt_input_xcall(void *data){
-    struct v3_vnet_bridge_input_args *args = (struct v3_vnet_bridge_input_args *)data;
+static void vnet_pkt_input_xcall(void * data) {
+    struct v3_vnet_bridge_input_args * args = (struct v3_vnet_bridge_input_args *)data;
        
     vnet_pkt_input_cb(args->vm, args->vnet_pkts, args->pkt_num, args->private_data);
 }
 
-static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) 
-{
+static int handle_pkt_kick(struct guest_info * core, struct virtio_vnet_state * vnet_state) {
     struct virtio_queue * q = &(vnet_state->queue[XMIT_QUEUE]);
     unsigned long flags = 0;
     int recvd = 0;
-       
+    int cpu = V3_Get_CPU();
+
     flags = v3_lock_irqsave(vnet_state->lock);
 
     if (q->ring_avail_addr == 0) {
-       goto exit;
+       v3_unlock_irqrestore(vnet_state->lock,flags);
+       return 0;
     }
 
     while (q->cur_avail_idx != q->avail->index) {
@@ -348,60 +359,62 @@ static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * v
        q->used->ring[q->used->index % q->queue_size].length = pkt_desc->length; // What do we set this to????
        q->used->index++;
 
-       vnet_state->pkt_sent ++;
-       recvd ++;
+       vnet_state->pkt_sent++;
+       recvd++;
 
        q->cur_avail_idx++;
     }
 
-    if(recvd == 0){
-       goto exit;
+    if (recvd == 0) {
+       v3_unlock_irqrestore(vnet_state->lock,flags);
+       return 0;
     }
 
     //PrintError("In polling get %d\n", recvd);
        
     //if on the dom0 core, interrupt the domU core to poll pkts
     //otherwise, call the polling directly
-    int cpu = V3_Get_CPU();
-    if(vnet_state->vm->cores[0].cpu_id == cpu){
-       cpu = (cpu == 0)?1:0;
+
+
+    if (vnet_state->vm->cores[0].cpu_id == cpu) {
+       cpu = (cpu == 0) ? 1 : 0;
        v3_interrupt_cpu(vnet_state->vm, cpu, V3_VNET_POLLING_VECTOR);
-    }else{
+    } else {
        v3_vnet_polling();
     }
 
-    if((vnet_state->pkt_sent % (QUEUE_SIZE/20)) == 0) { //optimized for guest's, batch the interrupts
-           if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
-               v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
-               vnet_state->virtio_cfg.pci_isr = 0x1;
-           }
+    if ((vnet_state->pkt_sent % (QUEUE_SIZE/20)) == 0) {
+       //optimized for guest's, batch the interrupts
+       
+       if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
+           v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
+           vnet_state->virtio_cfg.pci_isr = 0x1;
+       }
     }
-
+    
 #ifdef CONFIG_VNET_PROFILE
     if (vnet_state->pkt_sent % 200000 == 0)
        PrintError("Vnet Bridge: sent: %ld, rxed: %ld, dropped: %ld, total exit: %ld, tx exit: %ld, rx exit: %ld\n",
-                       vnet_state->pkt_sent,
-                       vnet_state->pkt_recv,
-                       vnet_state->pkt_drop, 
-                       vnet_state->total_exit,
-                       vnet_state->tx_exit,
-                       vnet_state->rx_exit);
+                  vnet_state->pkt_sent,
+                  vnet_state->pkt_recv,
+                  vnet_state->pkt_drop, 
+                  vnet_state->total_exit,
+                  vnet_state->tx_exit,
+                  vnet_state->rx_exit);
 #endif
 
-exit:
     v3_unlock_irqrestore(vnet_state->lock,flags);
 
     return 0;
 }
 
-static int polling_pkt_from_guest(struct v3_vm_info * vm, void *private_data){
+static int polling_pkt_from_guest(struct v3_vm_info * vm, void *private_data) {
     struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
        
     return handle_pkt_kick(&(vm->cores[0]), vnet_state);
 }
 
-static int handle_rx_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) 
-{
+static int handle_rx_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state) {
     v3_vnet_enable_bridge();
        
     return 0;
@@ -415,70 +428,77 @@ static int vnet_virtio_io_write(struct guest_info * core, uint16_t port, void *
               port, length, *(uint32_t *)src);
     PrintDebug("VNET Bridge: port idx=%d\n", port_idx);
 
-    vnet_state->total_exit ++;
+    vnet_state->total_exit++;
 
     switch (port_idx) {
        case GUEST_FEATURES_PORT:
+
            if (length != 4) {
                PrintError("Illegal write length for guest features\n");
                return -1;
            }    
+
            vnet_state->virtio_cfg.guest_features = *(uint32_t *)src;
 
            break;
-       case VRING_PG_NUM_PORT:
-           if (length == 4) {
-               addr_t pfn = *(uint32_t *)src;
-               addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
+       case VRING_PG_NUM_PORT: {
 
-               vnet_state->cur_queue->pfn = pfn;
-               
-               vnet_state->cur_queue->ring_desc_addr = page_addr ;
-               vnet_state->cur_queue->ring_avail_addr = page_addr + (QUEUE_SIZE * sizeof(struct vring_desc));
-               vnet_state->cur_queue->ring_used_addr = ( vnet_state->cur_queue->ring_avail_addr + \
-                                                sizeof(struct vring_avail)    + \
-                                                (QUEUE_SIZE * sizeof(uint16_t)));
-               
-               // round up to next page boundary.
-               vnet_state->cur_queue->ring_used_addr = (vnet_state->cur_queue->ring_used_addr + 0xfff) & ~0xfff;
+           addr_t pfn = *(uint32_t *)src;
+           addr_t page_addr = (pfn << VIRTIO_PAGE_SHIFT);
 
-               if (v3_gpa_to_hva(core, vnet_state->cur_queue->ring_desc_addr, (addr_t *)&(vnet_state->cur_queue->desc)) == -1) {
-                   PrintError("Could not translate ring descriptor address\n");
-                   return -1;
-               }
-
-               if (v3_gpa_to_hva(core, vnet_state->cur_queue->ring_avail_addr, (addr_t *)&(vnet_state->cur_queue->avail)) == -1) {
-                   PrintError("Could not translate ring available address\n");
-                   return -1;
-               }
-
-               if (v3_gpa_to_hva(core, vnet_state->cur_queue->ring_used_addr, (addr_t *)&(vnet_state->cur_queue->used)) == -1) {
-                   PrintError("Could not translate ring used address\n");
-                   return -1;
-               }
-
-               PrintDebug("VNET Bridge: RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n",
-                          (void *)(vnet_state->cur_queue->ring_desc_addr),
-                          (void *)(vnet_state->cur_queue->ring_avail_addr),
-                          (void *)(vnet_state->cur_queue->ring_used_addr));
-
-               PrintDebug("VNET Bridge: RingDesc=%p, Avail=%p, Used=%p\n", 
-                          vnet_state->cur_queue->desc, vnet_state->cur_queue->avail, vnet_state->cur_queue->used);
-
-               if(vnet_state->queue[RECV_QUEUE].avail != NULL){
-                   vnet_state->ready = 1;
-               }
+           if (length != 4) {
+               PrintError("Illegal write length for page frame number\n");
+               return -1;
+           }
+           
 
-               //No notify when there is pkt tx from guest
-               if(vnet_state->queue[XMIT_QUEUE].used != NULL){
-                   vnet_state->queue[XMIT_QUEUE].used->flags |= VRING_NO_NOTIFY_FLAG;
-               }
+           vnet_state->cur_queue->pfn = pfn;
                
-           } else {
-               PrintError("Illegal write length for page frame number\n");
+           vnet_state->cur_queue->ring_desc_addr = page_addr ;
+           vnet_state->cur_queue->ring_avail_addr = page_addr + (QUEUE_SIZE * sizeof(struct vring_desc));
+           vnet_state->cur_queue->ring_used_addr = ( vnet_state->cur_queue->ring_avail_addr + \
+                                                     sizeof(struct vring_avail) + \
+                                                     (QUEUE_SIZE * sizeof(uint16_t)));
+           
+           // round up to next page boundary.
+           vnet_state->cur_queue->ring_used_addr = (vnet_state->cur_queue->ring_used_addr + 0xfff) & ~0xfff;
+           
+           if (v3_gpa_to_hva(core, vnet_state->cur_queue->ring_desc_addr, (addr_t *)&(vnet_state->cur_queue->desc)) == -1) {
+               PrintError("Could not translate ring descriptor address\n");
                return -1;
            }
+           
+           if (v3_gpa_to_hva(core, vnet_state->cur_queue->ring_avail_addr, (addr_t *)&(vnet_state->cur_queue->avail)) == -1) {
+               PrintError("Could not translate ring available address\n");
+               return -1;
+           }
+           
+           if (v3_gpa_to_hva(core, vnet_state->cur_queue->ring_used_addr, (addr_t *)&(vnet_state->cur_queue->used)) == -1) {
+               PrintError("Could not translate ring used address\n");
+               return -1;
+           }
+           
+           PrintDebug("VNET Bridge: RingDesc_addr=%p, Avail_addr=%p, Used_addr=%p\n",
+                      (void *)(vnet_state->cur_queue->ring_desc_addr),
+                      (void *)(vnet_state->cur_queue->ring_avail_addr),
+                      (void *)(vnet_state->cur_queue->ring_used_addr));
+           
+           PrintDebug("VNET Bridge: RingDesc=%p, Avail=%p, Used=%p\n", 
+                      vnet_state->cur_queue->desc, 
+                      vnet_state->cur_queue->avail, 
+                      vnet_state->cur_queue->used);
+           
+           if (vnet_state->queue[RECV_QUEUE].avail != NULL){
+               vnet_state->ready = 1;
+           }
+           
+           //No notify when there is pkt tx from guest
+           if (vnet_state->queue[XMIT_QUEUE].used != NULL) {
+               vnet_state->queue[XMIT_QUEUE].used->flags |= VRING_NO_NOTIFY_FLAG;
+           }
+           
            break;
+       }
        case VRING_Q_SEL_PORT:
            vnet_state->virtio_cfg.vring_queue_selector = *(uint16_t *)src;
 
@@ -624,9 +644,9 @@ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
     struct virtio_vnet_state * vnet_state = NULL;
     struct pci_device * pci_dev = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
-    PrintDebug("VNET Bridge: Initializing VNET Bridge Control device: %s\n", name);
+    PrintDebug("VNET Bridge: Initializing VNET Bridge Control device: %s\n", dev_id);
 
     if (pci_bus == NULL) {
        PrintError("VNET Bridge device require a PCI Bus");
@@ -638,10 +658,10 @@ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
        
     vnet_state->vm = vm;
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnet_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, vnet_state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 521f543..ec042d6 100644 (file)
@@ -276,7 +276,7 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     char * ip_str = v3_cfg_val(cfg, "IP");
     char * port_str = v3_cfg_val(cfg, "port");
     char * disk_tag = v3_cfg_val(cfg, "tag");
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
 
@@ -286,10 +286,10 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     disk->ip_addr = v3_inet_addr(ip_str);
     disk->port = atoi(port_str);
        
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, disk);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
@@ -302,7 +302,7 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
                           &blk_ops, frontend_cfg, disk) == -1) {
-       PrintError("Could not connect %s to frontend\n", name);
+       PrintError("Could not connect %s to frontend\n", dev_id);
        return -1;
     }
 
index fb9b319..e2d1e05 100644 (file)
@@ -791,7 +791,7 @@ static struct v3_device_ops dev_ops = {
 static int nvram_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct nvram_internal * nvram_state = NULL;
     struct vm_device * ide = v3_find_dev(vm, v3_cfg_val(cfg, "storage"));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     if (!ide) {
        PrintError("Could not find IDE device\n");
@@ -805,11 +805,11 @@ static int nvram_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     nvram_state->ide = ide;
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, nvram_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, nvram_state);
 
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 963fd88..9e6ceba 100644 (file)
@@ -104,17 +104,17 @@ static struct v3_device_ops dev_ops = {
 
 static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct debug_state * state = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state));
 
     PrintDebug("Creating OS Debug Device\n");
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 0bb7698..a42d99a 100644 (file)
@@ -102,16 +102,16 @@ static struct v3_device_ops dev_ops = {
 
 static int net_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     struct nic_state * state = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     state = (struct nic_state *)V3_Malloc(sizeof(struct nic_state));
 
     PrintDebug("Creating VMNet Device\n");
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-        PrintError("Could not attach device %s\n", name);
+        PrintError("Could not attach device %s\n", dev_id);
         return -1;
     }
 
index f43d36d..267eca1 100644 (file)
@@ -655,14 +655,14 @@ static struct v3_device_ops dev_ops = {
 static int pci_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal));
     int i = 0;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
     
     PrintDebug("PCI internal at %p\n",(void *)pci_state);
     
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, pci_state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, pci_state);
     
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 3eee1d2..8552112 100644 (file)
@@ -779,7 +779,7 @@ static int passthrough_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct pt_dev_state * state = V3_Malloc(sizeof(struct pt_dev_state));
     struct vm_device * dev = NULL;
     struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
-    char * name = v3_cfg_val(cfg, "name");    
+    char * dev_id = v3_cfg_val(cfg, "ID");    
 
 
     memset(state, 0, sizeof(struct pt_dev_state));
@@ -790,13 +790,13 @@ static int passthrough_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     }
     
     state->pci_bus = pci;
-    strncpy(state->name, name, 32);
+    strncpy(state->name, dev_id, 32);
 
 
-    dev = v3_allocate_device(name, &dev_ops, state);
+    dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 493e3c5..89f021f 100644 (file)
@@ -449,7 +449,7 @@ static int piix3_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct v3_southbridge * piix3 = (struct v3_southbridge *)V3_Malloc(sizeof(struct v3_southbridge));
     struct vm_device * dev = NULL;
     struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus"));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     if (!pci) {
        PrintError("Could not find PCI device\n");
@@ -459,10 +459,10 @@ static int piix3_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     piix3->pci_bus = pci;
     piix3->type = V3_SB_PIIX3;
     
-    dev = v3_allocate_device(name, &dev_ops, piix3);
+    dev = v3_allocate_device(dev_id, &dev_ops, piix3);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 8930620..fe45da0 100644 (file)
@@ -89,7 +89,7 @@ static struct v3_device_ops dev_ops = {
 static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct disk_state * disk = NULL;
     struct v3_cfg_file * file = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
     char * filename = v3_cfg_val(cfg, "file");
 
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
@@ -99,7 +99,7 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
 
     if (!filename) {
-       PrintError("Missing filename (%s) for %s\n", filename, name);
+       PrintError("Missing filename (%s) for %s\n", filename, dev_id);
        return -1;
     }
 
@@ -115,17 +115,17 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     PrintDebug("Registering RAMDISK at %p (size=%d)\n", 
               (void *)file->data, (uint32_t)file->size);
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, disk);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
     if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
                           &blk_ops, frontend_cfg, disk) == -1) {
        PrintError("Could not connect %s to frontend %s\n", 
-                  name, v3_cfg_val(frontend_cfg, "tag"));
+                  dev_id, v3_cfg_val(frontend_cfg, "tag"));
        return -1;
     }
     
index e7f11da..3f0085e 100644 (file)
@@ -914,7 +914,7 @@ static int init_serial_port(struct serial_port * com) {
 
 static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct serial_state * state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state));
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     PrintDebug("UART: init_device\n");
     init_serial_port(&(state->com1));
@@ -928,10 +928,10 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     state->com4.irq_number = COM4_IRQ;
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 7d6dd80..951590e 100644 (file)
@@ -273,7 +273,7 @@ static int swap_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct swap_state * swap = NULL;
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
     uint32_t capacity = atoi(v3_cfg_val(cfg, "size")) * 1024 * 1024;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
     if (!frontend_cfg) {
        PrintError("Initializing sym swap without a frontend device\n");
@@ -300,17 +300,17 @@ static int swap_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     memset(swap->usage_map, 0, ((swap->capacity / 4096) / 8));
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, swap);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, swap);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
     if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
                           &blk_ops, frontend_cfg, swap) == -1) {
        PrintError("Could not connect %s to frontend %s\n", 
-                  name, v3_cfg_val(frontend_cfg, "tag"));
+                  dev_id, v3_cfg_val(frontend_cfg, "tag"));
        return -1;
     }
 
index 72ff58f..bc83762 100644 (file)
@@ -599,17 +599,17 @@ static int connect_fn(struct v3_vm_info * vm,
 
 static int swap_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, NULL);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, NULL);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
-    if (v3_dev_add_blk_frontend(vm, name, connect_fn, NULL) == -1) {
-       PrintError("Could not register %s as block frontend\n", name);
+    if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, NULL) == -1) {
+       PrintError("Could not register %s as block frontend\n", dev_id);
        return -1;
     }
 
index d0c2b1f..00415c5 100644 (file)
@@ -523,11 +523,11 @@ static int cons_server(void * arg) {
 }
 
 
-static int cons_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
+static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct cons_state * state = (struct cons_state *)V3_Malloc(sizeof(struct cons_state));
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
-    struct vm_device * frontend = v3_find_dev(vm, v3_cfg_val(frontend_cfg, "id"));
-    char * name = v3_cfg_val(cfg, "name");
+    struct vm_device * frontend = v3_find_dev(vm, v3_cfg_val(frontend_cfg, "tag"));
+    char * dev_id = v3_cfg_val(cfg, "ID");
 
 
     state->server_fd = 0;
@@ -537,10 +537,10 @@ static int cons_init(struct guest_info * vm, v3_cfg_tree_t * cfg) {
     v3_lock_init(&(state->cons_lock));
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, state);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
index 1a917ab..bf582e7 100644 (file)
@@ -99,7 +99,7 @@ static struct v3_device_ops dev_ops = {
 static int blk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct blk_state * blk = NULL;
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
     uint64_t capacity = atoi(v3_cfg_val(cfg, "size")) * 1024 * 1024;
     
     if (!frontend_cfg) {
@@ -119,17 +119,17 @@ static int blk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     memset(blk->blk_space, 0, capacity);
 
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, blk);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, blk);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
     if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), 
                           &blk_ops, frontend_cfg, blk) == -1) {
        PrintError("Could not connect %s to frontend %s\n", 
-                  name, v3_cfg_val(frontend_cfg, "tag"));
+                  dev_id, v3_cfg_val(frontend_cfg, "tag"));
        return -1;
     }
 
index 7a7dac0..479593b 100644 (file)
@@ -41,10 +41,10 @@ struct vnet_nic_state {
 };
 
 
-static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
-    struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
-
+static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device * dest_dev){
+    struct vnet_nic_state * vnetnic = (struct vnet_nic_state *)private_data;
     struct v3_vnet_pkt pkt;
+
     pkt.size = len;
     pkt.src_type = LINK_INTERFACE;
     pkt.src_id = vnetnic->vnet_dev_id;
@@ -82,10 +82,10 @@ static int virtio_input(struct v3_vm_info *info, struct v3_vnet_pkt * pkt, void
 }
 
 static int register_to_vnet(struct v3_vm_info * vm,
-                    struct vnet_nic_state *vnet_nic,
-                    char *dev_name,
-                    uchar_t mac[6]) { 
-   
+                           struct vnet_nic_state * vnet_nic,
+                           char * dev_name,
+                           uint8_t mac[6]) { 
+    
     PrintDebug("Vnet-nic: register Vnet-nic device %s, state %p to VNET\n", dev_name, vnet_nic);
        
     return v3_vnet_add_dev(vm, mac, virtio_input, (void *)vnet_nic);
@@ -103,16 +103,24 @@ static struct v3_device_ops dev_ops = {
 };
 
 
-static int str2mac(char *macstr, char mac[6]){
-    char hex[2], *s = macstr;
+static int str2mac(char * macstr, uint8_t mac[6]){
+    uint8_t hex[2];
     int i = 0;
+    char * s = macstr;
 
-    while(s){
+    while (s) {
        memcpy(hex, s, 2);
        mac[i++] = (char)atox(hex);
-       if (i == 6) return 0;
-       s=strchr(s, ':');
-       if(s) s++;
+
+       if (i == 6) {
+           return 0;
+       }
+
+       s = strchr(s, ':');
+
+       if (s) {
+           s++;
+       }
     }
 
     return -1;
@@ -120,126 +128,53 @@ static int str2mac(char *macstr, char mac[6]){
 
 static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
     struct vnet_nic_state * vnetnic = NULL;
-    char * name = v3_cfg_val(cfg, "name");
+    char * dev_id = v3_cfg_val(cfg, "ID");
     char * macstr = NULL;
-    char mac[6];
-    int vnet_dev_id;
-
+    int vnet_dev_id = 0;
     v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend");
+
     macstr = v3_cfg_val(frontend_cfg, "mac");
 
     if (macstr == NULL) {
-       PrintDebug("Vnet-nic: No Mac specified\n");
-    } else {
-       str2mac(macstr, mac);
+       PrintDebug("Vnet-nic configuration error: No Mac specified\n");
+       return -1;
     }
 
     vnetnic = (struct vnet_nic_state *)V3_Malloc(sizeof(struct vnet_nic_state));
     memset(vnetnic, 0, sizeof(struct vnet_nic_state));
 
-    struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnetnic);
+    struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, vnetnic);
 
     if (v3_attach_device(vm, dev) == -1) {
-       PrintError("Could not attach device %s\n", name);
+       PrintError("Could not attach device %s\n", dev_id);
        return -1;
     }
 
+
+
     vnetnic->net_ops.send = vnet_send;
-    memcpy(vnetnic->mac, mac, 6);
+    str2mac(macstr, vnetnic->mac);
     vnetnic->vm = vm;
        
     if (v3_dev_connect_net(vm, v3_cfg_val(frontend_cfg, "tag"), 
                           &(vnetnic->net_ops), frontend_cfg, vnetnic) == -1) {
        PrintError("Could not connect %s to frontend %s\n", 
-                  name, v3_cfg_val(frontend_cfg, "tag"));
+                  dev_id, v3_cfg_val(frontend_cfg, "tag"));
        return -1;
     }
 
     PrintDebug("Vnet-nic: Connect %s to frontend %s\n", 
-                  name, v3_cfg_val(frontend_cfg, "tag"));
+              dev_id, v3_cfg_val(frontend_cfg, "tag"));
 
-    if ((vnet_dev_id = register_to_vnet(vm, vnetnic, name, vnetnic->mac)) == -1) {
-       PrintError("Vnet-nic device %s (mac: %s) fails to registered to VNET\n", name, macstr);
+    if ((vnet_dev_id = register_to_vnet(vm, vnetnic, dev_id, vnetnic->mac)) == -1) {
+       PrintError("Vnet-nic device %s (mac: %s) fails to registered to VNET\n", dev_id, macstr);
+       return -1;
     }
-    vnetnic->vnet_dev_id = vnet_dev_id;
-
-    PrintDebug("Vnet-nic device %s (mac: %s, %ld) registered to VNET\n", name, macstr, *((ulong_t *)vnetnic->mac));
 
+    vnetnic->vnet_dev_id = vnet_dev_id;
 
-//for temporary hack for vnet bridge test
-#if 1
-    {
-       uchar_t zeromac[6] = {0,0,0,0,0,0};
-               
-       if(!strcmp(name, "vnet_nic")){
-           struct v3_vnet_route route;
-               
-           route.dst_id = vnet_dev_id;
-           route.dst_type = LINK_INTERFACE;
-           route.src_id = 0;
-           route.src_type = LINK_EDGE;
-           memcpy(route.dst_mac, zeromac, 6);
-           route.dst_mac_qual = MAC_ANY;
-           memcpy(route.src_mac, zeromac, 6);
-           route.src_mac_qual = MAC_ANY;  
-           v3_vnet_add_route(route);
-
-
-           route.dst_id = 0;
-           route.dst_type = LINK_EDGE;
-           route.src_id = vnet_dev_id;
-           route.src_type = LINK_INTERFACE;
-           memcpy(route.dst_mac, zeromac, 6);
-           route.dst_mac_qual = MAC_ANY;
-           memcpy(route.src_mac, zeromac, 6);
-           route.src_mac_qual = MAC_ANY;
-
-           v3_vnet_add_route(route);
-       }
-    }
-#endif
+    PrintDebug("Vnet-nic device %s (mac: %s, %ld) registered to VNET\n", dev_id, macstr, *((uint32_t *)vnetnic->mac));
 
-//for temporary hack for Linux bridge (w/o encapuslation) test
-#if 0
-    {
-       static int vnet_nic_guestid = -1;
-       static int vnet_nic_dom0 = -1;
-       uchar_t zeromac[6] = {0,0,0,0,0,0};
-               
-       if(!strcmp(name, "vnet_nic")){ //domu
-           vnet_nic_guestid = vnet_dev_id;
-       }
-       if (!strcmp(name, "vnet_nic_dom0")){
-           vnet_nic_dom0 = vnet_dev_id;
-       }\r
-
-       if(vnet_nic_guestid != -1 && vnet_nic_dom0 !=-1){
-           struct v3_vnet_route route;
-               
-           route.src_id = vnet_nic_guestid;
-           route.src_type = LINK_INTERFACE;
-           route.dst_id = vnet_nic_dom0;
-           route.dst_type = LINK_INTERFACE;
-           memcpy(route.dst_mac, zeromac, 6);
-           route.dst_mac_qual = MAC_ANY;
-           memcpy(route.src_mac, zeromac, 6);
-           route.src_mac_qual = MAC_ANY;  
-           v3_vnet_add_route(route);
-
-
-           route.src_id = vnet_nic_dom0;
-           route.src_type = LINK_INTERFACE;
-           route.dst_id = vnet_nic_guestid;
-           route.dst_type = LINK_INTERFACE;
-           memcpy(route.dst_mac, zeromac, 6);
-           route.dst_mac_qual = MAC_ANY;
-           memcpy(route.src_mac, zeromac, 6);
-           route.src_mac_qual = MAC_ANY;
-
-           v3_vnet_add_route(route);
-       }
-    }
-#endif
 
     return 0;
 }
index 2d2eda8..52497e1 100644 (file)
@@ -60,8 +60,9 @@ obj-$(CONFIG_VMX) +=          vmx.o \
 obj-$(CONFIG_INSTRUMENT_VMM) += vmm_instrument.o
 obj-$(CONFIG_TELEMETRY) += vmm_telemetry.o 
 obj-$(CONFIG_SOCKET) +=  vmm_socket.o
-obj-$(CONFIG_CONSOLE) +=  vmm_console.o
 obj-$(CONFIG_VNET) += vmm_vnet.o
+obj-$(CONFIG_FILE) += vmm_file.o
+
 
 obj-$(CONFIG_SYMBIOTIC) += vmm_symbiotic.o vmm_symspy.o
 obj-$(CONFIG_SYMCALL) += vmm_symcall.o
index 10c3f9d..83bfb10 100644 (file)
@@ -46,8 +46,11 @@ static inline int activate_shadow_pt_32(struct guest_info * core) {
  * *
  * *
  */
-static int handle_4MB_shadow_pagefault_32(struct guest_info * info,  addr_t fault_addr, pf_error_t error_code, 
-                                         pte32_t * shadow_pt, pde32_4MB_t * large_guest_pde);
+static int handle_4MB_shadow_pagefault_pde_32(struct guest_info * info,  addr_t fault_addr, pf_error_t error_code, 
+                                             pt_access_status_t shadow_pde_access, pde32_4MB_t * large_shadow_pde, 
+                                             pde32_4MB_t * large_guest_pde);
+static int handle_4MB_shadow_pagefault_pte_32(struct guest_info * info,  addr_t fault_addr, pf_error_t error_code, 
+                                             pte32_t * shadow_pt, pde32_4MB_t * large_guest_pde);
 
 static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
                                          pte32_t * shadow_pt,  pte32_t * guest_pt);
@@ -129,6 +132,28 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa
     // Get the next shadow page level, allocate if not present
 
     if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
+
+        if (info->use_large_pages && guest_pde->large_page) {
+            // Check underlying physical memory map to see if a large page is viable
+            addr_t guest_pa = BASE_TO_PAGE_ADDR_4MB(((pde32_4MB_t *)guest_pde)->page_base_addr);
+            addr_t host_pa;
+            if (v3_get_max_page_size(info, guest_pa, PAGE_SIZE_4MB) < PAGE_SIZE_4MB) {
+                PrintDebug("Underlying physical memory map doesn't allow use of a large page.\n");
+                // Fallthrough to small pages
+            } else if ((v3_gpa_to_hpa(info, guest_pa, &host_pa) != 0)
+                       || (v3_compute_page_alignment(host_pa) < PAGE_SIZE_4MB)) {
+                PrintDebug("Host memory alignment doesn't allow use of a large page.\n");
+                // Fallthrough to small pages
+            } else if (handle_4MB_shadow_pagefault_pde_32(info, fault_addr, error_code, shadow_pde_access,
+                                                          (pde32_4MB_t *)shadow_pde, (pde32_4MB_t *)guest_pde) == 0) {
+                return 0;
+            } else {
+                PrintError("Error handling large pagefault with large page\n");
+                return -1;
+            }
+            // Fallthrough to handle the region with small pages
+        }
+
        struct shadow_page_data * shdw_page =  create_new_shadow_pt(info);
        shadow_pt = (pte32_t *)V3_VAddr((void *)shdw_page->page_pa);
 
@@ -181,7 +206,7 @@ static inline int handle_shadow_pagefault_32(struct guest_info * info, addr_t fa
            return -1;
        }
     } else {
-       if (handle_4MB_shadow_pagefault_32(info, fault_addr, error_code, shadow_pt, (pde32_4MB_t *)guest_pde) == -1) {
+       if (handle_4MB_shadow_pagefault_pte_32(info, fault_addr, error_code, shadow_pt, (pde32_4MB_t *)guest_pde) == -1) {
            PrintError("Error handling large pagefault\n");
            return -1;
        }       
@@ -322,9 +347,8 @@ static int handle_pte_shadow_pagefault_32(struct guest_info * info, addr_t fault
     return 0;
 }
 
-
-
-static int handle_4MB_shadow_pagefault_32(struct guest_info * info, 
+// Handle a 4MB page fault with small pages in the PTE
+static int handle_4MB_shadow_pagefault_pte_32(struct guest_info * info, 
                                     addr_t fault_addr, pf_error_t error_code, 
                                     pte32_t * shadow_pt, pde32_4MB_t * large_guest_pde) 
 {
@@ -414,20 +438,98 @@ static int handle_4MB_shadow_pagefault_32(struct guest_info * info,
        return -1;
     }
 
-    PrintDebug("Returning from large page fault handler\n");
+    PrintDebug("Returning from large page->small page fault handler\n");
     return 0;
 }
 
 
+// Handle a 4MB page fault with a 4MB page in the PDE
+static int handle_4MB_shadow_pagefault_pde_32(struct guest_info * info, 
+                                    addr_t fault_addr, pf_error_t error_code, 
+                                    pt_access_status_t shadow_pde_access,
+                                    pde32_4MB_t * large_shadow_pde, pde32_4MB_t * large_guest_pde) 
+{
+    addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_4MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_4MB(fault_addr);  
+
+
+    PrintDebug("Handling 4MB fault with large page (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
+    PrintDebug("LargeShadowPDE=%p, LargeGuestPDE=%p\n", large_shadow_pde, large_guest_pde);
+
+    struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa);
+
+    if (shdw_reg == NULL) {
+       // Inject a machine check in the guest
+       PrintDebug("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
+       v3_raise_exception(info, MC_EXCEPTION);
+       return -1;
+    }
+
+    if (shadow_pde_access == PT_ACCESS_OK) {
+       // Inconsistent state...
+       // Guest Re-Entry will flush tables and everything should now workd
+       PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
+       return 0;
+    }
+
+  
+    if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
+       // Get the guest physical address of the fault
+
+       if ((shdw_reg->flags.alloced == 1) && 
+           (shdw_reg->flags.read  == 1)) {
+           addr_t shadow_pa = 0;
+
 
+           if (v3_gpa_to_hpa(info, guest_fault_pa, &shadow_pa) == -1) {
+               PrintError("could not translate page fault address (%p)\n", (void *)guest_fault_pa);
+               return -1;
+           }
 
+           PrintDebug("\tMapping shadow page (%p)\n", (void *)BASE_TO_PAGE_ADDR(shadow_pte->page_base_addr));
 
+            large_guest_pde->vmm_info = V3_LARGE_PG; /* For invalidations */
+            large_shadow_pde->page_base_addr = PAGE_BASE_ADDR_4MB(shadow_pa);
+            large_shadow_pde->large_page = 1;
+            large_shadow_pde->present = 1;
+            large_shadow_pde->user_page = 1;
 
+            if (shdw_reg->flags.write == 0) {
+                large_shadow_pde->writable = 0;
+            } else {
+                large_shadow_pde->writable = 1;
+            }
 
+           //set according to VMM policy
+           large_shadow_pde->write_through = large_guest_pde->write_through;
+           large_shadow_pde->cache_disable = large_guest_pde->cache_disable;
+           large_shadow_pde->global_page = large_guest_pde->global_page;
+           //
 
+       } else {
+           if (shdw_reg->unhandled(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+               PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+               return -1;
+           }
+       }
+    } else if (shadow_pde_access == PT_ACCESS_WRITE_ERROR) {
 
+       if (shdw_reg->flags.write == 0) {
+           if (shdw_reg->unhandled(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+               PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+               return -1;
+           }
+       }
 
+    } else {
+       PrintError("Error in large page fault handler...\n");
+       PrintError("This case should have been handled at the top level handler\n");
+       return -1;
+    }
 
+    PrintDebug("Returning from large page->large page fault handler\n");
+    return 0;
+}
 
 /* If we start to optimize we should look up the guest pages in the cache... */
 static inline int handle_shadow_invlpg_32(struct guest_info * info, addr_t vaddr) {
index 34102ac..011a882 100644 (file)
@@ -52,8 +52,11 @@ static inline int activate_shadow_pt_64(struct guest_info * info) {
  * *
  */
 
-static int handle_2MB_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
-                                         pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde);
+static int handle_2MB_shadow_pagefault_pde_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
+                                             pt_access_status_t shadow_pde_access, pde64_2MB_t * shadow_pt, 
+                                             pde64_2MB_t * large_guest_pde);
+static int handle_2MB_shadow_pagefault_pte_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
+                                             pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde);
 
 static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
                                          pte64_t * shadow_pt, pte64_t * guest_pt);
@@ -268,7 +271,6 @@ static int handle_pdpe_shadow_pagefault_64(struct guest_info * info, addr_t faul
     return 0;
 }
 
-
 static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault_addr, pf_error_t error_code,
                                          pde64_t * shadow_pd, pde64_t * guest_pd) {
     pt_access_status_t guest_pde_access;
@@ -329,13 +331,34 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault
        return 0;
     }
 
-
     pte64_t * shadow_pt = NULL;
     pte64_t * guest_pt = NULL;
 
-    // Get the next shadow page level, allocate if not present
-
+    // get the next shadow page level, allocate if not present
     if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
+        // Check if  we can use large pages and the guest memory is properly aligned
+        // to potentially use a large page
+        if (info->use_large_pages && guest_pde->large_page) {
+            // Check underlying physical memory map to see if a large page is viable
+           addr_t guest_pa = BASE_TO_PAGE_ADDR_2MB(((pde64_2MB_t *)guest_pde)->page_base_addr);
+           addr_t host_pa;
+           if (v3_get_max_page_size(info, guest_pa, PAGE_SIZE_2MB) < PAGE_SIZE_2MB) {
+               PrintDebug("Underlying physical memory map doesn't allow use of a large page.\n");
+               // Fallthrough to small pages
+           } else if ((v3_gpa_to_hpa(info, guest_pa, &host_pa) != 0)
+                      || (v3_compute_page_alignment(host_pa) < PAGE_SIZE_2MB)) {
+               PrintDebug("Host memory alignment doesn't allow use of a large page.\n");
+               // Fallthrough to small pages
+           } else if (handle_2MB_shadow_pagefault_pde_64(info, fault_addr, error_code, shadow_pde_access,
+                                                      (pde64_2MB_t *)shadow_pde, (pde64_2MB_t *)guest_pde) == 0) {
+               return 0;
+           } else {
+               PrintError("Error handling large pagefault with large page\n");
+               return -1;
+           }
+           // Fallthrough to handle the region with small pages
+       }
+
        struct shadow_page_data * shdw_page = create_new_shadow_pt(info);
        shadow_pt = (pte64_t *)V3_VAddr((void *)shdw_page->page_pa);
 
@@ -387,8 +410,8 @@ static int handle_pde_shadow_pagefault_64(struct guest_info * info, addr_t fault
            return -1;
        }
     } else {
-       if (handle_2MB_shadow_pagefault_64(info, fault_addr, error_code, shadow_pt, (pde64_2MB_t *)guest_pde) == -1) {
-           PrintError("Error handling large pagefault\n");
+       if (handle_2MB_shadow_pagefault_pte_64(info, fault_addr, error_code, shadow_pt, (pde64_2MB_t *)guest_pde) == -1) {
+           PrintError("Error handling large pagefault with small page\n");
            return -1;
        } 
     }
@@ -529,10 +552,90 @@ static int handle_pte_shadow_pagefault_64(struct guest_info * info, addr_t fault
 }
 
 
+static int handle_2MB_shadow_pagefault_pde_64(struct guest_info * info, 
+                                             addr_t fault_addr, pf_error_t error_code, 
+                                             pt_access_status_t shadow_pde_access,
+                                             pde64_2MB_t * large_shadow_pde, pde64_2MB_t * large_guest_pde) 
+{
+    addr_t guest_fault_pa = BASE_TO_PAGE_ADDR_2MB(large_guest_pde->page_base_addr) + PAGE_OFFSET_2MB(fault_addr);
+    //  struct shadow_page_state * state = &(info->shdw_pg_state);
+
+    PrintDebug("Handling 2MB fault with large page (guest_fault_pa=%p) (error_code=%x)\n", (void *)guest_fault_pa, *(uint_t*)&error_code);
+    PrintDebug("LargeShadowPDE=%p, LargeGuestPDE=%p\n", large_shadow_pde, large_guest_pde);
+
+    struct v3_mem_region * shdw_reg = v3_get_mem_region(info->vm_info, info->cpu_id, guest_fault_pa);
+    if (shdw_reg == NULL) {
+       // Inject a machine check in the guest
+       PrintError("Invalid Guest Address in page table (0x%p)\n", (void *)guest_fault_pa);
+       v3_raise_exception(info, MC_EXCEPTION);
+       return 0;
+    }
+
+    if (shadow_pde_access == PT_ACCESS_OK) {
+       // Inconsistent state...
+       // Guest Re-Entry will flush tables and everything should now workd
+       PrintDebug("Inconsistent state... Guest re-entry should flush tlb\n");
+       //PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
+       return 0;
+    }
+
+  
+    if (shadow_pde_access == PT_ACCESS_NOT_PRESENT) {
+       // Get the guest physical address of the fault
+
+       if ((shdw_reg->flags.alloced == 1) || 
+           (shdw_reg->flags.read == 1)) {
+           addr_t shadow_pa = 0;
+
+           if (v3_gpa_to_hpa(info, guest_fault_pa, &shadow_pa) == -1) {
+               PrintError("could not translate page fault address (%p)\n", (void *)guest_fault_pa);
+               return -1;
+           }
+
+           large_guest_pde->vmm_info = V3_LARGE_PG; /* For invalidations */
+           large_shadow_pde->page_base_addr = PAGE_BASE_ADDR_2MB(shadow_pa);
+           large_shadow_pde->large_page = 1;
+           large_shadow_pde->present = 1;
+           large_shadow_pde->user_page = 1;
+
+           if (shdw_reg->flags.write == 0) {
+               large_shadow_pde->writable = 0;
+           } else {
+               large_shadow_pde->writable = 1;
+           }
+
+           //set according to VMM policy
+           large_shadow_pde->write_through = large_guest_pde->write_through;
+           large_shadow_pde->cache_disable = large_guest_pde->cache_disable;
+           large_shadow_pde->global_page = large_guest_pde->global_page;
+           //
+      
+       } else {
+           if (shdw_reg->unhandled(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+               PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+               return -1;
+           }
+       }
+    } else if (shadow_pde_access == PT_ACCESS_WRITE_ERROR) {
+       if (shdw_reg->unhandled(info, fault_addr, guest_fault_pa, shdw_reg, error_code) == -1) {
+           PrintError("Special Page Fault handler returned error for address: %p\n", (void *)fault_addr);
+           return -1;
+       }
+    } else {
+       PrintError("Error in large page fault handler...\n");
+       PrintError("This case should have been handled at the top level handler\n");
+       return -1;
+    }
+
+    //  PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
+    PrintDebug("Returning from large page->large page fault handler\n");
+    return 0;
+}
 
-static int handle_2MB_shadow_pagefault_64(struct guest_info * info, 
-                                         addr_t fault_addr, pf_error_t error_code, 
-                                         pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde) 
+static int handle_2MB_shadow_pagefault_pte_64(struct guest_info * info, 
+                                             addr_t fault_addr, pf_error_t error_code, 
+                                             pte64_t * shadow_pt, pde64_2MB_t * large_guest_pde) 
 {
     pt_access_status_t shadow_pte_access = v3_can_access_pte64(shadow_pt, fault_addr, error_code);
     pte64_t * shadow_pte = (pte64_t *)&(shadow_pt[PTE64_INDEX(fault_addr)]);
@@ -614,7 +717,7 @@ static int handle_2MB_shadow_pagefault_64(struct guest_info * info,
     }
 
     //  PrintHostPageTree(info, fault_addr, info->ctrl_regs.cr3);
-    PrintDebug("Returning from large page fault handler\n");
+    PrintDebug("Returning from large page->small page fault handler\n");
     return 0;
 }
 
index 93038c6..3fb5bcc 100644 (file)
@@ -269,7 +269,7 @@ int v3_handle_svm_io_outs(struct guest_info * core, struct svm_io_info * io_info
     uint_t rep_num = 1;
     ullong_t mask = 0;
     addr_t inst_ptr;
-    struct v3_segment * theseg = &(core->segments.es); // default is ES
+    struct v3_segment * theseg = &(core->segments.ds); // default is DS
 
     // This is kind of hacky...
     // direction can equal either 1 or -1
index 86eb1dd..c2c8c57 100644 (file)
@@ -183,12 +183,35 @@ static struct v3_config * parse_config(void * cfg_blob) {
     return cfg;
 }
 
+
+static inline uint32_t get_alignment(char * align_str) {
+    // default is 4KB alignment
+    uint32_t alignment = PAGE_SIZE_4KB;
+
+    if (align_str != NULL) {
+       if (strcasecmp(align_str, "2MB") == 0) {
+           alignment = PAGE_SIZE_2MB;
+       } else if (strcasecmp(align_str, "4MB") == 0) {
+           alignment = PAGE_SIZE_4MB;
+       }
+    }
+    
+#ifndef CONFIG_ALIGNED_PG_ALLOC
+    if (alignment != PAGE_SIZE_4KB) {
+       PrintError("Aligned page allocations are not supported in this host (requested alignment=%d)\n", alignment);
+       PrintError("Ignoring alignment request\n");
+    }
+#endif 
+
+    return alignment;
+}
 static int pre_config_vm(struct v3_vm_info * vm, v3_cfg_tree_t * vm_cfg) {
 
 
     char * memory_str = v3_cfg_val(vm_cfg, "memory");
     char * schedule_hz_str = v3_cfg_val(vm_cfg, "schedule_hz");
     char * vm_class = v3_cfg_val(vm_cfg, "class");
+    char * align_str = v3_cfg_val(v3_cfg_subtree(vm_cfg, "memory"), "alignment");
     uint32_t sched_hz = 100;   // set the schedule frequency to 100 HZ
     
     if (!memory_str) {
@@ -197,10 +220,18 @@ static int pre_config_vm(struct v3_vm_info * vm, v3_cfg_tree_t * vm_cfg) {
     }
     
     PrintDebug("Memory=%s\n", memory_str);
+    if (align_str) {
+        PrintDebug("Alignment=%s\n", align_str);
+    } else {
+        PrintDebug("Alignment defaulted to 4KB.\n");
+    }
 
     // Amount of ram the Guest will have, always in MB
-    vm->mem_size = (unsigned long)atoi(memory_str) * 1024UL * 1024UL;
-    
+    vm->mem_size = atoi(memory_str) * 1024 * 1024;
+    vm->mem_align = get_alignment(align_str);
+
+    PrintDebug("Alignment computed as 0x%x\n", vm->mem_align);
+
     if (strcasecmp(vm_class, "PC") == 0) {
        vm->vm_class = V3_PC_VM;
     } else {
@@ -270,6 +301,7 @@ static int determine_paging_mode(struct guest_info *info, v3_cfg_tree_t * core_c
        info->shdw_pg_mode = SHADOW_PAGING;
     }
 
+
     if (info->shdw_pg_mode == NESTED_PAGING) {
        PrintDebug("Guest Paging Mode: NESTED_PAGING\n");
        if (strcasecmp(page_size, "4kb") == 0) { /* TODO: this may not be an ideal place for this */
@@ -287,6 +319,12 @@ static int determine_paging_mode(struct guest_info *info, v3_cfg_tree_t * core_c
        PrintError("Guest paging mode incorrectly set.\n");
        return -1;
     }
+
+    if (strcasecmp(v3_cfg_val(pg_tree, "large_pages"), "true") == 0) {
+       info->use_large_pages = 1;
+       PrintDebug("Use of large pages in memory virtualization enabled.\n");
+    }
+
     return 0;
 }
 
@@ -517,12 +555,12 @@ static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
 
     
     while (device) {
-       char * id = v3_cfg_val(device, "id");
+       char * dev_class = v3_cfg_val(device, "class");
 
-       V3_Print("configuring device %s\n", id);
+       V3_Print("configuring device %s\n", dev_class);
 
-       if (v3_create_device(vm, id, device) == -1) {
-           PrintError("Error creating device %s\n", id);
+       if (v3_create_device(vm, dev_class, device) == -1) {
+           PrintError("Error creating device %s\n", dev_class);
            return -1;
        }
        
index c4c41e3..97324d4 100644 (file)
@@ -29,9 +29,7 @@
 
 // Reference: AMD Software Developer Manual Vol.2 Ch.5 "Page Translation and Protection"
 
-static inline int handle_passthrough_pagefault_64(struct guest_info * info, 
-                                                 addr_t fault_addr, 
-                                                 pf_error_t error_code) {
+static inline int handle_passthrough_pagefault_64(struct guest_info * core, addr_t fault_addr, pf_error_t error_code) {
     pml4e64_t * pml      = NULL;
     pdpe64_t * pdpe      = NULL;
     pde64_t * pde        = NULL;
@@ -44,79 +42,30 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
     int pde_index  = PDE64_INDEX(fault_addr);
     int pte_index  = PTE64_INDEX(fault_addr);
 
-    struct v3_mem_region * region =  v3_get_mem_region(info->vm_info, info->cpu_id, fault_addr);
-    struct v3_mem_region * base_reg = &(info->vm_info->mem_map.base_region);
-
-    /* If the guest has been configured for 2MiB pages, then we must check for hooked regions of
-     * memory which may overlap with the 2MiB page containing the faulting address (due to
-     * potentially differing access policies in place for e.g. i/o devices and APIC). A 2MiB page
-     * can be used if a) no region overlaps the page [or b) a region does overlap but fully contains
-     * the page]. The [bracketed] text pertains to the #if 0'd code below, state D. TODO modify this
-     * note if someone decides to enable this optimization. It can be tested with the SeaStar
-     * mapping.
-     *
-     * Examples: (CAPS regions are returned by v3_get_next_mem_region; state A returns the base reg)
-     *
-     *    |region| |region|                               2MiB mapped (state A)
-     *                   |reg|          |REG|             2MiB mapped (state B)
-     *   |region|     |reg|   |REG| |region|   |reg|      4KiB mapped (state C)
-     *        |reg|  |reg|   |--REGION---|                [2MiB mapped (state D)]
-     * |--------------------------------------------|     RAM
-     *                             ^                      fault addr
-     * |----|----|----|----|----|page|----|----|----|     2MB pages
-     *                           >>>>>>>>>>>>>>>>>>>>     search space
-     */
-    addr_t pg_start = 0UL, pg_end = 0UL; // 2MiB page containing the faulting address
-    struct v3_mem_region * pg_next_reg = NULL; // next immediate mem reg after page start addr
-    bool use_large_page = false;
+    struct v3_mem_region * region =  v3_get_mem_region(core->vm_info, core->cpu_id, fault_addr);
+    int page_size = PAGE_SIZE_4KB;
 
     if (region == NULL) {
        PrintError("%s: invalid region, addr=%p\n", __FUNCTION__, (void *)fault_addr);
        return -1;
     }
 
-    // set use_large_page here
-    if (info->vm_info->paging_size == PAGING_2MB) {
-
-       // guest page maps to a host page + offset (so when we shift, it aligns with a host page)
-       pg_start = PAGE_ADDR_2MB(fault_addr);
-       pg_end = (pg_start + PAGE_SIZE_2MB);
-
-       PrintDebug("%s: page   [%p,%p) contains address\n", __FUNCTION__, (void *)pg_start, (void *)pg_end);
-
-       pg_next_reg = v3_get_next_mem_region(info->vm_info, info->cpu_id, pg_start);
-
-       if (pg_next_reg == NULL) {
-           PrintError("%s: Error: address not in base region, %p\n", __FUNCTION__, (void *)fault_addr);
-           return -1;
-       }
-
-       if ((pg_next_reg->guest_start == base_reg->guest_start) &&
-               (pg_next_reg->guest_end == base_reg->guest_end)) { // next region == base region
-           use_large_page = 1; // State A
-       } else {
-#if 0       // State B/C and D optimization
-           use_large_page = (pg_next_reg->guest_end >= pg_end) &&
-               ((pg_next_reg->guest_start >= pg_end) || (pg_next_reg->guest_start <= pg_start));
-           PrintDebug("%s: region [%p,%p) %s partial overlap with page\n", __FUNCTION__,
-                   (void *)pg_next_reg->guest_start, (void *)pg_next_reg->guest_end,
-                   (use_large_page ? "does not have" : "has"));
-#else       // State B/C
-           use_large_page = (pg_next_reg->guest_start >= pg_end);
-           PrintDebug("%s: region [%p,%p) %s overlap with page\n", __FUNCTION__,
-                   (void *)pg_next_reg->guest_start, (void *)pg_next_reg->guest_end,
-                   (use_large_page ? "does not have" : "has"));
-#endif
-       }
+    /*  Check if:
+     *  1. the guest is configured to use large pages and 
+     *         2. the memory regions can be referenced by a large page
+     */
+    if ((core->use_large_pages == 1) ) {
+       page_size = v3_get_max_page_size(core, fault_addr, PAGE_SIZE_2MB);
     }
 
-    PrintDebug("%s: Address gets a 2MiB page? %s\n", __FUNCTION__, (use_large_page ? "yes" : "no"));
+    PrintDebug("Using page size of %dKB\n", page_size / 1024);
 
     // Lookup the correct PML address based on the PAGING MODE
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
-       pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3);
+    if (core->shdw_pg_mode == SHADOW_PAGING) {
+       pml = CR3_TO_PML4E64_VA(core->ctrl_regs.cr3);
     } else {
-       pml = CR3_TO_PML4E64_VA(info->direct_map_pt);
+       pml = CR3_TO_PML4E64_VA(core->direct_map_pt);
     }
 
     //Fix up the PML entry
@@ -128,7 +77,7 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
         pml[pml_index].writable = 1;
         pml[pml_index].user_page = 1;
 
-       pml[pml_index].pdp_base_addr = PAGE_BASE_ADDR_4KB((addr_t)V3_PAddr(pdpe));
+       pml[pml_index].pdp_base_addr = PAGE_BASE_ADDR_4KB((addr_t)V3_PAddr(pdpe));    
     } else {
        pdpe = V3_VAddr((void*)BASE_TO_PAGE_ADDR_4KB(pml[pml_index].pdp_base_addr));
     }
@@ -142,21 +91,21 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
        pdpe[pdpe_index].writable = 1;
        pdpe[pdpe_index].user_page = 1;
 
-       pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR_4KB((addr_t)V3_PAddr(pde));
+       pdpe[pdpe_index].pd_base_addr = PAGE_BASE_ADDR_4KB((addr_t)V3_PAddr(pde));    
     } else {
        pde = V3_VAddr((void*)BASE_TO_PAGE_ADDR_4KB(pdpe[pdpe_index].pd_base_addr));
     }
 
     // Fix up the 2MiB PDE and exit here
-    if (use_large_page) {
-
+    if (page_size == PAGE_SIZE_2MB) {
        pde2mb = (pde64_2MB_t *)pde; // all but these two lines are the same for PTE
        pde2mb[pde_index].large_page = 1;
 
        if (pde2mb[pde_index].present == 0) {
            pde2mb[pde_index].user_page = 1;
 
-           if ((region->flags.alloced == 1) && (region->flags.read == 1)) {
+           if ( (region->flags.alloced == 1) && 
+                (region->flags.read == 1)) {
                // Full access
                pde2mb[pde_index].present = 1;
 
@@ -166,25 +115,28 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
                    pde2mb[pde_index].writable = 0;
                }
 
-               if (v3_gpa_to_hpa(info, fault_addr, &host_addr) == -1) {
+               if (v3_gpa_to_hpa(core, fault_addr, &host_addr) == -1) {
                    PrintError("Error Could not translate fault addr (%p)\n", (void *)fault_addr);
                    return -1;
                }
 
                pde2mb[pde_index].page_base_addr = PAGE_BASE_ADDR_2MB(host_addr);
            } else {
-               return region->unhandled(info, fault_addr, fault_addr, region, error_code);
+               return region->unhandled(core, fault_addr, fault_addr, region, error_code);
            }
        } else {
-           // We fix all permissions on the first pass,
+           // We fix all permissions on the first pass, 
            // so we only get here if its an unhandled exception
 
-           return region->unhandled(info, fault_addr, fault_addr, region, error_code);
+           return region->unhandled(core, fault_addr, fault_addr, region, error_code);
        }
-    }
 
-    // Continue with the 4KiB page heirarchy
+       // All done
+       return 0;
+    } 
 
+    // Continue with the 4KiB page heirarchy
+    
     // Fix up the PDE entry
     if (pde[pde_index].present == 0) {
        pte = (pte64_t *)create_generic_pt_page();
@@ -198,7 +150,6 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
        pte = V3_VAddr((void*)BASE_TO_PAGE_ADDR_4KB(pde[pde_index].pt_base_addr));
     }
 
-
     // Fix up the PTE entry
     if (pte[pte_index].present == 0) {
        pte[pte_index].user_page = 1;
@@ -214,26 +165,26 @@ static inline int handle_passthrough_pagefault_64(struct guest_info * info,
                pte[pte_index].writable = 0;
            }
 
-           if (v3_gpa_to_hpa(info, fault_addr, &host_addr) == -1) {
+           if (v3_gpa_to_hpa(core, fault_addr, &host_addr) == -1) {
                PrintError("Error Could not translate fault addr (%p)\n", (void *)fault_addr);
                return -1;
            }
 
            pte[pte_index].page_base_addr = PAGE_BASE_ADDR_4KB(host_addr);
        } else {
-           return region->unhandled(info, fault_addr, fault_addr, region, error_code);
+           return region->unhandled(core, fault_addr, fault_addr, region, error_code);
        }
     } else {
        // We fix all permissions on the first pass, 
        // so we only get here if its an unhandled exception
 
-       return region->unhandled(info, fault_addr, fault_addr, region, error_code);
+       return region->unhandled(core, fault_addr, fault_addr, region, error_code);
     }
 
     return 0;
 }
 
-static inline int invalidate_addr_64(struct guest_info * info, addr_t inv_addr) {
+static inline int invalidate_addr_64(struct guest_info * core, addr_t inv_addr) {
     pml4e64_t * pml = NULL;
     pdpe64_t * pdpe = NULL;
     pde64_t * pde = NULL;
@@ -251,10 +202,10 @@ static inline int invalidate_addr_64(struct guest_info * info, addr_t inv_addr)
 
     
     // Lookup the correct PDE address based on the PAGING MODE
-    if (info->shdw_pg_mode == SHADOW_PAGING) {
-       pml = CR3_TO_PML4E64_VA(info->ctrl_regs.cr3);
+    if (core->shdw_pg_mode == SHADOW_PAGING) {
+       pml = CR3_TO_PML4E64_VA(core->ctrl_regs.cr3);
     } else {
-       pml = CR3_TO_PML4E64_VA(info->direct_map_pt);
+       pml = CR3_TO_PML4E64_VA(core->direct_map_pt);
     }
 
     if (pml[pml_index].present == 0) {
diff --git a/palacios/src/palacios/vmm_file.c b/palacios/src/palacios/vmm_file.c
new file mode 100644 (file)
index 0000000..ada9972
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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) 2010, Peter Dinda <pdinda@northwestern.edu> 
+ * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org> 
+ * All rights reserved.
+ *
+ * Author: Peter Dinda <pdinda@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_file.h>
+#include <palacios/vmm.h>
+#include <palacios/vmm_debug.h>
+#include <palacios/vmm_types.h>
+
+
+struct v3_file_hooks * file_hooks = 0;
+
+void V3_Init_File(struct v3_file_hooks * hooks) {
+    file_hooks = hooks;
+    PrintDebug("V3 file access inited\n");
+
+    return;
+}
index 89fd64f..7994cc4 100644 (file)
@@ -50,8 +50,6 @@ static int unhandled_err(struct guest_info * core, addr_t guest_va, addr_t guest
     return -1;
 }
 
-
-
 int v3_init_mem_map(struct v3_vm_info * vm) {
     struct v3_mem_map * map = &(vm->mem_map);
     addr_t mem_pages = vm->mem_size >> 12;
@@ -60,14 +58,18 @@ int v3_init_mem_map(struct v3_vm_info * vm) {
 
     map->mem_regions.rb_node = NULL;
 
-
     // There is an underlying region that contains all of the guest memory
     // PrintDebug("Mapping %d pages of memory (%u bytes)\n", (int)mem_pages, (uint_t)info->mem_size);
 
     // 2MB page alignment needed for 2MB hardware nested paging
     map->base_region.guest_start = 0;
     map->base_region.guest_end = mem_pages * PAGE_SIZE_4KB;
-    map->base_region.host_addr = (addr_t)V3_AllocAlignedPages(mem_pages, PAGE_SIZE_2MB);
+
+#ifdef CONFIG_ALIGNED_PG_ALLOC
+    map->base_region.host_addr = (addr_t)V3_AllocAlignedPages(mem_pages, vm->mem_align);
+#else
+    map->base_region.host_addr = (addr_t)V3_AllocPages(mem_pages);
+#endif
 
     map->base_region.flags.read = 1;
     map->base_region.flags.write = 1;
@@ -289,30 +291,38 @@ struct v3_mem_region * v3_get_mem_region(struct v3_vm_info * vm, uint16_t core_i
 
 
 
-/* Search the "hooked" memory regions for a region that ends after the given address.  If the
- * address is invalid, return NULL. Else, return the first region found or the base region if no
- * region ends after the given address.
+/* Given an address, find the successor region. If the address is within a region, return that
+ * region. Input is an address, because the address may not have a region associated with it.
+ *
+ * Returns a region following or touching the given address. If address is invalid, NULL is
+ * returned, else the base region is returned if no region exists at or after the given address.
  */
 struct v3_mem_region * v3_get_next_mem_region( struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr) {
-    struct rb_node * n = vm->mem_map.mem_regions.rb_node;
-    struct v3_mem_region * reg = NULL;
-
-    // Keep going to the right in the tree while the address is greater than the current region's
-    // end address.
-    while (n) {
-        reg = rb_entry(n, struct v3_mem_region, tree_node);
-        if (guest_addr >= reg->guest_end) { // reg is [start,end)
-            n = n->rb_right;
-        } else {
-           if ((core_id == reg->core_id) || (reg->core_id == V3_MEM_CORE_ANY)) {
-               return reg;
-           } else {
-               n = n->rb_right;
+    struct rb_node * current_n         = vm->mem_map.mem_regions.rb_node;
+    struct rb_node * successor_n       = NULL; /* left-most node greater than guest_addr */
+    struct v3_mem_region * current_r   = NULL;
+
+    /* current_n tries to find the region containing guest_addr, going right when smaller and left when
+     * greater. Each time current_n becomes greater than guest_addr, update successor <- current_n.
+     * current_n becomes successively closer to guest_addr than the previous time it was greater
+     * than guest_addr.
+     */
+
+    /* | is address, ---- is region, + is intersection */
+    while (current_n) {
+        current_r = rb_entry(current_n, struct v3_mem_region, tree_node);
+       if (current_r->guest_start > guest_addr) { /* | ---- */
+           successor_n = current_n;
+           current_n = current_n->rb_left;
+       } else {
+           if (current_r->guest_end > guest_addr) {
+               return current_r; /* +--- or --+- */
            }
-        }
+           current_n = current_n->rb_right; /* ---- | */
+       }
     }
 
-    // There is no registered region, so we check if it's a valid address in the base region
+    /* Address does not have its own region. Check if it's a valid address in the base region */
 
     if (guest_addr >= vm->mem_map.base_region.guest_end) {
        PrintError("%s: Guest Address Exceeds Base Memory Size (ga=%p), (limit=%p)\n",
@@ -376,7 +386,111 @@ void v3_delete_mem_region(struct v3_vm_info * vm, struct v3_mem_region * reg) {
 
 }
 
+// Determine if a given address can be handled by a large page of the requested size
+uint32_t v3_get_max_page_size(struct guest_info * core, addr_t fault_addr, uint32_t req_size) {
+    addr_t pg_start = 0UL, pg_end = 0UL; // large page containing the faulting addres
+    struct v3_mem_region * pg_next_reg = NULL; // next immediate mem reg after page start addr
+    uint32_t page_size = PAGE_SIZE_4KB;
+
+   /* If the guest has been configured for large pages, then we must check for hooked regions of
+     * memory which may overlap with the large page containing the faulting address (due to
+     * potentially differing access policies in place for e.g. i/o devices and APIC). A large page
+     * can be used if a) no region overlaps the page [or b) a region does overlap but fully contains
+     * the page]. The [bracketed] text pertains to the #if 0'd code below, state D. TODO modify this
+     * note if someone decides to enable this optimization. It can be tested with the SeaStar
+     * mapping.
+     *
+     * Examples: (CAPS regions are returned by v3_get_next_mem_region; state A returns the base reg)
+     *
+     *    |region| |region|                               2MiB mapped (state A)
+     *                   |reg|          |REG|             2MiB mapped (state B)
+     *   |region|     |reg|   |REG| |region|   |reg|      4KiB mapped (state C)
+     *        |reg|  |reg|   |--REGION---|                [2MiB mapped (state D)]
+     * |--------------------------------------------|     RAM
+     *                             ^                      fault addr
+     * |----|----|----|----|----|page|----|----|----|     2MB pages
+     *                           >>>>>>>>>>>>>>>>>>>>     search space
+     */
+
+
+    // guest page maps to a host page + offset (so when we shift, it aligns with a host page)
+    switch (req_size) {
+       case PAGE_SIZE_4KB:
+               return PAGE_SIZE_4KB;
+       case PAGE_SIZE_2MB:
+               pg_start = PAGE_ADDR_2MB(fault_addr);
+               pg_end = (pg_start + PAGE_SIZE_2MB);
+               break;
+       case PAGE_SIZE_4MB:
+               pg_start = PAGE_ADDR_4MB(fault_addr);
+               pg_end = (pg_start + PAGE_SIZE_4MB);
+               break;
+       case PAGE_SIZE_1GB:
+               pg_start = PAGE_ADDR_1GB(fault_addr);
+               pg_end = (pg_start + PAGE_SIZE_1GB);
+               break;
+       default:
+               PrintError("Invalid large page size requested.\n");
+               return -1;
+    }
+
+    //PrintDebug("%s: page   [%p,%p) contains address\n", __FUNCTION__, (void *)pg_start, (void *)pg_end);
+
+    pg_next_reg = v3_get_next_mem_region(core->vm_info, core->cpu_id, pg_start);
 
+    if (pg_next_reg == NULL) {
+       PrintError("%s: Error: address not in base region, %p\n", __FUNCTION__, (void *)fault_addr);
+       return PAGE_SIZE_4KB;
+    }
+
+    if (pg_next_reg->flags.base == 1) {
+       page_size = req_size; // State A
+       //PrintDebug("%s: base region [%p,%p) contains page.\n", __FUNCTION__,
+       //         (void *)pg_next_reg->guest_start, (void *)pg_next_reg->guest_end);
+    } else {
+#if 0       // State B/C and D optimization
+       if ((pg_next_reg->guest_end >= pg_end) &&
+           ((pg_next_reg->guest_start >= pg_end) || (pg_next_reg->guest_start <= pg_start))) {     
+           page_size = req_size;
+       }
+
+       PrintDebug("%s: region [%p,%p) %s partially overlap with page\n", __FUNCTION__,
+                  (void *)pg_next_reg->guest_start, (void *)pg_next_reg->guest_end, 
+                  (page_size == req_size) ? "does not" : "does");
+
+#else       // State B/C
+       if (pg_next_reg->guest_start >= pg_end) {
+           
+           page_size = req_size;
+       }
+
+       PrintDebug("%s: region [%p,%p) %s overlap with page\n", __FUNCTION__,
+                  (void *)pg_next_reg->guest_start, (void *)pg_next_reg->guest_end,
+                  (page_size == req_size) ? "does not" : "does");
+
+#endif
+    }
+
+    return page_size;
+}
+
+// For an address on a page of size page_size, compute the actual alignment
+// of the physical page it maps to
+uint32_t v3_compute_page_alignment(addr_t page_addr)
+{
+    if (PAGE_OFFSET_1GB(page_addr) == 0) {
+        return PAGE_SIZE_1GB;
+    } else if (PAGE_OFFSET_4MB(page_addr) == 0) {
+        return PAGE_SIZE_4MB;
+    } else if (PAGE_OFFSET_2MB(page_addr) == 0) {
+       return PAGE_SIZE_2MB;
+    } else if (PAGE_OFFSET_4KB(page_addr) == 0) {
+       return PAGE_SIZE_4KB;
+    } else {
+        PrintError("Non-page aligned address passed to %s.\n", __FUNCTION__);
+       return 0;
+    }
+}
 
 void v3_print_mem_map(struct v3_vm_info * vm) {
     struct rb_node * node = v3_rb_first(&(vm->mem_map.mem_regions));
index 13f57aa..d7455ac 100644 (file)
@@ -61,15 +61,15 @@ struct bridge_pkts_buf {
     int num; 
     v3_lock_t lock;
     struct v3_vnet_pkt pkts[BRIDGE_BUF_SIZE];
-    uint8_t datas[ETHERNET_PACKET_LEN*BRIDGE_BUF_SIZE];
+    uint8_t datas[ETHERNET_PACKET_LEN * BRIDGE_BUF_SIZE];
 };
 
 struct vnet_brg_dev {
     struct v3_vm_info * vm;
     
     int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt pkt[], uint16_t pkt_num, void * private_data);
-    void (*xcall_input)(void *data);
-    int (*polling_pkt)(struct v3_vm_info * vm,  void *private_data);
+    void (*xcall_input)(void * data);
+    int (*polling_pkt)(struct v3_vm_info * vm,  void * private_data);
 
     int disabled;
        
@@ -109,7 +109,7 @@ static struct {
     int num_routes;
     int num_devs;
 
-    struct vnet_brg_dev *bridge;
+    struct vnet_brg_dev * bridge;
 
     v3_lock_t lock;
 
@@ -122,46 +122,53 @@ static struct {
 
 
 #ifdef CONFIG_DEBUG_VNET
-static inline void mac_to_string(char mac[6], char * buf) {
+static inline void mac_to_string(uint8_t mac[6], char * buf) {
     snprintf(buf, 100, "%d:%d:%d:%d:%d:%d", 
             mac[0], mac[1], mac[2],
             mac[3], mac[4], mac[5]);
 }
 
-static void print_route(struct vnet_route_info *route){
+static void print_route(struct vnet_route_info * route){
     char str[50];
 
+    memset(str, 0, 50);
+
     mac_to_string(route->route_def.src_mac, str);
     PrintDebug("Src Mac (%s),  src_qual (%d)\n", 
                        str, route->route_def.src_mac_qual);
+
     mac_to_string(route->route_def.dst_mac, str);
     PrintDebug("Dst Mac (%s),  dst_qual (%d)\n", 
                        str, route->route_def.dst_mac_qual);
+
     PrintDebug("Src dev id (%d), src type (%d)", 
                        route->route_def.src_id, 
                        route->route_def.src_type);
+
     PrintDebug("Dst dev id (%d), dst type (%d)\n", 
                        route->route_def.dst_id, 
                        route->route_def.dst_type);
+
     if (route->route_def.dst_type == LINK_INTERFACE) {
        PrintDebug("dst_dev (%p), dst_dev_id (%d), dst_dev_input (%p), dst_dev_data (%p)\n",
-                                       route->dst_dev,
-                                       route->dst_dev->dev_id,
-                                       route->dst_dev->input,
-                                       route->dst_dev->private_data);
+                  route->dst_dev,
+                  route->dst_dev->dev_id,
+                  route->dst_dev->input,
+                  route->dst_dev->private_data);
     }
 }
 
-static void dump_routes(){
-       struct vnet_route_info *route;
-
+static void dump_routes() {
+       struct vnet_route_info * route = NULL;
        int i = 0;
+
        PrintDebug("\n========Dump routes starts ============\n");
+
        list_for_each_entry(route, &(vnet_state.routes), node) {
-               PrintDebug("\nroute %d:\n", ++i);
-               
+               PrintDebug("\nroute %d:\n", i++);
                print_route(route);
        }
+
        PrintDebug("\n========Dump routes end ============\n");
 }
 
@@ -215,8 +222,9 @@ static struct vnet_dev * find_dev_by_id(int idx) {
     list_for_each_entry(dev, &(vnet_state.devs), node) {
        int dev_id = dev->dev_id;
 
-       if (dev_id == idx)
+       if (dev_id == idx) {
            return dev;
+       }
     }
 
     return NULL;
@@ -226,27 +234,28 @@ static struct vnet_dev * find_dev_by_mac(char mac[6]) {
     struct vnet_dev * dev = NULL; 
     
     list_for_each_entry(dev, &(vnet_state.devs), node) {
-       if (!memcmp(dev->mac_addr, mac, 6))
+       if (memcmp(dev->mac_addr, mac, 6) == 0) {
            return dev;
+       }
     }
 
     return NULL;
 }
 
-int get_device_id_by_mac(char mac[6]){
-
-    struct vnet_dev *dev = find_dev_by_mac(mac);
-
-    if (dev == NULL)
+int get_device_id_by_mac(char mac[6]) {
+    struct vnet_dev * dev = find_dev_by_mac(mac);
+    
+    if (dev == NULL) {
        return -1;
-
+    }
+    
     return dev->dev_id;
 }
 
 
 int v3_vnet_add_route(struct v3_vnet_route route) {
     struct vnet_route_info * new_route = NULL;
-    unsigned long flags; 
+    uint32_t flags = 0; 
 
     new_route = (struct vnet_route_info *)V3_Malloc(sizeof(struct vnet_route_info));
     memset(new_route, 0, sizeof(struct vnet_route_info));
@@ -418,8 +427,10 @@ static struct route_list * match_route(const struct v3_vnet_pkt * pkt) {
 
 #if 0
 static int flush_bridge_pkts(struct vnet_brg_dev *bridge){
-    unsigned long flags;
-    int num, start, send;
+    uint32_t flags;
+    int num;
+    int start;
+    int send;
     struct v3_vnet_bridge_input_args args;
     int cpu_id = bridge->vm->cores[0].cpu_id;
     int current_core = V3_Get_CPU();
@@ -441,34 +452,34 @@ static int flush_bridge_pkts(struct vnet_brg_dev *bridge){
     v3_unlock_irqrestore(bridge->recv_buf.lock, flags);
 
 
-    if(bridge->disabled){
+    if (bridge->disabled) {
        PrintDebug("VNET: In flush bridge pkts: Bridge is disabled\n");
        return -1;
     }
 
-    if(num <= 2 && num > 0){
+    if (num <= 2 && num > 0) {
        PrintDebug("VNET: In flush bridge pkts: %d\n", num);
     }
 
-    if(num > 0) {
+    if (num > 0) {
        PrintDebug("VNET: In flush bridge pkts to bridge, cur_cpu %d, brige_core: %d\n", current_core, cpu_id);
-       if (current_core == cpu_id){
-           if ((start + num) < BRIDGE_BUF_SIZE){
+       if (current_core == cpu_id) {
+           if ((start + num) < BRIDGE_BUF_SIZE) { 
                bridge->input(bridge->vm, &(bridge->recv_buf.pkts[start]), num, bridge->private_data);
-           }else {
+           } else {
                bridge->input(bridge->vm, &(bridge->recv_buf.pkts[start]), (BRIDGE_BUF_SIZE - start), bridge->private_data);                            
                send = num - (BRIDGE_BUF_SIZE - start);
                bridge->input(bridge->vm, &(bridge->recv_buf.pkts[0]), send, bridge->private_data);
            }   
-       }else {
+       } else {
            args.vm = bridge->vm;
            args.private_data = bridge->private_data;
        
-           if ((start + num) < BRIDGE_BUF_SIZE){
+           if ((start + num) < BRIDGE_BUF_SIZE) {
                args.pkt_num = num;
                args.vnet_pkts = &(bridge->recv_buf.pkts[start]);
                V3_Call_On_CPU(cpu_id, bridge->xcall_input, (void *)&args);
-           }else {
+           } else {
                args.pkt_num = BRIDGE_BUF_SIZE - start;
                args.vnet_pkts = &(bridge->recv_buf.pkts[start]);
                V3_Call_On_CPU(cpu_id, bridge->xcall_input, (void *)&args);
@@ -488,96 +499,43 @@ static int flush_bridge_pkts(struct vnet_brg_dev *bridge){
 #endif
 
 static int send_to_bridge(struct v3_vnet_pkt * pkt){
-    struct vnet_brg_dev *bridge = vnet_state.bridge;
+    struct vnet_brg_dev * bridge = vnet_state.bridge;
 
     if (bridge == NULL) {
        PrintDebug("VNET: No bridge to sent data to links\n");
        return -1;
     }
 
-    if(bridge->max_delayed_pkts <= 1){
-       if(bridge->disabled){
+    if (bridge->max_delayed_pkts <= 1) {
+
+       if (bridge->disabled) {
            PrintDebug("VNET: Bridge diabled\n");
            return -1;
-      }
+       }
 
-/*
-       //avoid the cross-core call here
-       int cpu_id = bridge->vm->cores[0].cpu_id;
-       struct v3_vnet_bridge_input_args args;
-
-       args.pkt_num = 1;
-       args.vm = bridge->vm;
-       args.vnet_pkts = pkt;
-       args.private_data = bridge->private_data;
-       
-       V3_Call_On_CPU(cpu_id, bridge->xcall_input, (void *)&args);
-*/
        bridge->input(bridge->vm, pkt, 1, bridge->private_data);
 
        PrintDebug("VNET: sent one packet to the bridge\n");
-       return 0;
-    }
-
-/*
-    unsigned long flags;
-    int end, num=0;
-    struct v3_vnet_pkt *buf;
-
-    PrintDebug("VNET: send_to_bridge\n");
-
-    flags = v3_lock_irqsave(bridge->recv_buf.lock);
-
-    if(bridge->disabled && bridge->recv_buf.num >= BRIDGE_BUF_SIZE){
-       PrintDebug("Bridge diabled and bridge receive buffer full\n");
-       v3_unlock_irqrestore(bridge->recv_buf.lock, flags);//maybe should move this after copy
-       num = bridge->recv_buf.num;
-       goto exit;
     }
-           
-    end =      bridge->recv_buf.end;
-    buf = &(bridge->recv_buf.pkts[end]);
-
-    bridge->recv_buf.num ++;
-    bridge->recv_buf.end ++;
-    bridge->recv_buf.end %= BRIDGE_BUF_SIZE;
-
-    num = bridge->recv_buf.num;
-
-    v3_unlock_irqrestore(bridge->recv_buf.lock, flags);//maybe should move this after copy
 
 
-    buf->size = pkt->size;
-    buf->dst_id = pkt->dst_id;
-    buf->src_id = pkt->src_id;
-    buf->src_type = pkt->src_type;
-    buf->dst_type = pkt->dst_type;
-    memcpy(buf->header, pkt->header, ETHERNET_HEADER_LEN);
-    memcpy(buf->data, pkt->data, pkt->size);
-
-exit:  
-
-    if (num >= bridge->max_delayed_pkts){
-       flush_bridge_pkts(bridge);
-    }
-*/
     return 0;
 }
 
 int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
     struct route_list * matched_routes = NULL;
-    unsigned long flags;
-    int i;
-
+    uint32_t flags = 0;
+    int i = 0;
+    
 #ifdef CONFIG_DEBUG_VNET
-   {
+    {
        struct eth_hdr * hdr = (struct eth_hdr *)(pkt->header);
        char dest_str[100];
        char src_str[100];
-
+       int cpu = V3_Get_CPU();
+       
        mac_to_string(hdr->src_mac, src_str);  
        mac_to_string(hdr->dst_mac, dest_str);
-       int cpu = V3_Get_CPU();
        PrintDebug("Vnet: on cpu %d, HandleDataOverLink. SRC(%s), DEST(%s), pkt size: %d\n", cpu, src_str, dest_str, pkt->size);
    }
 #endif
@@ -632,17 +590,17 @@ int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
     return 0;
 }
 
-void v3_vnet_send_pkt_xcall(void * data){
+void v3_vnet_send_pkt_xcall(void * data) {
     struct v3_vnet_pkt * pkt = (struct v3_vnet_pkt *)data;
     v3_vnet_send_pkt(pkt, NULL);
 }
 
 
-void v3_vnet_polling()
-{
-    unsigned long flags;
-    int num, start;
-    struct v3_vnet_pkt *buf;
+void v3_vnet_polling() {
+    uint32_t flags = 0;
+    int num = 0;
+    int start = 0;
+    struct v3_vnet_pkt * buf = NULL;
 
     PrintDebug("In vnet pollling: cpu %d\n", V3_Get_CPU());
 
@@ -653,15 +611,15 @@ void v3_vnet_polling()
 
     PrintDebug("VNET: polling pkts %d\n", num);
 
-    while(num > 0) {
+    while (num > 0) {
        buf = &(vnet_state.in_buf.pkts[vnet_state.in_buf.start]);
 
        v3_vnet_send_pkt(buf, NULL);
 
-       vnet_state.in_buf.num --;
-       vnet_state.in_buf.start ++;
+       vnet_state.in_buf.num--;
+       vnet_state.in_buf.start++;
        vnet_state.in_buf.start %= BRIDGE_BUF_SIZE;
-       num --;
+       num--;
     }
 
     v3_unlock_irqrestore(vnet_state.in_buf.lock, flags);
@@ -670,23 +628,24 @@ void v3_vnet_polling()
 }
 
 
-int v3_vnet_rx(uchar_t *buf, uint16_t size, uint16_t src_id, uint8_t src_type){
-    unsigned long flags;
-    int end;
-    struct v3_vnet_pkt *pkt;
+int v3_vnet_rx(uint8_t * buf, uint16_t size, uint16_t src_id, uint8_t src_type) {
+    uint32_t flags = 0;
+    int end = 0;
+    struct v3_vnet_pkt * pkt = NULL;
    
     flags = v3_lock_irqsave(vnet_state.in_buf.lock);
            
     end = vnet_state.in_buf.end;
     pkt = &(vnet_state.in_buf.pkts[end]);
 
-    if(vnet_state.in_buf.num > BRIDGE_BUF_SIZE){
+    if (vnet_state.in_buf.num > BRIDGE_BUF_SIZE){
        PrintDebug("VNET: bridge rx: buffer full\n");
-       goto exit;
+       v3_unlock_irqrestore(vnet_state.in_buf.lock, flags);
+       return 0;
     }
 
-    vnet_state.in_buf.num ++;
-    vnet_state.in_buf.end ++;
+    vnet_state.in_buf.num++;
+    vnet_state.in_buf.end++;
     vnet_state.in_buf.end %= BRIDGE_BUF_SIZE;
 
     pkt->size = size;
@@ -695,7 +654,6 @@ int v3_vnet_rx(uchar_t *buf, uint16_t size, uint16_t src_id, uint8_t src_type){
     memcpy(pkt->header, buf, ETHERNET_HEADER_LEN);
     memcpy(pkt->data, buf, size);
 
-exit:
        
     v3_unlock_irqrestore(vnet_state.in_buf.lock, flags);
 
@@ -703,11 +661,11 @@ exit:
 }
        
 
-int v3_vnet_add_dev(struct v3_vm_info *vm, uint8_t mac[6], 
+int v3_vnet_add_dev(struct v3_vm_info * vm, uint8_t mac[6], 
                    int (*netif_input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * private_data), 
                    void * priv_data){
     struct vnet_dev * new_dev = NULL;
-    unsigned long flags;
+    uint32_t flags = 0;
 
     new_dev = (struct vnet_dev *)V3_Malloc(sizeof(struct vnet_dev)); 
 
@@ -738,17 +696,18 @@ int v3_vnet_add_dev(struct v3_vm_info *vm, uint8_t mac[6],
     }
 
     PrintDebug("Vnet: Add Device: dev_id %d, input : %p, private_data %p\n",
-                       new_dev->dev_id, new_dev->input, new_dev->private_data);
+              new_dev->dev_id, new_dev->input, new_dev->private_data);
 
     return new_dev->dev_id;
 }
 
 
-void  v3_vnet_heartbeat(struct guest_info *core){
+void v3_vnet_heartbeat(struct guest_info *core){
     //static long last_time, cur_time;
 
-    if(vnet_state.bridge == NULL)
+    if (vnet_state.bridge == NULL) {
        return;
+    }
 /*     
     if(vnet_state.bridge->max_delayed_pkts > 1){
        if(V3_Get_CPU() != vnet_state.bridge->vm->cores[0].cpu_id){
@@ -766,12 +725,13 @@ void  v3_vnet_heartbeat(struct guest_info *core){
 
 int v3_vnet_add_bridge(struct v3_vm_info * vm,
                       int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt pkt[], uint16_t pkt_num, void * private_data),
-                      void (*xcall_input)(void *data),
+                      void (*xcall_input)(void * data),
                       int (*poll_pkt)(struct v3_vm_info * vm, void * private_data),
                       uint16_t max_delayed_pkts,
                       long max_latency,
                       void * priv_data) {
-    unsigned long flags;
+
+    uint32_t flags = 0;
     int bridge_free = 0;
     struct vnet_brg_dev * tmp_bridge = NULL;    
     
@@ -819,7 +779,7 @@ int v3_vnet_add_bridge(struct v3_vm_info * vm,
 
 */
     
-    tmp_bridge->max_delayed_pkts = (max_delayed_pkts<BRIDGE_BUF_SIZE)?max_delayed_pkts : BRIDGE_BUF_SIZE;
+    tmp_bridge->max_delayed_pkts = (max_delayed_pkts < BRIDGE_BUF_SIZE) ? max_delayed_pkts : BRIDGE_BUF_SIZE;
     tmp_bridge->max_latency = max_latency;
        
     // make this atomic to avoid possible race conditions
@@ -832,7 +792,7 @@ int v3_vnet_add_bridge(struct v3_vm_info * vm,
 
 
 int v3_vnet_disable_bridge() {
-    unsigned long flags; 
+    uint32_t flags = 0; 
     
     flags = v3_lock_irqsave(vnet_state.lock);
 
@@ -847,7 +807,7 @@ int v3_vnet_disable_bridge() {
 
 
 int v3_vnet_enable_bridge() {
-    unsigned long flags; 
+    uint32_t flags = 0;
     
     flags = v3_lock_irqsave(vnet_state.lock);
 
@@ -863,7 +823,7 @@ int v3_vnet_enable_bridge() {
 
 
 int V3_init_vnet() {
-    int i;
+    int i = 0;
 
     memset(&vnet_state, 0, sizeof(vnet_state));
        
@@ -885,12 +845,15 @@ int V3_init_vnet() {
     vnet_state.in_buf.start = 0;
     vnet_state.in_buf.end = 0;
     vnet_state.in_buf.num = 0;
-    if(v3_lock_init(&(vnet_state.in_buf.lock)) == -1){
+
+    if (v3_lock_init(&(vnet_state.in_buf.lock)) == -1){
        PrintError("VNET: add bridge, error to initiate send buf lock\n");
     }
-    for(i = 0; i<BRIDGE_BUF_SIZE; i++){
-       vnet_state.in_buf.pkts[i].data = &(vnet_state.in_buf.datas[i*ETHERNET_PACKET_LEN]);
+
+    for (i = 0; i < BRIDGE_BUF_SIZE; i++){
+       vnet_state.in_buf.pkts[i].data = &(vnet_state.in_buf.datas[i * ETHERNET_PACKET_LEN]);
     }
+
     PrintDebug("VNET: Receiving buffer initiated\n");
 
     vnet_state.route_cache = v3_create_htable(0, &hash_fn, &hash_eq);
index 4880f45..d836ad2 100644 (file)
 #include <palacios/vm_guest_mem.h>
 #include <palacios/vmx.h>
 
+#ifndef CONFIG_DEBUG_VMX
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
 static void vmx_save_world_ctx(struct guest_info * info, struct vmx_assist_context * ctx);
 static void vmx_restore_world_ctx(struct guest_info * info, struct vmx_assist_context * ctx);
 
index eb12760..afa0fb8 100644 (file)
 #include <palacios/vmm_direct_paging.h>
 #include <palacios/vmm_ctrl_regs.h>
 
+#ifndef CONFIG_DEBUG_VMX
+#undef PrintDebug
+#define PrintDebug(fmt, args...)
+#endif
+
 static v3_reg_t * get_reg_ptr(struct guest_info * info, struct vmx_exit_cr_qual * cr_qual);
 static int handle_mov_to_cr0(struct guest_info * info, v3_reg_t * new_val, struct vmx_exit_info * exit_info);
 static int handle_mov_to_cr3(struct guest_info * info, v3_reg_t * cr3_reg);
index b1727ac..4327985 100644 (file)
@@ -3,16 +3,17 @@
 <vm class="PC"> 
 
        <!-- Memory in MB -->
-       <memory>256</memory> 
+       <memory alignment="2MB">256</memory> 
 
        <!-- Basic VMM system flags -->
        <telemetry>enable</telemetry>
        <paging mode="shadow">
                <strategy>VTLB</strategy>
+               <large_pages>true</large_pages>
        </paging>
 <!--
        <paging mode="nested">
-               <page_size>2MB</page_size>
+               <large_pages>true<large_pages/>
        </paging>
 -->
        <schedule_hz>100</schedule_hz>
 
 
        <!-- List of devices attached to guest -->
-       <!-- The device 'ID' is the device name in the global device registry -->
-       <!-- The device 'name' is the reference to the device instance associated with a VM -->
+       <!-- The device 'class' is the device name in the global device registry -->
+       <!-- The device 'id' is the reference to the device instance associated with a VM -->
        <!--    The name can be used as a reference by other devices -->
        <devices>
-               <device id="8259A" name="PIC"/>
-               <device id="KEYBOARD" name="keyboard"/>
-               <device id="8254_PIT" name="PIT" />
-               <device id="BOCHS_DEBUG" name="bochs debug"/>
-               <device id="OS_DEBUG" name="os debug" />
-               <device id="ICC_BUS" name="icc"/>
-               <device id="LAPIC" name="apic">
+               <device class="8259A" id="PIC"/>
+               <device class="KEYBOARD" id="keyboard"/>
+               <device class="8254_PIT" id="PIT" />
+               <device class="BOCHS_DEBUG" id="bochs debug"/>
+               <device class="OS_DEBUG" id="os debug" />
+
+
+<!--
+               <device class="ICC_BUS" id="icc"/>
+               <device class="LAPIC" id="apic">
                        <bus>icc</bus>
                </device>
-               <device id="IOAPIC" name="ioapic">
+               <device class="IOAPIC" id="ioapic">
                        <bus>icc</bus>
                </device>
-
+-->
 <!--
-               <device id="CGA_VIDEO" name="cga" passthrough="enable" />
-               <device id="TELNET_CONSOLE" name="telnet console">
+               <device class="CGA_VIDEO" id="cga" passthrough="enable" />
+               <device class="TELNET_CONSOLE" id="telnet console">
                        <frontend tag="CGA_VIDEO" />
                        <port>19997</port>
                </device>
 -->
-               <device id="PCI" name="pci0" />
+               <device class="PCI" id="pci0" />
 
-               <device id="i440FX" name="northbridge">
+               <device class="i440FX" id="northbridge">
                        <bus>pci0</bus>
                </device>
 
-               <device id="PIIX3" name="southbridge">
+               <device class="PIIX3" id="southbridge">
                        <bus>pci0</bus>
                </device>
 
-               <device id="IDE" name="ide">
+               <device class="IDE" id="ide">
                        <bus>pci0</bus>
                        <controller>southbridge</controller>
                </device>
 
 
 <!--
-               <device id="LNX_VIRTIO_SYM" name="sym_pci">
+               <device class="LNX_VIRTIO_SYM" id="sym_pci">
                        <bus>pci0</bus>
                </device>
 
-               <device id="LNX_VIRTIO_BLK" name="blk_virtio">
+               <device class="LNX_VIRTIO_BLK" id="blk_virtio">
                        <bus>pci0</bus>
                </device>
 
-               <device id="LNX_VIRTIO_BALLOON" name="balloon">
+               <device class="LNX_VIRTIO_BALLOON" id="balloon">
                        <bus>pci0</bus>
                </device>
 
-               <device id="PCI_PASSTHROUGH" name="e1000">
+               <device class="PCI_PASSTHROUGH" id="e1000">
                        <bus>pci0</bus>
                        <vendor_id>0x8086</vendor_id>
                        <device_id>0x100e</device_id>
                        <irq>59</irq>
                </device>
 
-               <device id="PCI_PASSTHROUGH" name="e1000-hw">
+               <device class="PCI_PASSTHROUGH" id="e1000-hw">
                        <bus>pci0</bus>
                        <vendor_id>0x8086</vendor_id>
                        <device_id>0x107c</device_id>
                <!-- This is a Storage Backend that connects to a frontend -->
                <!-- The frontend section is passed to the frontend when the backend connects -->
                <!-- The file tag refers to an 'id' already listed in the file list section above -->
-               <device id="RAMDISK" name="CD0">
+               <device class="RAMDISK" id="CD0">
                        <file>boot-cd</file>
                        <frontend tag="ide">
                                <model>V3Vee CDROM</model>
 
 
 <!---
-               <device id="SYM_SWAP" name="sym swap">
+               <device class="SYM_SWAP" id="sym swap">
                        <frontend tag="blk_virtio" />
                        <size>150</size>
                </device>
 
-               <device id="RAMDISK" name="HD0">
+               <device class="RAMDISK" id="HD0">
                        <file>harddisk</file>
                        <frontend tag="blk_virtio" />
                </device>
 -->
 
-               <device id="NVRAM" name="nvram">
+               <device class="NVRAM" id="nvram">
                        <storage>ide</storage>
                </device>
 
-               <device id="GENERIC" name="generic">
+               <device class="GENERIC" id="generic">
                        <ports>
                                <start>0x00</start>
                                <end>0x07</end>