From: Jack Lange Date: Tue, 1 Dec 2009 01:04:44 +0000 (-0600) Subject: integrated new configuration system X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=123a1ba27ea09c8fa77a1b36ce625b43d7c48b14 integrated new configuration system --- diff --git a/Kconfig b/Kconfig index 1b7c7b7..c6446e5 100644 --- a/Kconfig +++ b/Kconfig @@ -166,6 +166,14 @@ config BUILT_IN_STRCMP help This enables Palacios' internal implementation of strcmp + +config BUILT_IN_STRCASECMP + bool "strcasecmp()" + default n + depends on BUILT_IN_STDLIB + help + This enables Palacios' internal implementation of strcasecmp + config BUILT_IN_STRNCMP bool "strncmp()" default n @@ -173,6 +181,14 @@ config BUILT_IN_STRNCMP help This enables Palacios' internal implementation of strncmp +config BUILT_IN_STRNCASECMP + bool "strncasecmp()" + default n + depends on BUILT_IN_STDLIB + help + This enables Palacios' internal implementation of strncasecmp + + config BUILT_IN_STRCAT bool "strcat()" default n diff --git a/palacios/include/devices/block_dev.h b/palacios/include/devices/block_dev.h deleted file mode 100644 index 574c5af..0000000 --- a/palacios/include/devices/block_dev.h +++ /dev/null @@ -1,66 +0,0 @@ - -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_BLOCK_DEV_H__ -#define __DEVICES_BLOCK_DEV_H__ - -#ifdef __V3VEE__ - - - -#define ATAPI_BLOCK_SIZE 2048 -#define HD_SECTOR_SIZE 512 - - -struct v3_hd_ops { - uint64_t (*get_capacity)(void * private_data); - // Reads always operate on 2048 byte blocks - int (*read)(uint8_t * buf, int sector_count, uint64_t lba, void * private_data); - int (*write)(uint8_t * buf, int sector_count, uint64_t lba, void * private_data); -}; - - - -struct v3_cd_ops { - uint32_t (*get_capacity)(void * private_data); - // Reads always operate on 2048 byte blocks - int (*read)(uint8_t * buf, int block_count, uint64_t lba, void * private_data); -}; - - -typedef enum {BLOCK_NONE, BLOCK_DISK, BLOCK_CDROM} v3_block_type_t; - - - -static const char * block_dev_type_strs[] = {"NONE", "HARDDISK", "CDROM" }; - -static inline const char * v3_block_type_to_str(v3_block_type_t type) { - if (type > BLOCK_CDROM) { - return NULL; - } - return block_dev_type_strs[type]; -} - - - -#endif - - -#endif diff --git a/palacios/include/devices/cga.h b/palacios/include/devices/cga.h deleted file mode 100644 index b2c168c..0000000 --- a/palacios/include/devices/cga.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_CGA_H__ -#define __DEVICES_CGA_H__ - -#ifdef __V3VEE__ - -#include - - -int v3_console_register_cga(struct vm_device * cga_dev, struct v3_console_ops * ops, void * private_data); - -#endif - -#endif diff --git a/palacios/include/devices/generic.h b/palacios/include/devices/generic.h deleted file mode 100644 index 77d3822..0000000 --- a/palacios/include/devices/generic.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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, Peter Dinda - * Copyright (c) 2008, Jack Lange - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Peter Dinda - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - - -#ifndef __DEVICES_GENERIC_H__ -#define __DEVICES_GENERIC_H__ - -#ifdef __V3VEE__ - -#include - - -// -// The generic device simply hooks ranges of ports, addresses, and irqs -// if they are not already hooked -// -// for each hooked port, it simply executes reads and writes and the same physical port, -// for each hooked memory range, it simply executes reads and writes on the same -// physical memory addresses -// for each hooked irq, it simply injects the irq into the VM -// -// These operations are also logged to serial (optionaly) -// -// If you attach a generic device *last*, you can capture all ops that are not -// already hooked, and capture a log of VM activity with respect to them. -// -// The effects of using the generic device should be identical to -// doing passthrough I/O, but with logging, and, of course, slower -// - - -#define GENERIC_PRINT_AND_PASSTHROUGH 0 -#define GENERIC_PRINT_AND_IGNORE 1 - - -int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type); - - - - -#endif // ! __V3VEE__ - -#endif diff --git a/palacios/include/devices/ide.h b/palacios/include/devices/ide.h index b778f1e..8f8951d 100644 --- a/palacios/include/devices/ide.h +++ b/palacios/include/devices/ide.h @@ -22,30 +22,6 @@ #ifdef __V3VEE__ -#include - -struct ide_cfg { - char pci[32]; - char southbridge[32]; -}; - - -int v3_ide_register_cdrom(struct vm_device * ide, - uint_t bus_num, - uint_t drive_num, - char * drive_name, - struct v3_cd_ops * ops, - void * private_data); - -int v3_ide_register_harddisk(struct vm_device * ide, - uint_t bus_num, - uint_t drive_num, - char * drive_name, - struct v3_hd_ops * ops, - void * private_data); - - - int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, diff --git a/palacios/include/devices/lnx_virtio_blk.h b/palacios/include/devices/lnx_virtio_blk.h deleted file mode 100644 index 1bcf08c..0000000 --- a/palacios/include/devices/lnx_virtio_blk.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_LNX_VIRTIO_BLK_H__ -#define __DEVICES_LNX_VIRTIO_BLK_H__ - -#ifdef __V3VEE__ - -#include - -int v3_virtio_register_cdrom(struct vm_device * dev, - struct v3_cd_ops * ops, - void * private_data); - - -int v3_virtio_register_harddisk(struct vm_device * dev, - struct v3_hd_ops * ops, - void * private_data); - - -#endif - - -#endif diff --git a/palacios/include/devices/net_cd.h b/palacios/include/devices/net_cd.h deleted file mode 100644 index d1f8a31..0000000 --- a/palacios/include/devices/net_cd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_NET_CD_H__ -#define __DEVICES_NET_CD_H__ - -#ifdef __V3VEE__ - - -struct net_cd_cfg { - char ide[32]; - uint_t bus; - uint_t drive; - const char * ip_str; - uint16_t port; - const char * disk_tag; -}; - - - -#endif - -#endif diff --git a/palacios/include/devices/net_hd.h b/palacios/include/devices/net_hd.h deleted file mode 100644 index 2a57832..0000000 --- a/palacios/include/devices/net_hd.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_NET_HD_H__ -#define __DEVICES_NET_HD_H__ - -#ifdef __V3VEE__ - - - -struct net_hd_cfg { - char ide[32]; - uint_t bus; - uint_t drive; - const char * ip_str; - uint16_t port; - const char * disk_tag; -}; - - - -#endif - -#endif diff --git a/palacios/include/devices/pci.h b/palacios/include/devices/pci.h index 9e329b8..1da7102 100644 --- a/palacios/include/devices/pci.h +++ b/palacios/include/devices/pci.h @@ -30,6 +30,8 @@ #include +struct vm_device; + typedef enum { PCI_BAR_IO, PCI_BAR_MEM24, diff --git a/palacios/include/devices/pci_passthrough.h b/palacios/include/devices/pci_passthrough.h deleted file mode 100644 index 8ac8580..0000000 --- a/palacios/include/devices/pci_passthrough.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_PCI_PASSTHROUGH_H__ -#define __DEVICES_PCI_PASSTHROUGH_H__ - -#ifdef __V3VEE__ - -struct pci_passthrough_cfg { - char pci_bus_name[32]; - - char name[32]; - uint16_t vendor_id; - uint16_t device_id; -}; - - -#endif - -#endif diff --git a/palacios/include/devices/ram_cd.h b/palacios/include/devices/ram_cd.h deleted file mode 100644 index c105394..0000000 --- a/palacios/include/devices/ram_cd.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_RAM_CD_H__ -#define __DEVICES_RAM_CD_H__ - -#ifdef __V3VEE__ - - - -struct ram_cd_cfg { - char ide[32]; - uint_t bus; - uint_t drive; - addr_t ramdisk; - uint32_t size; -}; - - - -#endif - -#endif diff --git a/palacios/include/devices/ram_hd.h b/palacios/include/devices/ram_hd.h deleted file mode 100644 index 4c4fdad..0000000 --- a/palacios/include/devices/ram_hd.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_RAM_HD_H__ -#define __DEVICES_RAM_HD_H__ - -#ifdef __V3VEE__ - -struct ram_hd_cfg { - char ide[32]; - uint_t bus; - uint_t drive; - addr_t ramdisk; - uint32_t size; -}; - - - -#endif - -#endif diff --git a/palacios/include/devices/telnet_cons.h b/palacios/include/devices/telnet_cons.h deleted file mode 100644 index afca897..0000000 --- a/palacios/include/devices/telnet_cons.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#ifndef __DEVICES_TELNET_CONS_H__ -#define __DEVICES_TELNET_CONS_H__ - -#ifdef __V3VEE__ - - - -struct telnet_cons_cfg { - char frontend[32]; - uint16_t port; -}; - - - -#endif - -#endif diff --git a/palacios/include/palacios/svm.h b/palacios/include/palacios/svm.h index 3780b95..1a9ecfd 100644 --- a/palacios/include/palacios/svm.h +++ b/palacios/include/palacios/svm.h @@ -78,10 +78,12 @@ void v3_init_svm_cpu(int cpu_id); -void v3_init_svm_hooks(struct v3_ctrl_ops * vmm_ops); int v3_is_svm_capable(); +int v3_init_svm_vmcb(struct guest_info * info, v3_vm_class_t vm_class); + int v3_svm_enter(struct guest_info * info); +int v3_start_svm_guest(struct guest_info *info); #endif diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index b5d481c..6506658 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -48,6 +48,8 @@ + + struct v3_gprs { v3_reg_t rdi; v3_reg_t rsi; @@ -124,6 +126,8 @@ struct v3_segments { #include #endif +#include + struct shadow_page_state; struct v3_intr_state; @@ -147,6 +151,8 @@ struct guest_info { addr_t mem_size; // In bytes for now v3_shdw_map_t mem_map; + struct v3_config * cfg_data; + v3_vm_class_t vm_class; struct vm_time time_state; diff --git a/palacios/include/palacios/vmm.h b/palacios/include/palacios/vmm.h index 6fbbe7d..87d50ed 100644 --- a/palacios/include/palacios/vmm.h +++ b/palacios/include/palacios/vmm.h @@ -21,10 +21,11 @@ #define __VMM_H__ -#include +//#include #include #include +struct guest_info; #ifdef __V3VEE__ @@ -183,9 +184,8 @@ -#define VMM_INVALID_CPU 0 -#define VMM_VMX_CPU 1 -#define VMM_SVM_CPU 2 + +typedef enum v3_vm_class {V3_INVALID_VM, V3_PC_VM, V3_CRAY_VM} v3_vm_class_t; // Maybe make this a define.... @@ -200,6 +200,11 @@ void v3_yield_cond(struct guest_info * info); void v3_interrupt_cpu(struct guest_info * vm, int logical_cpu); +unsigned int v3_get_cpu_id(); + +v3_cpu_arch_t v3_get_cpu_type(int cpu_id); + + int v3_vm_enter(struct guest_info * info); @@ -238,6 +243,7 @@ struct v3_os_hooks { void (*mutex_lock)(void * mutex, int must_spin); void (*mutex_unlock)(void * mutex); + unsigned int (*get_cpu)(void); void (*interrupt_cpu)(struct guest_info * vm, int logical_cpu); void (*call_on_cpu)(int logical_cpu, void (*fn)(void * arg), void * arg); void (*start_thread_on_cpu)(int logical_cpu, int (*fn)(void * arg), void * arg, char * thread_name); @@ -245,62 +251,6 @@ struct v3_os_hooks { -typedef enum {NONE, HARDDRIVE, CDROM, VIRTIO} v3_disk_type_t; -typedef enum {RAM, NETWORK} v3_disk_connection_t; - -union v3_disk_info { - struct { - void * data_ptr; - int size; - } ram; - - struct { - char * ip_str; - int port; - char * disk_name; - } net; -}; - -struct v3_vm_config { - - unsigned long mem_size; // in bytes, var should be natural size of cpu - // so we can specify maximum physical address size - // (We're screwed if we want to do 32 bit host/64 bit guest) - - int enable_telemetry; - int enable_nested_paging; - - int enable_pci; - - int enable_swap; - - int guest_cpu; - - unsigned long schedule_freq; // in HZ - - v3_disk_type_t pri_disk_type; - v3_disk_connection_t pri_disk_con; - union v3_disk_info pri_disk_info; - - v3_disk_type_t sec_disk_type; - v3_disk_connection_t sec_disk_con; - union v3_disk_info sec_disk_info; -}; - - - -/* This will contain Function pointers that control the VMs */ -struct v3_ctrl_ops { - struct guest_info *(*allocate_guest)(void); - - int (*init_guest)(struct guest_info * info, struct v3_vm_config * config_ptr); - int (*start_guest)(struct guest_info * info); - // int (*stop_vm)(uint_t vm_id); - - int (*has_nested_paging)(void); - - // v3_cpu_arch_t (*get_cpu_arch)(); -}; @@ -320,7 +270,11 @@ struct v3_interrupt { -void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops, int num_cpus); +void Init_V3(struct v3_os_hooks * hooks, int num_cpus); + + +int v3_start_vm(struct guest_info * info, unsigned int cpu_mask); +struct guest_info * v3_create_vm(void * cfg); int v3_deliver_irq(struct guest_info * vm, struct v3_interrupt * intr); diff --git a/palacios/include/palacios/vmm_config.h b/palacios/include/palacios/vmm_config.h index 716e5b6..a719cf5 100644 --- a/palacios/include/palacios/vmm_config.h +++ b/palacios/include/palacios/vmm_config.h @@ -24,17 +24,47 @@ #ifdef __V3VEE__ -#include +//#include #include +#include +#include +#include +//#include -int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr); -int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr); +struct guest_info; +int v3_config_guest(struct guest_info * info, void * cfg_blob); +struct v3_cfg_file { + void * data; + uint64_t size; -#endif // ! __V3VEE__ + char tag[256]; + + struct list_head file_node; +}; + + + +typedef struct v3_xml v3_cfg_tree_t; + +struct v3_config { + v3_cfg_tree_t * cfg; + struct list_head file_list; + struct hashtable * file_table; + void * blob; +}; + + +struct v3_cfg_file * v3_cfg_get_file(struct guest_info * info, char * tag); + +char * v3_cfg_val(v3_cfg_tree_t * tree, char * tag); +v3_cfg_tree_t * v3_cfg_subtree(v3_cfg_tree_t * tree, char * tag); +v3_cfg_tree_t * v3_cfg_next_branch(v3_cfg_tree_t * tree); + +#endif // ! __V3VEE__ #endif diff --git a/palacios/include/palacios/vmm_dev_mgr.h b/palacios/include/palacios/vmm_dev_mgr.h index 9495861..dd62093 100644 --- a/palacios/include/palacios/vmm_dev_mgr.h +++ b/palacios/include/palacios/vmm_dev_mgr.h @@ -26,6 +26,7 @@ #include #include #include +#include struct guest_info; @@ -53,14 +54,23 @@ struct vm_device { struct vmm_dev_mgr { uint_t num_devs; struct list_head dev_list; - struct hashtable * dev_table; + + struct list_head blk_list; + struct hashtable * blk_table; + + struct list_head net_list; + struct hashtable * net_table; + + struct list_head console_list; + struct hashtable * console_table; + }; -int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg_data); +int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tree_t * cfg); void v3_free_device(struct vm_device * dev); @@ -121,7 +131,7 @@ struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, v struct v3_device_info { char * name; - int (*init)(struct guest_info * info, void * cfg_data); + int (*init)(struct guest_info * info, v3_cfg_tree_t * cfg); }; @@ -136,11 +146,51 @@ struct v3_device_info { -void PrintDebugDevMgr(struct guest_info * info); -void PrintDebugDev(struct vm_device * dev); +void v3_print_dev_mgr(struct guest_info * info); + +struct v3_dev_blk_ops { + uint64_t (*get_capacity)(void * private_data); + // Reads always operate on 2048 byte blocks + int (*read)(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data); + int (*write)(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data); +}; + +struct v3_dev_net_ops { + +}; + +struct v3_dev_console_ops { +}; +int v3_dev_add_blk_frontend(struct guest_info * info, + char * name, + int (*connect)(struct guest_info * info, + void * frontend_data, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data), + void * priv_data); +int v3_dev_connect_blk(struct guest_info * info, + char * frontend_name, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data); + +int v3_dev_add_net_frontend(struct guest_info * info, + char * name, + int (*connect)(struct guest_info * info, + void * frontend_data, + struct v3_dev_net_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data), + void * priv_data); +int v3_dev_connect_net(struct guest_info * info, + char * frontend_name, + struct v3_dev_net_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data); #endif // ! __V3VEE__ diff --git a/palacios/include/palacios/vmm_string.h b/palacios/include/palacios/vmm_string.h index 0b5d270..78c3cf0 100644 --- a/palacios/include/palacios/vmm_string.h +++ b/palacios/include/palacios/vmm_string.h @@ -44,7 +44,9 @@ int memcmp(const void *s1, const void *s2, size_t n); size_t strlen(const char* s); size_t strnlen(const char *s, size_t maxlen); int strcmp(const char* s1, const char* s2); +int strcasecmp(const char* s1, const char* s2); int strncmp(const char* s1, const char* s2, size_t limit); +int strncasecmp(const char* s1, const char* s2, size_t limit); char *strcat(char *s1, const char *s2); char *strncat(char *s1, const char *s2, size_t limit); char *strcpy(char *dest, const char *src); @@ -62,8 +64,12 @@ size_t strspn(const char * s, const char * accept); size_t strcspn(const char * s, const char * reject); char * strstr(const char * haystack, const char * needle); +void str_tolower(char * s); +void str_toupper(char * s); -#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') + + +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') #define isascii(c) (((c) & ~0x7f) == 0) #define isupper(c) ((c) >= 'A' && (c) <= 'Z') #define islower(c) ((c) >= 'a' && (c) <= 'z') diff --git a/palacios/include/palacios/vmm_sym_iface.h b/palacios/include/palacios/vmm_sym_iface.h index 6c96dab..5de9720 100644 --- a/palacios/include/palacios/vmm_sym_iface.h +++ b/palacios/include/palacios/vmm_sym_iface.h @@ -23,18 +23,15 @@ #ifdef __V3VEE__ -#include - struct v3_sym_interface { uint64_t magic; - union { uint32_t feature_flags; struct { - uint_t pci_map_valid : 1; + uint_t pci_map_valid : 1; uint32_t sym_call_enabled : 1; } __attribute__((packed)); } __attribute__((packed)); @@ -51,13 +48,12 @@ struct v3_sym_interface { uint8_t pci_pt_map[(4 * 256) / 8]; // we're hardcoding this: (4 busses, 256 max devs) - - - } __attribute__((packed)); +#include + struct v3_sym_context { struct v3_gprs vm_regs; @@ -71,7 +67,6 @@ struct v3_sym_context { }; - struct v3_sym_state { struct v3_sym_interface * sym_page; @@ -97,6 +92,12 @@ struct v3_sym_state { uint64_t sym_call_fs; }; + + + + + + int v3_init_sym_iface(struct guest_info * info); diff --git a/palacios/include/palacios/vmx.h b/palacios/include/palacios/vmx.h index 67e546b..a34cd46 100644 --- a/palacios/include/palacios/vmx.h +++ b/palacios/include/palacios/vmx.h @@ -1,4 +1,5 @@ + /* * This file is part of the Palacios Virtual Machine Monitor developed * by the V3VEE Project with funding from the United States National @@ -230,7 +231,6 @@ struct vmx_data { }; int v3_is_vmx_capable(); -void v3_init_vmx_hooks(struct v3_ctrl_ops * vm_ops); void v3_init_vmx_cpu(int cpu_id); diff --git a/palacios/src/devices/8254.c b/palacios/src/devices/8254.c index c205752..4b2f4c0 100644 --- a/palacios/src/devices/8254.c +++ b/palacios/src/devices/8254.c @@ -23,7 +23,7 @@ #include #include #include - +#include #ifndef CONFIG_DEBUG_PIT @@ -631,9 +631,10 @@ static struct v3_device_ops dev_ops = { }; -static int pit_init(struct guest_info * info, void * cfg_data) { +static int pit_init(struct guest_info * info, v3_cfg_tree_t * cfg) { struct pit * pit_state = NULL; struct vm_device * dev = NULL; + char * name = v3_cfg_val(cfg, "name"); uint_t cpu_khz = V3_CPU_KHZ(); ullong_t reload_val = (ullong_t)cpu_khz * 1000; @@ -641,10 +642,10 @@ static int pit_init(struct guest_info * info, void * cfg_data) { pit_state = (struct pit *)V3_Malloc(sizeof(struct pit)); V3_ASSERT(pit_state != NULL); - dev = v3_allocate_device("PIT", &dev_ops, pit_state); + dev = v3_allocate_device(name, &dev_ops, pit_state); if (v3_attach_device(info, dev) == -1) { - PrintError("Could not attach device %s\n", "PIT"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/8259a.c b/palacios/src/devices/8259a.c index d1944f6..443fb0a 100644 --- a/palacios/src/devices/8259a.c +++ b/palacios/src/devices/8259a.c @@ -715,15 +715,17 @@ static struct v3_device_ops dev_ops = { -static int pic_init(struct guest_info * vm, void * cfg_data) { +static int pic_init(struct guest_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"); + V3_ASSERT(state != NULL); - struct vm_device * dev = v3_allocate_device("8259A", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "8259A"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/Kconfig b/palacios/src/devices/Kconfig index dde39ab..4a51101 100644 --- a/palacios/src/devices/Kconfig +++ b/palacios/src/devices/Kconfig @@ -150,19 +150,7 @@ config DEBUG_NE2k Enable debugging for the NE2K -config NET_CD - bool "Networked CD backend" - default y - depends on SOCKET && (IDE || LINUX_VIRTIO_BLOCK) - help - Includes the Network CD backend -config NET_HD - bool "Networked HD backend" - default y - depends on SOCKET && (IDE || LINUX_VIRTIO_BLOCK) - help - Includes the Network HD backend config NVRAM @@ -240,24 +228,27 @@ config DEBUG_PIT Enable debugging for the PIT - - -config RAM_CD - bool "RAM based CD backend" +config NETDISK + bool "NETDISK storage backend" default y - depends on IDE || LINUX_VIRTIO_BLOCK + depends on SOCKET && (IDE || LINUX_VIRTIO_BLOCK) help - Includes the RAM based CD backend + Includes the Network based disk backend -config RAM_HD - bool "RAM based HD backend" +config RAMDISK + bool "RAMDISK storage backend" default y depends on IDE || LINUX_VIRTIO_BLOCK help - Includes the RAM based HD backend - + Includes the RAM based disk backend +config TMPDISK + bool "TMPDISK storage backend" + default y + depends on IDE || LINUX_VIRTIO_BLOCK + help + Includes the temporary RAM disk config SYM_SWAP bool "Symbiotic Swap disk" diff --git a/palacios/src/devices/Makefile b/palacios/src/devices/Makefile index 515b088..894a1f2 100644 --- a/palacios/src/devices/Makefile +++ b/palacios/src/devices/Makefile @@ -14,14 +14,13 @@ obj-$(CONFIG_NVRAM) += nvram.o obj-$(CONFIG_OS_DEBUG) += os_debug.o obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_PIIX3) += piix3.o -obj-$(CONFIG_RAM_CD) += ram_cd.o -obj-$(CONFIG_RAM_HD) += ram_hd.o -obj-$(CONFIG_SYM_SWAP) += sym_swap.o tmp_blk.o +obj-$(CONFIG_SYM_SWAP) += sym_swap.o obj-$(CONFIG_NE2K) += ne2k.o -obj-$(CONFIG_NET_CD) += net_cd.o -obj-$(CONFIG_NET_HD) += net_hd.o +obj-$(CONFIG_TMPDISK) += tmpdisk.o +obj-$(CONFIG_RAMDISK) += ramdisk.o +obj-$(CONFIG_NETDISK) += netdisk.o obj-$(CONFIG_CGA) += cga.o obj-$(CONFIG_TELNET_CONSOLE) += telnet_cons.o diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index bbef7e2..ccb89e3 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -22,7 +22,7 @@ #include #include #include - +#include #ifndef CONFIG_DEBUG_APIC #undef PrintDebug @@ -1072,15 +1072,16 @@ static struct v3_device_ops dev_ops = { -static int apic_init(struct guest_info * vm, void * cfg_data) { +static int apic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("Creating APIC\n"); + char * name = v3_cfg_val(cfg, "name"); struct apic_state * apic = (struct apic_state *)V3_Malloc(sizeof(struct apic_state)); - struct vm_device * dev = v3_allocate_device("LAPIC", &dev_ops, apic); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, apic); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "LAPIC"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/ata.h b/palacios/src/devices/ata.h index 5cdb737..4cf6cd2 100644 --- a/palacios/src/devices/ata.h +++ b/palacios/src/devices/ata.h @@ -64,10 +64,10 @@ static void ata_identify_device(struct ide_drive * drive) { drive_id->lba_enable = 1; // Drive Capacity (28 bit LBA) - drive_id->lba_capacity = drive->hd_ops->get_capacity(drive->private_data); + drive_id->lba_capacity = drive->ops->get_capacity(drive->private_data); // Drive Capacity (48 bit LBA) - drive_id->lba_capacity_2 = drive->hd_ops->get_capacity(drive->private_data); + drive_id->lba_capacity_2 = drive->ops->get_capacity(drive->private_data); // lower byte is the maximum multiple sector size... @@ -116,7 +116,7 @@ static int ata_read(struct vm_device * dev, struct ide_channel * channel, uint8_ PrintDebug("Reading Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt); - int ret = drive->hd_ops->read(dst, sect_cnt, drive->current_lba, drive->private_data); + int ret = drive->ops->read(dst, drive->current_lba * HD_SECTOR_SIZE, sect_cnt * HD_SECTOR_SIZE, drive->private_data); if (ret == -1) { PrintError("IDE: Error reading HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba)); @@ -132,7 +132,7 @@ static int ata_write(struct vm_device * dev, struct ide_channel * channel, uint8 PrintDebug("Writing Drive LBA=%d (count=%d)\n", (uint32_t)(drive->current_lba), sect_cnt); - int ret = drive->hd_ops->write(src, sect_cnt, drive->current_lba, drive->private_data); + int ret = drive->ops->write(src, drive->current_lba * HD_SECTOR_SIZE, sect_cnt * HD_SECTOR_SIZE, drive->private_data); if (ret == -1) { PrintError("IDE: Error writing HD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba)); @@ -168,11 +168,11 @@ static int ata_get_lba(struct vm_device * dev, struct ide_channel * channel, uin if ((lba_addr.addr + sect_cnt) > - drive->hd_ops->get_capacity(drive->private_data)) { + drive->ops->get_capacity(drive->private_data)) { PrintError("IDE: request size exceeds disk capacity (lba=%d) (sect_cnt=%d) (ReadEnd=%d) (capacity=%p)\n", lba_addr.addr, sect_cnt, lba_addr.addr + (sect_cnt * HD_SECTOR_SIZE), - (void *)(addr_t)(drive->hd_ops->get_capacity(drive->private_data))); + (void *)(addr_t)(drive->ops->get_capacity(drive->private_data))); return -1; } diff --git a/palacios/src/devices/atapi.h b/palacios/src/devices/atapi.h index 27bed29..ad03ee9 100644 --- a/palacios/src/devices/atapi.h +++ b/palacios/src/devices/atapi.h @@ -128,7 +128,8 @@ static void atapi_cmd_nop(struct vm_device * dev, struct ide_channel * channel) static int atapi_read_chunk(struct vm_device * dev, struct ide_channel * channel) { struct ide_drive * drive = get_selected_drive(channel); - int ret = drive->cd_ops->read(drive->data_buf, 1, drive->current_lba, drive->private_data); + int ret = drive->ops->read(drive->data_buf, drive->current_lba * ATAPI_BLOCK_SIZE, ATAPI_BLOCK_SIZE, +drive->private_data); if (ret == -1) { PrintError("IDE: Error reading CD block (LBA=%p)\n", (void *)(addr_t)(drive->current_lba)); @@ -177,10 +178,10 @@ static int atapi_read10(struct vm_device * dev, struct ide_channel * channel) { return 0; } - if (lba + xfer_len > drive->cd_ops->get_capacity(drive->private_data)) { + if (lba + xfer_len > drive->ops->get_capacity(drive->private_data)) { PrintError("IDE: xfer len exceeded capacity (lba=%d) (xfer_len=%d) (ReadEnd=%d) (capacity=%d)\n", lba, xfer_len, lba + xfer_len, - drive->cd_ops->get_capacity(drive->private_data)); + (uint32_t)drive->ops->get_capacity(drive->private_data)); atapi_cmd_error(dev, channel, ATAPI_SEN_ILL_REQ, ASC_LOG_BLK_OOR); ide_raise_irq(dev, channel); return 0; @@ -238,7 +239,7 @@ static void atapi_req_sense(struct vm_device * dev, struct ide_channel * channel static int atapi_get_capacity(struct vm_device * dev, struct ide_channel * channel) { struct ide_drive * drive = get_selected_drive(channel); struct atapi_rd_capacity_resp * resp = (struct atapi_rd_capacity_resp *)(drive->data_buf); - uint32_t capacity = drive->cd_ops->get_capacity(drive->private_data); + uint32_t capacity = drive->ops->get_capacity(drive->private_data); resp->lba = le_to_be_32(capacity); resp->block_len = le_to_be_32(ATAPI_BLOCK_SIZE); diff --git a/palacios/src/devices/bochs_debug.c b/palacios/src/devices/bochs_debug.c index 12f22c9..4c1ab08 100644 --- a/palacios/src/devices/bochs_debug.c +++ b/palacios/src/devices/bochs_debug.c @@ -134,18 +134,19 @@ static struct v3_device_ops dev_ops = { -static int debug_init(struct guest_info * vm, void * cfg_data) { - struct debug_state * state = NULL; +static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { + struct debug_state * state = NULL; + char * name = v3_cfg_val(cfg, "name"); 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("BOCHS_DEBUG", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "BOCHS_DEBUG"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/cga.c b/palacios/src/devices/cga.c index 3a77563..ee94f84 100644 --- a/palacios/src/devices/cga.c +++ b/palacios/src/devices/cga.c @@ -310,18 +310,20 @@ static struct v3_device_ops dev_ops = { .stop = NULL, }; -static int cga_init(struct guest_info * vm, void * cfg_data) { +static int cga_init(struct guest_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; - uint32_t enable_passthrough = (uint32_t)(addr_t)cfg_data; + int enable_passthrough = 0; + char * name = v3_cfg_val(cfg, "name"); + enable_passthrough = (strcasecmp(v3_cfg_val(cfg, "passthrough"), "enable") == 0) ? 1 : 0; PrintDebug("video: init_device\n"); - struct vm_device * dev = v3_allocate_device("CGA_VIDEO", &dev_ops, video_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, video_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "CGA_VIDEO"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/cirrus_gfx_card.c b/palacios/src/devices/cirrus_gfx_card.c index a768007..25bf720 100644 --- a/palacios/src/devices/cirrus_gfx_card.c +++ b/palacios/src/devices/cirrus_gfx_card.c @@ -420,9 +420,11 @@ static struct v3_device_ops dev_ops = { .stop = cirrus_gfx_card_stop_device, }; -static int cirrus_gfx_card_init(struct guest_info * vm, void * cfg_data){ +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"); + struct vm_device * dev = v3_allocate_device("TEXT_GFX_CARD", &dev_ops, video_state); if (v3_attach_device(vm, dev) == -1) { diff --git a/palacios/src/devices/generic.c b/palacios/src/devices/generic.c index c6dd8d6..e4a00ff 100644 --- a/palacios/src/devices/generic.c +++ b/palacios/src/devices/generic.c @@ -19,12 +19,11 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include #include #include #include - - +#include +#include #ifndef CONFIG_DEBUG_GENERIC #undef PrintDebug @@ -32,6 +31,11 @@ #endif +typedef enum {GENERIC_IGNORE, + GENERIC_PASSTHROUGH, + GENERIC_PRINT_AND_PASSTHROUGH, + GENERIC_PRINT_AND_IGNORE} generic_mode_t; + struct generic_internal { struct list_head port_list; uint_t num_port_ranges; @@ -42,7 +46,7 @@ struct generic_internal { struct port_range { uint_t start; uint_t end; - uint_t type; + generic_mode_t mode; struct list_head range_link; }; @@ -211,26 +215,26 @@ static struct v3_device_ops dev_ops = { -int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, uint_t type) { +static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, generic_mode_t mode) { struct generic_internal * state = (struct generic_internal *)(dev->private_data); struct port_range * range = (struct port_range *)V3_Malloc(sizeof(struct port_range)); uint_t i = 0; range->start = start; range->end = end; - range->type = type; + range->mode = mode; PrintDebug("generic: Adding Port Range: 0x%x to 0x%x as %s\n", - range->start, range->end, - (range->type == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); + start, end, + (mode == GENERIC_PRINT_AND_PASSTHROUGH) ? "print-and-passthrough" : "print-and-ignore"); for (i = start; i <= end; i++) { - if (type == GENERIC_PRINT_AND_PASSTHROUGH) { + if (mode == GENERIC_PRINT_AND_PASSTHROUGH) { if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough) == -1) { PrintError("generic: can't hook port 0x%x (already hooked?)\n", i); return -1; } - } else if (type == GENERIC_PRINT_AND_IGNORE) { + } else if (mode == GENERIC_PRINT_AND_IGNORE) { if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore) == -1) { PrintError("generic: can't hook port 0x%x (already hooked?)\n", i); return -1; @@ -248,22 +252,52 @@ int v3_generic_add_port_range(struct vm_device * dev, uint_t start, uint_t end, -static int generic_init(struct guest_info * vm, void * cfg_data) { +static int generic_init(struct guest_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"); + + v3_cfg_tree_t * port_cfg = v3_cfg_subtree(cfg, "ports"); + + INIT_LIST_HEAD(&(state->port_list)); state->num_port_ranges = 0; + - struct vm_device * dev = v3_allocate_device("GENERIC", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "GENERIC"); + PrintError("Could not attach device %s\n", name); return -1; } PrintDebug("generic: init_device\n"); generic_reset_device(dev); + // scan port list.... + while (port_cfg) { + uint16_t start = atox(v3_cfg_val(port_cfg, "start")); + uint16_t end = atox(v3_cfg_val(port_cfg, "end")); + char * mode_str = v3_cfg_val(port_cfg, "mode"); + generic_mode_t mode = GENERIC_IGNORE; + + if (strcasecmp(mode_str, "print_and_ignore") == 0) { + mode = GENERIC_PRINT_AND_IGNORE; + } else if (strcasecmp(mode_str, "print_and_passthrough") == 0) { + mode = GENERIC_PRINT_AND_PASSTHROUGH; + } else { + PrintError("Invalid Mode %s\n", mode_str); + return -1; + } + + if (add_port_range(dev, start, end, mode) == -1) { + PrintError("Could not add port range %d-%d\n", start, end); + return -1; + } + + port_cfg = v3_cfg_next_branch(port_cfg); + } + + return 0; } diff --git a/palacios/src/devices/i440fx.c b/palacios/src/devices/i440fx.c index 2408cdd..ee4dc80 100644 --- a/palacios/src/devices/i440fx.c +++ b/palacios/src/devices/i440fx.c @@ -57,12 +57,13 @@ static struct v3_device_ops dev_ops = { -static int i440_init(struct guest_info * vm, void * cfg_data) { +static int i440_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { struct pci_device * pci_dev = NULL; struct v3_pci_bar bars[6]; int i; struct i440_state * state = NULL; - struct vm_device * pci = v3_find_dev(vm, (char *)cfg_data); + struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); + char * name = v3_cfg_val(cfg, "name"); if (!pci) { PrintError("could not find PCI Device\n"); @@ -73,10 +74,10 @@ static int i440_init(struct guest_info * vm, void * cfg_data) { state->pci = pci; - struct vm_device * dev = v3_allocate_device("i440FX", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "i440FX"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index bf95245..7b13e5b 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -18,11 +18,11 @@ */ #include +#include #include #include #include #include -#include #include "ide-types.h" #include "atapi-types.h" @@ -63,6 +63,10 @@ #define DATA_BUFFER_SIZE 2048 +#define ATAPI_BLOCK_SIZE 2048 +#define HD_SECTOR_SIZE 512 + + static const char * ide_pri_port_strs[] = {"PRI_DATA", "PRI_FEATURES", "PRI_SECT_CNT", "PRI_SECT_NUM", "PRI_CYL_LOW", "PRI_CYL_HIGH", "PRI_DRV_SEL", "PRI_CMD", "PRI_CTRL", "PRI_ADDR_REG"}; @@ -76,6 +80,7 @@ static const char * ide_dma_port_strs[] = {"DMA_CMD", NULL, "DMA_STATUS", NULL, "DMA_PRD0", "DMA_PRD1", "DMA_PRD2", "DMA_PRD3"}; +typedef enum {BLOCK_NONE, BLOCK_DISK, BLOCK_CDROM} v3_block_type_t; static inline const char * io_port_to_str(uint16_t port) { if ((port >= PRI_DATA_PORT) && (port <= PRI_CMD_PORT)) { @@ -122,11 +127,7 @@ struct ide_drive { v3_block_type_t drive_type; - union { - struct v3_cd_ops * cd_ops; - struct v3_hd_ops * hd_ops; - }; - + struct v3_dev_blk_ops * ops; union { struct ide_cd_state cd_state; @@ -1372,7 +1373,7 @@ static void init_drive(struct ide_drive * drive) { drive->private_data = NULL; - drive->cd_ops = NULL; + drive->ops = NULL; } static void init_channel(struct ide_channel * channel) { @@ -1442,28 +1443,91 @@ static struct v3_device_ops dev_ops = { -static int ide_init(struct guest_info * vm, void * cfg_data) { - struct ide_internal * ide = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal)); - struct ide_cfg * cfg = (struct ide_cfg *)(cfg_data); + +static int connect_fn(struct guest_info * info, + void * frontend_data, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data) { + struct ide_internal * ide = (struct ide_internal *)(frontend_data); + struct ide_channel * channel = NULL; + struct ide_drive * drive = NULL; + + char * bus_str = v3_cfg_val(cfg, "bus_num"); + char * drive_str = v3_cfg_val(cfg, "drive_num"); + char * type_str = v3_cfg_val(cfg, "type"); + char * model_str = v3_cfg_val(cfg, "model"); + uint_t bus_num = 0; + uint_t drive_num = 0; + + + if ((!type_str) || (!drive_str) || (!bus_str)) { + PrintError("Incomplete IDE Configuration\n"); + return -1; + } + + bus_num = atoi(bus_str); + drive_num = atoi(drive_str); + + channel = &(ide->channels[bus_num]); + drive = &(channel->drives[drive_num]); + + if (drive->drive_type != BLOCK_NONE) { + PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num); + return -1; + } + + strncpy(drive->model, model_str, sizeof(drive->model) - 1); + if (strcasecmp(type_str, "cdrom") == 0) { + drive->drive_type = BLOCK_CDROM; + + while (strlen((char *)(drive->model)) < 40) { + strcat((char*)(drive->model), " "); + } + + } else if (strcasecmp(type_str, "hd") == 0) { + drive->drive_type = BLOCK_DISK; + + drive->hd_state.accessed = 0; + drive->hd_state.mult_sector_num = 1; + + drive->num_sectors = 63; + drive->num_heads = 16; + drive->num_cylinders = ops->get_capacity(private_data) / (drive->num_sectors * drive->num_heads); + } else { + PrintError("invalid IDE drive type\n"); + return -1; + } + + + drive->ops = ops; + + if (ide->ide_pci) { + // Hardcode this for now, but its not a good idea.... + ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80; + } + + drive->private_data = private_data; + + return 0; +} + + + + +static int ide_init(struct guest_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"); + PrintDebug("IDE: Initializing IDE\n"); memset(ide, 0, sizeof(struct ide_internal)); - if (cfg->pci != NULL) { - if (cfg->southbridge == NULL) { - PrintError("PCI Enabled BUT southbridge is NULL\n"); - return -1; - } - - ide->pci_bus = v3_find_dev(vm, (char *)cfg->pci); - - if (ide->pci_bus == NULL) { - PrintError("Could not find PCI device\n"); - return -1; - } + ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); - struct vm_device * southbridge = v3_find_dev(vm, cfg->southbridge); + if (ide->pci_bus != NULL) { + struct vm_device * southbridge = v3_find_dev(vm, v3_cfg_val(cfg, "controller")); if (!southbridge) { PrintError("Could not find southbridge\n"); @@ -1473,17 +1537,15 @@ static int ide_init(struct guest_info * vm, void * cfg_data) { ide->southbridge = (struct v3_southbridge *)(southbridge->private_data); } - PrintDebug("IDE: Creating IDE bus x 2\n"); - struct vm_device * dev = v3_allocate_device("IDE", &dev_ops, ide); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, ide); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "IDE"); + PrintError("Could not attach device %s\n", name); return -1; } - if (init_ide_state(dev) == -1) { PrintError("Failed to initialize IDE state\n"); return -1; @@ -1595,6 +1657,12 @@ static int ide_init(struct guest_info * vm, void * cfg_data) { } + if (v3_dev_add_blk_frontend(vm, name, connect_fn, (void *)ide) == -1) { + PrintError("Could not register %s as frontend\n", name); + return -1; + } + + PrintDebug("IDE Initialized\n"); return 0; @@ -1606,11 +1674,6 @@ device_register("IDE", ide_init) - - - - - int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_num, uint32_t * cylinders, uint32_t * heads, uint32_t * sectors) { @@ -1631,98 +1694,3 @@ int v3_ide_get_geometry(struct vm_device * ide_dev, int channel_num, int drive_n - -int v3_ide_register_cdrom(struct vm_device * ide_dev, - uint_t bus_num, - uint_t drive_num, - char * dev_name, - struct v3_cd_ops * ops, - void * private_data) { - - struct ide_internal * ide = (struct ide_internal *)(ide_dev->private_data); - struct ide_channel * channel = NULL; - struct ide_drive * drive = NULL; - - V3_ASSERT((bus_num >= 0) && (bus_num < 2)); - V3_ASSERT((drive_num >= 0) && (drive_num < 2)); - - channel = &(ide->channels[bus_num]); - drive = &(channel->drives[drive_num]); - - if (drive->drive_type != BLOCK_NONE) { - PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num); - return -1; - } - - strncpy(drive->model, dev_name, sizeof(drive->model) - 1); - - while (strlen((char *)(drive->model)) < 40) { - strcat((char*)(drive->model), " "); - } - - - drive->drive_type = BLOCK_CDROM; - - drive->cd_ops = ops; - - if (ide->ide_pci) { - // Hardcode this for now, but its not a good idea.... - ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80; - } - - drive->private_data = private_data; - - return 0; -} - - -int v3_ide_register_harddisk(struct vm_device * ide_dev, - uint_t bus_num, - uint_t drive_num, - char * dev_name, - struct v3_hd_ops * ops, - void * private_data) { - - struct ide_internal * ide = (struct ide_internal *)(ide_dev->private_data); - struct ide_channel * channel = NULL; - struct ide_drive * drive = NULL; - - V3_ASSERT((bus_num >= 0) && (bus_num < 2)); - V3_ASSERT((drive_num >= 0) && (drive_num < 2)); - - channel = &(ide->channels[bus_num]); - drive = &(channel->drives[drive_num]); - - if (drive->drive_type != BLOCK_NONE) { - PrintError("Device slot (bus=%d, drive=%d) already occupied\n", bus_num, drive_num); - return -1; - } - - strncpy(drive->model, dev_name, sizeof(drive->model) - 1); - - drive->drive_type = BLOCK_DISK; - - drive->hd_state.accessed = 0; - drive->hd_state.mult_sector_num = 1; - - drive->hd_ops = ops; - - /* this is something of a hack... */ - drive->num_sectors = 63; - drive->num_heads = 16; - drive->num_cylinders = ops->get_capacity(private_data) / (drive->num_sectors * drive->num_heads); - - if (ide->ide_pci) { - // Hardcode this for now, but its not a good idea.... - ide->ide_pci->config_space[0x41 + (bus_num * 2)] = 0x80; - } - - - - drive->private_data = private_data; - - return 0; -} - - - diff --git a/palacios/src/devices/io_apic.c b/palacios/src/devices/io_apic.c index 3bd5902..95392d0 100644 --- a/palacios/src/devices/io_apic.c +++ b/palacios/src/devices/io_apic.c @@ -21,7 +21,7 @@ #include #include #include - +#include #ifndef CONFIG_DEBUG_IO_APIC #undef PrintDebug @@ -319,11 +319,12 @@ static struct v3_device_ops dev_ops = { -static int ioapic_init(struct guest_info * vm, void * cfg_data) { - struct vm_device * apic = v3_find_dev(vm, (char *)cfg_data); +static int ioapic_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { + struct vm_device * apic = v3_find_dev(vm, v3_cfg_val(cfg, "irq_bus")); + char * name = v3_cfg_val(cfg, "name"); if (!apic) { - PrintError("Could not locate APIC device (%s)\n", (char *)cfg_data); + PrintError("Could not locate APIC device (%s)\n", v3_cfg_val(cfg, "irq_bus")); return -1; } @@ -333,11 +334,11 @@ static int ioapic_init(struct guest_info * vm, void * cfg_data) { ioapic->apic = apic; - struct vm_device * dev = v3_allocate_device("IOAPIC", &dev_ops, ioapic); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, ioapic); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "IOAPIC"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index c05b00e..cf61967 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -23,6 +23,9 @@ #include #include +#include +#include +#include #ifndef CONFIG_DEBUG_KEYBOARD @@ -981,9 +984,9 @@ static struct v3_device_ops dev_ops = { -static int keyboard_init(struct guest_info * vm, void * cfg_data) { +static int keyboard_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { struct keyboard_internal * keyboard_state = NULL; - + char * name = v3_cfg_val(cfg, "name"); PrintDebug("keyboard: init_device\n"); @@ -999,10 +1002,10 @@ static int keyboard_init(struct guest_info * vm, void * cfg_data) { keyboard_state->mouse_enabled = 0; - struct vm_device * dev = v3_allocate_device("KEYBOARD", &dev_ops, keyboard_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, keyboard_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "KEYBOARD"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/lnx_virtio_balloon.c b/palacios/src/devices/lnx_virtio_balloon.c index fed0c83..088cea4 100644 --- a/palacios/src/devices/lnx_virtio_balloon.c +++ b/palacios/src/devices/lnx_virtio_balloon.c @@ -415,10 +415,11 @@ static int handle_query_hcall(struct guest_info * info, uint_t hcall_id, void * -static int virtio_init(struct guest_info * vm, void * cfg_data) { - struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data); +static int virtio_init(struct guest_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"); PrintDebug("Initializing VIRTIO Balloon device\n"); @@ -432,9 +433,9 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) { memset(virtio_state, 0, sizeof(struct virtio_balloon_state)); - struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_BALLOON", &dev_ops, virtio_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "LNX_VIRTIO_BALLOON"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/lnx_virtio_blk.c b/palacios/src/devices/lnx_virtio_blk.c index 69187cc..7bc41a6 100644 --- a/palacios/src/devices/lnx_virtio_blk.c +++ b/palacios/src/devices/lnx_virtio_blk.c @@ -20,8 +20,6 @@ #include #include #include -#include -#include #include #include @@ -93,12 +91,8 @@ struct virtio_blk_state { struct virtio_queue queue; - union { - struct v3_cd_ops * cd_ops; - struct v3_hd_ops * hd_ops; - }; + struct v3_dev_blk_ops * ops; - v3_block_type_t block_type; void * backend_data; int io_range_size; @@ -138,52 +132,23 @@ static int virtio_reset(struct vm_device * dev) { return 0; } -static int handle_read_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint32_t len) { +static int handle_read_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint64_t len) { int ret = -1; - if (blk_state->block_type == BLOCK_DISK) { - if (len % HD_SECTOR_SIZE) { - PrintError("Write of something that is not a sector len %d, mod=%d\n", len, len % HD_SECTOR_SIZE); - return -1; - } - - - PrintDebug("Reading Disk\n"); - - ret = blk_state->hd_ops->read(buf, len / HD_SECTOR_SIZE, *sector, blk_state->backend_data); - - *sector += len / HD_SECTOR_SIZE; - - } else if (blk_state->block_type == BLOCK_CDROM) { - if (len % ATAPI_BLOCK_SIZE) { - PrintError("Write of something that is not an ATAPI block len %d, mod=%d\n", len, len % ATAPI_BLOCK_SIZE); - return -1; - } - - ret = blk_state->cd_ops->read(buf, len / ATAPI_BLOCK_SIZE, *sector , blk_state->backend_data); - - *sector += len / ATAPI_BLOCK_SIZE; - } + PrintDebug("Reading Disk\n"); + ret = blk_state->ops->read(buf, *sector, len, (void *)(blk_state->backend_data)); + *sector += len; return ret; } -static int handle_write_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint32_t len) { +static int handle_write_op(struct virtio_blk_state * blk_state, uint8_t * buf, uint64_t * sector, uint64_t len) { int ret = -1; - if (blk_state->block_type == BLOCK_DISK) { - if (len % HD_SECTOR_SIZE) { - PrintError("Write of something that is not a sector len %d, mod=%d\n", len, len % HD_SECTOR_SIZE); - return -1; - } - - PrintDebug("Writing Disk\n"); - - ret = blk_state->hd_ops->write(buf, len / HD_SECTOR_SIZE, *sector, blk_state->backend_data); - - *sector += len / HD_SECTOR_SIZE; - } + PrintDebug("Writing Disk\n"); + ret = blk_state->ops->write(buf, *sector, len, (void *)(blk_state->backend_data)); + *sector += len; return ret; } @@ -197,50 +162,33 @@ static int handle_block_op(struct virtio_blk_state * blk_state, struct blk_op_hd uint8_t * buf = NULL; PrintDebug("Handling Block op\n"); - - - if (guest_pa_to_host_va(blk_state->virtio_dev->vm, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) { PrintError("Could not translate buffer address\n"); return -1; } - PrintDebug("Sector=%p Length=%d\n", (void *)(addr_t)(hdr->sector), buf_desc->length); if (hdr->type == BLK_IN_REQ) { - if (blk_state->block_type != BLOCK_NONE) { - if (handle_read_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) { - *status = BLK_STATUS_ERR; - return -1; - } else { - *status = BLK_STATUS_OK; - } + if (handle_read_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) { + *status = BLK_STATUS_ERR; + return -1; } else { - *status = BLK_STATUS_NOT_SUPPORTED; + *status = BLK_STATUS_OK; } - } else if (hdr->type == BLK_OUT_REQ) { - if (blk_state->block_type == BLOCK_DISK) { - if (handle_write_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) { - *status = BLK_STATUS_ERR; - return -1; - } else { - *status = BLK_STATUS_OK; - } - + if (handle_write_op(blk_state, buf, &(hdr->sector), buf_desc->length) == -1) { + *status = BLK_STATUS_ERR; + return -1; } else { - *status = BLK_STATUS_NOT_SUPPORTED; + *status = BLK_STATUS_OK; } - } else if (hdr->type == BLK_SCSI_CMD) { PrintError("VIRTIO: SCSI Command Not supported!!!\n"); *status = BLK_STATUS_NOT_SUPPORTED; return -1; } - - PrintDebug("Returning Status: %d\n", *status); return 0; @@ -629,49 +577,35 @@ static int register_dev(struct virtio_dev_state * virtio, struct virtio_blk_stat } -int v3_virtio_register_cdrom(struct vm_device * dev, struct v3_cd_ops * ops, void * private_data) { - struct virtio_dev_state * virtio = (struct virtio_dev_state *)dev->private_data; - struct virtio_blk_state * blk_state = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state)); - memset(blk_state, 0, sizeof(struct virtio_blk_state)); - - register_dev(virtio, blk_state); - - blk_state->block_type = BLOCK_CDROM; - blk_state->cd_ops = ops; - blk_state->backend_data = private_data; - - blk_state->block_cfg.capacity = ops->get_capacity(private_data); - - return 0; -} +static int connect_fn(struct guest_info * info, + void * frontend_data, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data) { + struct virtio_dev_state * virtio = (struct virtio_dev_state *)frontend_data; -int v3_virtio_register_harddisk(struct vm_device * dev, struct v3_hd_ops * ops, void * private_data) { - struct virtio_dev_state * virtio = (struct virtio_dev_state *)dev->private_data; struct virtio_blk_state * blk_state = (struct virtio_blk_state *)V3_Malloc(sizeof(struct virtio_blk_state)); memset(blk_state, 0, sizeof(struct virtio_blk_state)); register_dev(virtio, blk_state); - blk_state->block_type = BLOCK_DISK; - blk_state->hd_ops = ops; + blk_state->ops = ops; blk_state->backend_data = private_data; blk_state->block_cfg.capacity = ops->get_capacity(private_data); PrintDebug("Virtio Capacity = %d -- 0x%p\n", (int)(virtio->block_cfg.capacity), - (void *)(addr_t)(virtio->block_cfg.capacity)); + (void *)(addr_t)(virtio->block_cfg.capacity)); return 0; } - - -static int virtio_init(struct guest_info * vm, void * cfg_data) { - struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data); +static int virtio_init(struct guest_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"); PrintDebug("Initializing VIRTIO Block device\n"); @@ -688,16 +622,19 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) { virtio_state->pci_bus = pci_bus; virtio_state->vm = vm; - struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_BLK", &dev_ops, virtio_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "LNX_VIRTIO_BLK"); + PrintError("Could not attach device %s\n", name); + 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); return -1; } return 0; } - - device_register("LNX_VIRTIO_BLK", virtio_init) diff --git a/palacios/src/devices/lnx_virtio_sym.c b/palacios/src/devices/lnx_virtio_sym.c index 8f4401e..d27429b 100644 --- a/palacios/src/devices/lnx_virtio_sym.c +++ b/palacios/src/devices/lnx_virtio_sym.c @@ -351,10 +351,11 @@ static struct v3_device_ops dev_ops = { -static int virtio_init(struct guest_info * vm, void * cfg_data) { - struct vm_device * pci_bus = v3_find_dev(vm, (char *)cfg_data); +static int virtio_init(struct guest_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"); PrintDebug("Initializing VIRTIO Symbiotic device\n"); @@ -368,9 +369,9 @@ static int virtio_init(struct guest_info * vm, void * cfg_data) { memset(virtio_state, 0, sizeof(struct virtio_sym_state)); - struct vm_device * dev = v3_allocate_device("LNX_VIRTIO_SYM", &dev_ops, virtio_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "LNX_VIRTIO_SYM"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/net_cd.c b/palacios/src/devices/net_cd.c deleted file mode 100644 index f980bab..0000000 --- a/palacios/src/devices/net_cd.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#include -#include -#include -#include - -#ifndef CONFIG_DEBUG_IDE -#undef PrintDebug -#define PrintDebug(fmt, args...) -#endif - - -#define NBD_READ_CMD 0x1 -#define NBD_WRITE_CMD 0x2 -#define NBD_CAPACITY_CMD 0x3 - -#define NBD_STATUS_OK 0x00 -#define NBD_STATUS_ERR 0xff - -struct cd_state { - uint64_t capacity; // in bytes - - int socket; - - uint32_t ip_addr; - uint16_t port; - - char disk_name[32]; - - struct vm_device * ide; - - uint_t bus; - uint_t drive; -}; - - -static int send_all(int socket, char * buf, int length) { - int bytes_sent = 0; - - PrintDebug("Sending %d bytes\n", length - bytes_sent); - while (bytes_sent < length) { - int tmp_bytes = V3_Send(socket, buf + bytes_sent, length - bytes_sent); - PrintDebug("Sent %d bytes\n", tmp_bytes); - - if (tmp_bytes == 0) { - PrintError("Connection Closed unexpectedly\n"); - return -1; - } - - bytes_sent += tmp_bytes; - } - - return 0; -} - - -static int recv_all(int socket, char * buf, int length) { - int bytes_read = 0; - - PrintDebug("Reading %d bytes\n", length - bytes_read); - while (bytes_read < length) { - int tmp_bytes = V3_Recv(socket, buf + bytes_read, length - bytes_read); - PrintDebug("Received %d bytes\n", tmp_bytes); - - if (tmp_bytes == 0) { - PrintError("Connection Closed unexpectedly\n"); - return -1; - } - - bytes_read += tmp_bytes; - } - - return 0; -} - -// CDs always read 2048 byte blocks... ? -static int cd_read(uint8_t * buf, int block_count, uint64_t lba, void * private_data) { - struct vm_device * cd_dev = (struct vm_device *)private_data; - struct cd_state * cd = (struct cd_state *)(cd_dev->private_data); - uint64_t offset = lba * ATAPI_BLOCK_SIZE; - int length = block_count * ATAPI_BLOCK_SIZE; - uint8_t status; - uint32_t ret_len = 0; - char nbd_cmd[4] = {0,0,0,0}; - - nbd_cmd[0] = NBD_READ_CMD; - - if (send_all(cd->socket, nbd_cmd, 4) == -1) { - PrintError("Error sending capacity command\n"); - return -1; - } - - if (send_all(cd->socket, (char *)&offset, 8) == -1) { - PrintError("Error sending read offset\n"); - return -1; - } - - if (send_all(cd->socket, (char *)&length, 4) == -1) { - PrintError("Error sending read length\n"); - return -1; - } - - if (recv_all(cd->socket, (char *)&status, 1) == -1) { - PrintError("Error receiving status\n"); - return -1; - } - - if (status != NBD_STATUS_OK) { - PrintError("NBD Error....\n"); - return -1; - } - - PrintDebug("Reading Data Ret Length\n"); - - if (recv_all(cd->socket, (char *)&ret_len, 4) == -1) { - PrintError("Error receiving Return read length\n"); - return -1; - } - - if (ret_len != length) { - PrintError("Read length mismatch (req=%d) (result=%d)\n", length, ret_len); - return -1; - } - - PrintDebug("Reading Data (%d bytes)\n", ret_len); - - if (recv_all(cd->socket, (char *)buf, ret_len) == -1) { - PrintError("Read Data Error\n"); - return -1; - } - - return 0; -} - - -static uint32_t cd_get_capacity(void * private_data) { - struct vm_device * cd_dev = (struct vm_device *)private_data; - struct cd_state * cd = (struct cd_state *)(cd_dev->private_data); - - return cd->capacity / ATAPI_BLOCK_SIZE; -} - -static struct v3_cd_ops cd_ops = { - .read = cd_read, - .get_capacity = cd_get_capacity, -}; - - - - -static int cd_free(struct vm_device * dev) { - return 0; -} - -static struct v3_device_ops dev_ops = { - .free = cd_free, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - - -static int socket_init(struct cd_state * cd) { - char header[64]; - - PrintDebug("Intializing Net CD\n"); - - cd->socket = V3_Create_TCP_Socket(); - - PrintDebug("CD socket: %d\n", cd->socket); - PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(cd->ip_addr), cd->port); - - V3_Connect_To_IP(cd->socket, v3_ntohl(cd->ip_addr), cd->port); - - - PrintDebug("Connected to NBD server\n"); - - //snprintf(header, 64, "V3_NBD_1 %s\n", cd->disk_name); - strcpy(header, "V3_NBD_1 "); - strncat(header, cd->disk_name, 32); - strncat(header, "\n", 1); - - - if (send_all(cd->socket, header, strlen(header)) == -1) { - PrintError("Error connecting to Network Block Device: %s\n", cd->disk_name); - return -1; - } - - // Cache Capacity - { - char nbd_cmd[4] = {0,0,0,0}; - - nbd_cmd[0] = NBD_CAPACITY_CMD; - - if (send_all(cd->socket, nbd_cmd, 4) == -1) { - PrintError("Error sending capacity command\n"); - return -1; - } - - if (recv_all(cd->socket, (char *)&(cd->capacity), 8) == -1) { - PrintError("Error Receiving Capacity\n"); - return -1; - } - - PrintDebug("Capacity: %p\n", (void *)(cd->capacity)); - } - - return 0; -} - -static int cd_init(struct guest_info * vm, void * cfg_data) { - struct net_cd_cfg * cfg = (struct net_cd_cfg *)cfg_data; - struct cd_state * cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state)); - - PrintDebug("Registering Net CD at %s:%d disk=%s\n", cfg->ip_str, cfg->port, cfg->disk_tag); - - strncpy(cd->disk_name, cfg->disk_tag, sizeof(cd->disk_name)); - cd->ip_addr = v3_inet_addr(cfg->ip_str); - cd->port = cfg->port; - - cd->ide = (struct vm_device * )v3_find_dev(vm, cfg->ide); - - if (cd->ide == 0) { - PrintError("Could not find backend %s\n", cfg->ide); - return -1; - } - - cd->bus = cfg->bus; - cd->drive = cfg->drive; - - struct vm_device * dev = v3_allocate_device("NET-CD", &dev_ops, cd); - - - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "NET-CD"); - return -1; - } - - if (socket_init(cd) == -1) { - PrintError("Could not initialize socket connection\n"); - return -1; - } - - PrintDebug("Registering CD\n"); - - if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "NET-CD", &cd_ops, dev) == -1) { - return -1; - } - - PrintDebug("intialization done\n"); - - return 0; -} - - - - -device_register("NET-CD", cd_init) diff --git a/palacios/src/devices/net_hd.c b/palacios/src/devices/netdisk.c similarity index 55% rename from palacios/src/devices/net_hd.c rename to palacios/src/devices/netdisk.c index 0894797..552de56 100644 --- a/palacios/src/devices/net_hd.c +++ b/palacios/src/devices/netdisk.c @@ -18,8 +18,7 @@ */ #include -#include -#include +#include #include #ifndef CONFIG_DEBUG_IDE @@ -36,7 +35,7 @@ #define NBD_STATUS_ERR 0xff -struct hd_state { +struct disk_state { uint64_t capacity; // in bytes int socket; @@ -46,10 +45,6 @@ struct hd_state { char disk_name[32]; - struct vm_device * ide; - - uint_t bus; - uint_t drive; }; @@ -94,33 +89,32 @@ static int recv_all(int socket, char * buf, int length) { // HDs always read 512 byte blocks... ? -static int hd_read(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { - struct vm_device * hd_dev = (struct vm_device *)private_data; - struct hd_state * hd = (struct hd_state *)(hd_dev->private_data); - int offset = lba * HD_SECTOR_SIZE; - int length = sector_count * HD_SECTOR_SIZE; +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 ; uint8_t status; uint32_t ret_len = 0; char nbd_cmd[4] = {0,0,0,0}; + uint64_t offset = lba; + uint64_t length = num_bytes; nbd_cmd[0] = NBD_READ_CMD; - if (send_all(hd->socket, nbd_cmd, 4) == -1) { + if (send_all(disk->socket, nbd_cmd, 4) == -1) { PrintError("Error sending read command\n"); return -1; } - if (send_all(hd->socket, (char *)&offset, 8) == -1) { + if (send_all(disk->socket, (char *)&offset, 8) == -1) { PrintError("Error sending read offset\n"); return -1; } - if (send_all(hd->socket, (char *)&length, 4) == -1) { + if (send_all(disk->socket, (char *)&length, 4) == -1) { PrintError("Error sending read length\n"); return -1; } - if (recv_all(hd->socket, (char *)&status, 1) == -1) { + if (recv_all(disk->socket, (char *)&status, 1) == -1) { PrintError("Error receiving status\n"); return -1; } @@ -132,7 +126,7 @@ static int hd_read(uint8_t * buf, int sector_count, uint64_t lba, void * privat PrintDebug("Reading Data Ret Length\n"); - if (recv_all(hd->socket, (char *)&ret_len, 4) == -1) { + if (recv_all(disk->socket, (char *)&ret_len, 4) == -1) { PrintError("Error receiving Return read length\n"); return -1; } @@ -144,7 +138,7 @@ static int hd_read(uint8_t * buf, int sector_count, uint64_t lba, void * privat PrintDebug("Reading Data (%d bytes)\n", ret_len); - if (recv_all(hd->socket, (char *)buf, ret_len) == -1) { + if (recv_all(disk->socket, (char *)buf, ret_len) == -1) { PrintError("Read Data Error\n"); return -1; } @@ -153,39 +147,38 @@ static int hd_read(uint8_t * buf, int sector_count, uint64_t lba, void * privat } -static int hd_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { - struct vm_device * hd_dev = (struct vm_device *)private_data; - struct hd_state * hd = (struct hd_state *)(hd_dev->private_data); - int offset = lba * HD_SECTOR_SIZE; - int length = sector_count * HD_SECTOR_SIZE; +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 ; + uint64_t offset = lba; + int length = num_bytes; uint8_t status; char nbd_cmd[4] = {0,0,0,0}; nbd_cmd[0] = NBD_WRITE_CMD; - if (send_all(hd->socket, nbd_cmd, 4) == -1) { + if (send_all(disk->socket, nbd_cmd, 4) == -1) { PrintError("Error sending write command\n"); return -1; } - if (send_all(hd->socket, (char *)&offset, 8) == -1) { + if (send_all(disk->socket, (char *)&offset, 8) == -1) { PrintError("Error sending write offset\n"); return -1; } - if (send_all(hd->socket, (char *)&length, 4) == -1) { + if (send_all(disk->socket, (char *)&length, 4) == -1) { PrintError("Error sending write length\n"); return -1; } PrintDebug("Writing Data (%d bytes)\n", length); - if (send_all(hd->socket, (char *)buf, length) == -1) { + if (send_all(disk->socket, (char *)buf, length) == -1) { PrintError("Write Data Error\n"); return -1; } - if (recv_all(hd->socket, (char *)&status, 1) == -1) { + if (recv_all(disk->socket, (char *)&status, 1) == -1) { PrintError("Error receiving status\n"); return -1; } @@ -199,77 +192,76 @@ static int hd_write(uint8_t * buf, int sector_count, uint64_t lba, void * privat } -static uint64_t hd_get_capacity(void * private_data) { - struct vm_device * hd_dev = (struct vm_device *)private_data; - struct hd_state * hd = (struct hd_state *)(hd_dev->private_data); +static uint64_t get_capacity(void * private_data) { + struct disk_state * disk = (struct disk_state *)private_data; - return hd->capacity / HD_SECTOR_SIZE; + return disk->capacity; } -static struct v3_hd_ops hd_ops = { - .read = hd_read, - .write = hd_write, - .get_capacity = hd_get_capacity, +static struct v3_dev_blk_ops blk_ops = { + .read = read, + .write = write, + .get_capacity = get_capacity, }; -static int hd_free(struct vm_device * dev) { +static int disk_free(struct vm_device * dev) { return 0; } static struct v3_device_ops dev_ops = { - .free = hd_free, + .free = disk_free, .reset = NULL, .start = NULL, .stop = NULL, }; -static int socket_init(struct hd_state * hd) { +static int socket_init(struct disk_state * disk) { char header[64]; - PrintDebug("Intializing Net HD\n"); + PrintDebug("Intializing Net Disk\n"); - hd->socket = V3_Create_TCP_Socket(); + disk->socket = V3_Create_TCP_Socket(); - PrintDebug("HD socket: %d\n", hd->socket); - PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(hd->ip_addr), hd->port); + PrintDebug("DISK socket: %d\n", disk->socket); + PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(disk->ip_addr), disk->port); - V3_Connect_To_IP(hd->socket, v3_ntohl(hd->ip_addr), hd->port); + V3_Connect_To_IP(disk->socket, v3_ntohl(disk->ip_addr), disk->port); PrintDebug("Connected to NBD server\n"); //snprintf(header, 64, "V3_NBD_1 %s\n", cd->disk_name); strcpy(header, "V3_NBD_1 "); - strncat(header, hd->disk_name, 32); + strncat(header, disk->disk_name, 32); strncat(header, "\n", 1); - if (send_all(hd->socket, header, strlen(header)) == -1) { - PrintError("Error connecting to Network Block Device: %s\n", hd->disk_name); + if (send_all(disk->socket, header, strlen(header)) == -1) { + PrintError("Error connecting to Network Block Device: %s\n", disk->disk_name); return -1; } - // Cache Capacity + // store local copy of capacity { char nbd_cmd[4] = {0,0,0,0}; nbd_cmd[0] = NBD_CAPACITY_CMD; - if (send_all(hd->socket, nbd_cmd, 4) == -1) { + if (send_all(disk->socket, nbd_cmd, 4) == -1) { PrintError("Error sending capacity command\n"); return -1; } - if (recv_all(hd->socket, (char *)&(hd->capacity), 8) == -1) { + if (recv_all(disk->socket, (char *)&(disk->capacity), 8) == -1) { PrintError("Error Receiving Capacity\n"); return -1; } - PrintDebug("Capacity: %p\n", (void *)(hd->capacity)); + PrintDebug("Capacity: %p\n", (void *)(disk->capacity)); } @@ -278,49 +270,46 @@ static int socket_init(struct hd_state * hd) { } -static int hd_init(struct guest_info * vm, void * cfg_data) { - struct hd_state * hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state)); - struct net_hd_cfg * cfg = (struct net_hd_cfg *)cfg_data; - - PrintDebug("Registering Net HD at %s:%d disk=%s\n", cfg->ip_str, cfg->port, cfg->disk_tag); +static int disk_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { + struct disk_state * disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state)); - strncpy(hd->disk_name, cfg->disk_tag, sizeof(hd->disk_name)); - hd->ip_addr = v3_inet_addr(cfg->ip_str); - hd->port = cfg->port; + 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"); - hd->ide = v3_find_dev(vm, cfg->ide); + v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); - if (hd->ide == 0) { - PrintError("Could not find backend %s\n", cfg->ide); - return -1; - } + PrintDebug("Registering Net disk at %s:%s disk=%s\n", ip_str, port_str, disk_tag); - hd->bus = cfg->bus; - hd->drive = cfg->drive; + strncpy(disk->disk_name, disk_tag, sizeof(disk->disk_name)); + disk->ip_addr = v3_inet_addr(ip_str); + disk->port = atoi(port_str); - struct vm_device * dev = v3_allocate_device("NET-HD", &dev_ops, hd); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, disk); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "NET-HD"); + PrintError("Could not attach device %s\n", name); return -1; } - if (socket_init(hd) == -1) { + if (socket_init(disk) == -1) { PrintError("could not initialize network connection\n"); return -1; } + PrintDebug("Registering Disk\n"); - PrintDebug("Registering HD\n"); - - if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "V3-NET-HD", &hd_ops, dev) == -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\n", name); return -1; } - + PrintDebug("intialization done\n"); return 0; } -device_register("NET-HD", hd_init) +device_register("NETDISK", disk_init) diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index 36da2aa..565c183 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -25,6 +25,9 @@ #include #include +#include +#include +#include #ifndef CONFIG_DEBUG_NVRAM #undef PrintDebug @@ -791,9 +794,10 @@ static struct v3_device_ops dev_ops = { -static int nvram_init(struct guest_info * vm, void * cfg_data) { +static int nvram_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { struct nvram_internal * nvram_state = NULL; - struct vm_device * ide = v3_find_dev(vm, (char *)cfg_data); + struct vm_device * ide = v3_find_dev(vm, v3_cfg_val(cfg, "storage")); + char * name = v3_cfg_val(cfg, "name"); if (!ide) { PrintError("Could not find IDE device\n"); @@ -807,11 +811,11 @@ static int nvram_init(struct guest_info * vm, void * cfg_data) { nvram_state->ide = ide; - struct vm_device * dev = v3_allocate_device("NVRAM", &dev_ops, nvram_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, nvram_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "NVRAM"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/os_debug.c b/palacios/src/devices/os_debug.c index 7abdeb0..a51dc19 100644 --- a/palacios/src/devices/os_debug.c +++ b/palacios/src/devices/os_debug.c @@ -103,18 +103,19 @@ static struct v3_device_ops dev_ops = { -static int debug_init(struct guest_info * vm, void * cfg_data) { +static int debug_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { struct debug_state * state = NULL; + char * name = v3_cfg_val(cfg, "name"); state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); PrintDebug("Creating OS Debug Device\n"); - struct vm_device * dev = v3_allocate_device("OS_DEBUG", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "OS_DEBUG"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/para_net.c b/palacios/src/devices/para_net.c index 13c5524..0bb7698 100644 --- a/palacios/src/devices/para_net.c +++ b/palacios/src/devices/para_net.c @@ -100,17 +100,18 @@ static struct v3_device_ops dev_ops = { -static int net_init(struct guest_info * vm, void * cfg_data) { +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"); state = (struct nic_state *)V3_Malloc(sizeof(struct nic_state)); PrintDebug("Creating VMNet Device\n"); - struct vm_device * dev = v3_allocate_device("VMNET", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "VMNET"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index 29c5435..06ccb6b 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -28,10 +28,13 @@ #include #include #include +#include #include #include + + #ifndef CONFIG_DEBUG_PCI #undef PrintDebug #define PrintDebug(fmt, args...) @@ -648,16 +651,17 @@ static struct v3_device_ops dev_ops = { -static int pci_init(struct guest_info * vm, void * cfg_data) { +static int pci_init(struct guest_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"); PrintDebug("PCI internal at %p\n",(void *)pci_state); - struct vm_device * dev = v3_allocate_device("PCI", &dev_ops, pci_state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, pci_state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "PCI"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/pci_passthrough.c b/palacios/src/devices/pci_passthrough.c index 25b2262..ce4b334 100644 --- a/palacios/src/devices/pci_passthrough.c +++ b/palacios/src/devices/pci_passthrough.c @@ -35,11 +35,11 @@ #include #include #include +#include // must include this to avoid dependency issue #include #include #include -#include // Hardcoded... Are these standard?? @@ -545,12 +545,11 @@ static int irq_handler(struct guest_info * info, struct v3_interrupt * intr, voi -static int passthrough_init(struct guest_info * info, void * cfg_data) { - struct pci_passthrough_cfg * cfg = (struct pci_passthrough_cfg *)cfg_data; +static int passthrough_init(struct guest_info * info, 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(info, cfg->pci_bus_name); - + struct vm_device * pci = v3_find_dev(info, v3_cfg_val(cfg, "bus")); + char * name = v3_cfg_val(cfg, "name"); memset(state, 0, sizeof(struct pt_dev_state)); @@ -560,28 +559,30 @@ static int passthrough_init(struct guest_info * info, void * cfg_data) { } state->pci_bus = pci; - strncpy(state->name, cfg->name, 32); - - + strncpy(state->name, name, 32); - dev = v3_allocate_device("PCI_PASSTHROUGH", &dev_ops, state); + dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(info, dev) == -1) { - PrintError("Could not attach device %s\n", "PCI_PASSTHROUGH"); + PrintError("Could not attach device %s\n", name); return -1; } - if (find_real_pci_dev(cfg->vendor_id, cfg->device_id, state) == -1) { - PrintError("Could not find PCI Device %x:%x\n", cfg->vendor_id, cfg->device_id); + if (find_real_pci_dev(atox(v3_cfg_val(cfg, "vendor_id")), + atox(v3_cfg_val(cfg, "device_id")), + state) == -1) { + PrintError("Could not find PCI Device %s:%s\n", + v3_cfg_val(cfg, "vendor_id"), + v3_cfg_val(cfg, "device_id")); return 0; } setup_virt_pci_dev(info, dev); - v3_hook_irq(info, 59, irq_handler, dev); - v3_hook_irq(info, 64, irq_handler, dev); + v3_hook_irq(info, atoi(v3_cfg_val(cfg, "irq")), irq_handler, dev); + // v3_hook_irq(info, 64, irq_handler, dev); return 0; } diff --git a/palacios/src/devices/piix3.c b/palacios/src/devices/piix3.c index 8c2872d..377c845 100644 --- a/palacios/src/devices/piix3.c +++ b/palacios/src/devices/piix3.c @@ -19,9 +19,13 @@ #include +#include +#include + #include #include + struct iort_reg { union { uint8_t value; @@ -441,10 +445,11 @@ static int setup_pci(struct vm_device * dev) { return 0; } -static int piix3_init(struct guest_info * vm, void * cfg_data) { +static int piix3_init(struct guest_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, (char *)cfg_data); + struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); + char * name = v3_cfg_val(cfg, "name"); if (!pci) { PrintError("Could not find PCI device\n"); @@ -454,10 +459,10 @@ static int piix3_init(struct guest_info * vm, void * cfg_data) { piix3->pci_bus = pci; piix3->type = V3_SB_PIIX3; - dev = v3_allocate_device("PIIX3", &dev_ops, piix3); + dev = v3_allocate_device(name, &dev_ops, piix3); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "PIIX3"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/ram_cd.c b/palacios/src/devices/ram_cd.c deleted file mode 100644 index 4a3baac..0000000 --- a/palacios/src/devices/ram_cd.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#include -#include -#include -#include - -#ifndef CONFIG_DEBUG_IDE -#undef PrintDebug -#define PrintDebug(fmt, args...) -#endif - - -struct cd_state { - addr_t disk_image; - uint32_t capacity; // in bytes - - struct vm_device * ide; - - uint_t bus; - uint_t drive; -}; - - -// CDs always read 2048 byte blocks... ? -static int cd_read(uint8_t * buf, int block_count, uint64_t lba, void * private_data) { - struct vm_device * cd_dev = (struct vm_device *)private_data; - struct cd_state * cd = (struct cd_state *)(cd_dev->private_data); - int offset = lba * ATAPI_BLOCK_SIZE; - int length = block_count * ATAPI_BLOCK_SIZE; - - PrintDebug("Reading RAM CD at (LBA=%d) offset %d (length=%d)\n", (uint32_t)lba, offset, length); - - memcpy(buf, (uint8_t *)(cd->disk_image + offset), length); - - return 0; -} - - -static uint32_t cd_get_capacity(void * private_data) { - struct vm_device * cd_dev = (struct vm_device *)private_data; - struct cd_state * cd = (struct cd_state *)(cd_dev->private_data); - PrintDebug("Querying RAM CD capacity (bytes=%d) (ret = %d)\n", - cd->capacity, cd->capacity / ATAPI_BLOCK_SIZE); - return cd->capacity / ATAPI_BLOCK_SIZE; -} - -static struct v3_cd_ops cd_ops = { - .read = cd_read, - .get_capacity = cd_get_capacity, -}; - - - - -static int cd_free(struct vm_device * dev) { - return 0; -} - -static struct v3_device_ops dev_ops = { - .free = cd_free, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - -static int cd_init(struct guest_info * vm, void * cfg_data) { - struct cd_state * cd = NULL; - struct ram_cd_cfg * cfg = (struct ram_cd_cfg *)cfg_data; - - if (cfg->size % ATAPI_BLOCK_SIZE) { - PrintError("CD image must be an integral of block size (ATAPI_BLOCK_SIZE=%d)\n", ATAPI_BLOCK_SIZE); - return -1; - } - - cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state)); - - PrintDebug("Registering Ram CD at %p (size=%d)\n", (void *)cfg->ramdisk, cfg->size); - - - cd->disk_image = cfg->ramdisk; - cd->capacity = cfg->size; - - cd->ide = v3_find_dev(vm, cfg->ide); - - if (cd->ide == 0) { - PrintError("Could not find backend %s\n", cfg->ide); - return -1; - } - - cd->bus = cfg->bus; - cd->drive = cfg->drive; - - struct vm_device * dev = v3_allocate_device("RAM-CD", &dev_ops, cd); - - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "RAM-CD"); - return -1; - } - - - if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "RAM-CD", &cd_ops, dev) == -1) { - return -1; - } - - return 0; -} - - -device_register("RAM-CD", cd_init) diff --git a/palacios/src/devices/ram_hd.c b/palacios/src/devices/ram_hd.c deleted file mode 100644 index c90e5be..0000000 --- a/palacios/src/devices/ram_hd.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#include -#include -#include - - - -#ifndef CONFIG_DEBUG_IDE -#undef PrintDebug -#define PrintDebug(fmt, args...) -#endif - -struct hd_state { - addr_t disk_image; - uint32_t capacity; // in bytes - - struct vm_device * ide; - - uint_t bus; - uint_t drive; -}; - - -// HDs always read 512 byte blocks... ? -static int hd_read(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { - struct vm_device * hd_dev = (struct vm_device *)private_data; - struct hd_state * hd = (struct hd_state *)(hd_dev->private_data); - int offset = lba * HD_SECTOR_SIZE; - int length = sector_count * HD_SECTOR_SIZE; - - // PrintDebug("Reading RAM HD at (LBA=%d) offset %d (length=%d)\n", (uint32_t)lba, offset, length); - - memcpy(buf, (uint8_t *)(hd->disk_image + offset), length); - - return 0; -} - - -static int hd_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { - struct vm_device * hd_dev = (struct vm_device *)private_data; - struct hd_state * hd = (struct hd_state *)(hd_dev->private_data); - int offset = lba * HD_SECTOR_SIZE; - int length = sector_count * HD_SECTOR_SIZE; - - memcpy((uint8_t *)(hd->disk_image + offset), buf, length); - - return 0; -} - - -static uint64_t hd_get_capacity(void * private_data) { - struct vm_device * hd_dev = (struct vm_device *)private_data; - struct hd_state * hd = (struct hd_state *)(hd_dev->private_data); - PrintDebug("Querying RAM HD capacity (bytes=%d) (ret = %d)\n", - hd->capacity, hd->capacity / HD_SECTOR_SIZE); - return hd->capacity / HD_SECTOR_SIZE; -} - -static struct v3_hd_ops hd_ops = { - .read = hd_read, - .write = hd_write, - .get_capacity = hd_get_capacity, -}; - - - - -static int hd_free(struct vm_device * dev) { - return 0; -} - -static struct v3_device_ops dev_ops = { - .free = hd_free, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - - - -static int hd_init(struct guest_info * vm, void * cfg_data) { - struct hd_state * hd = NULL; - struct ram_hd_cfg * cfg = (struct ram_hd_cfg *)cfg_data; - - if (cfg->size % HD_SECTOR_SIZE) { - PrintError("HD image must be an integral of sector size (HD_SECTOR_SIZE=%d)\n", HD_SECTOR_SIZE); - return -1; - } - - hd = (struct hd_state *)V3_Malloc(sizeof(struct hd_state)); - - PrintDebug("Registering Ram HDD at %p (size=%d)\n", (void *)cfg->ramdisk, cfg->size); - - hd->disk_image = cfg->ramdisk; - hd->capacity = cfg->size; - - hd->ide = v3_find_dev(vm, cfg->ide); - - if (hd->ide == 0) { - PrintError("Could not find backend %s\n", cfg->ide); - return -1; - } - - hd->bus = cfg->bus; - hd->drive = cfg->drive; - - struct vm_device * dev = v3_allocate_device("RAM-HD", &dev_ops, hd); - - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "RAM-HD"); - return -1; - } - - - if (v3_ide_register_harddisk(hd->ide, hd->bus, hd->drive, "RAM-HD", &hd_ops, dev) == -1) { - return -1; - } - - return 0; -} - - -device_register("RAM-HD", hd_init) diff --git a/palacios/src/devices/ramdisk.c b/palacios/src/devices/ramdisk.c new file mode 100644 index 0000000..9a2e716 --- /dev/null +++ b/palacios/src/devices/ramdisk.c @@ -0,0 +1,137 @@ +/* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include + + +#ifndef CONFIG_DEBUG_RAMDISK +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + +struct disk_state { + uint8_t * disk_image; + uint32_t capacity; // in bytes +}; + + +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); + + memcpy(buf, (uint8_t *)(disk->disk_image + lba), 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)); + + memcpy((uint8_t *)(disk->disk_image + 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; + struct v3_cfg_file * file = NULL; + char * name = v3_cfg_val(cfg, "name"); + 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 (!filename) { + PrintError("Missing filename (%s) for %s\n", filename, name); + return -1; + } + + file = v3_cfg_get_file(vm, filename); + + if (!file) { + PrintError("Invalid ramdisk file: %s\n", filename); + return -1; + } + + disk->disk_image = file->data; + disk->capacity = file->size; + 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); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", name); + 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")); + return -1; + } + + + return 0; +} + + +device_register("RAMDISK", disk_init) diff --git a/palacios/src/devices/sym_swap.c b/palacios/src/devices/sym_swap.c index d6740c4..dad0419 100644 --- a/palacios/src/devices/sym_swap.c +++ b/palacios/src/devices/sym_swap.c @@ -19,10 +19,8 @@ #include #include -#include #include -#define SWAP_CAPACITY (150 * 1024 * 1024) #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY #include @@ -55,8 +53,6 @@ union swap_header { struct swap_state { int active; - struct vm_device * blk_dev; - uint_t swapped_pages; uint_t unswapped_pages; @@ -134,7 +130,7 @@ static uint64_t swap_get_capacity(void * private_data) { PrintDebug("SymSwap: Getting Capacity %d\n", (uint32_t)(swap->capacity)); - return swap->capacity / HD_SECTOR_SIZE; + return swap->capacity; } @@ -144,11 +140,11 @@ static struct v3_swap_ops swap_ops = { -static int swap_read(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { +static int swap_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) { struct vm_device * dev = (struct vm_device *)private_data; struct swap_state * swap = (struct swap_state *)(dev->private_data); - uint32_t offset = lba * HD_SECTOR_SIZE; - uint32_t length = sector_count * HD_SECTOR_SIZE; + uint32_t offset = lba; + uint32_t length = num_bytes; /* @@ -184,11 +180,11 @@ static int swap_read(uint8_t * buf, int sector_count, uint64_t lba, void * priv -static int swap_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { +static int swap_write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) { struct vm_device * dev = (struct vm_device *)private_data; struct swap_state * swap = (struct swap_state *)(dev->private_data); - uint32_t offset = lba * HD_SECTOR_SIZE; - uint32_t length = sector_count * HD_SECTOR_SIZE; + uint32_t offset = lba; + uint32_t length = num_bytes; /* PrintDebug("SymSwap: Writing %d bytes to %p from %p\n", length, @@ -242,7 +238,7 @@ static int swap_free(struct vm_device * dev) { } -static struct v3_hd_ops hd_ops = { +static struct v3_dev_blk_ops blk_ops = { .read = swap_read, .write = swap_write, .get_capacity = swap_get_capacity, @@ -274,26 +270,22 @@ static void telemetry_cb(struct guest_info * info, void * private_data, char * h -static int swap_init(struct guest_info * vm, void * cfg_data) { +static int swap_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { struct swap_state * swap = NULL; - struct vm_device * virtio_blk = v3_find_dev(vm, (char *)cfg_data); + 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"); - if (!virtio_blk) { - PrintError("could not find Virtio backend\n"); + if (!frontend_cfg) { + PrintError("Initializing sym swap without a frontend device\n"); return -1; } PrintDebug("Creating Swap Device\n"); - if (virtio_blk == NULL) { - PrintError("Swap device requires a virtio block device\n"); - return -1; - } - - swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state) + ((SWAP_CAPACITY / 4096) / 8)); + swap = (struct swap_state *)V3_Malloc(sizeof(struct swap_state) + ((capacity / 4096) / 8)); - swap->blk_dev = virtio_blk; - swap->capacity = SWAP_CAPACITY; + swap->capacity = capacity; swap->swapped_pages = 0; swap->unswapped_pages = 0; @@ -301,22 +293,25 @@ static int swap_init(struct guest_info * vm, void * cfg_data) { swap->active = 0; swap->hdr = (union swap_header *)swap; - swap->swap_base_addr = (addr_t)V3_AllocPages(swap->capacity / 4096); swap->swap_space = (uint8_t *)V3_VAddr((void *)(swap->swap_base_addr)); - memset(swap->swap_space, 0, SWAP_CAPACITY); + memset(swap->swap_space, 0, swap->capacity); - memset(swap->usage_map, 0, ((SWAP_CAPACITY / 4096) / 8)); + memset(swap->usage_map, 0, ((swap->capacity / 4096) / 8)); - struct vm_device * dev = v3_allocate_device("SYM_SWAP", &dev_ops, swap); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, swap); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "SYM_SWAP"); + PrintError("Could not attach device %s\n", name); return -1; } - - v3_virtio_register_harddisk(virtio_blk, &hd_ops, dev); + 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")); + return -1; + } #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY if (vm->enable_telemetry) { diff --git a/palacios/src/devices/telnet_cons.c b/palacios/src/devices/telnet_cons.c index 4abe5a0..30e07d1 100644 --- a/palacios/src/devices/telnet_cons.c +++ b/palacios/src/devices/telnet_cons.c @@ -519,23 +519,24 @@ static int cons_server(void * arg) { } -static int cons_init(struct guest_info * vm, void * cfg_data) { - struct telnet_cons_cfg * cfg = (struct telnet_cons_cfg *)cfg_data; +static int cons_init(struct guest_info * vm, v3_cfg_tree_t * cfg) { struct cons_state * state = (struct cons_state *)V3_Malloc(sizeof(struct cons_state)); - struct vm_device * frontend = v3_find_dev(vm, cfg->frontend); + 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"); state->server_fd = 0; state->client_fd = 0; state->frontend_dev = frontend; - state->port = cfg->port; + state->port = atoi(v3_cfg_val(cfg, "port")); v3_lock_init(&(state->cons_lock)); - struct vm_device * dev = v3_allocate_device("TELNET_CONS", &dev_ops, state); + struct vm_device * dev = v3_allocate_device(name, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "TELNET_CONS"); + PrintError("Could not attach device %s\n", name); return -1; } diff --git a/palacios/src/devices/tmp_blk.c b/palacios/src/devices/tmp_blk.c deleted file mode 100644 index b8e08b2..0000000 --- a/palacios/src/devices/tmp_blk.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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 - * Copyright (c) 2008, The V3VEE Project - * All rights reserved. - * - * Author: Jack Lange - * - * This is free software. You are permitted to use, - * redistribute, and modify it as specified in the file "V3VEE_LICENSE". - */ - -#include -#include -#include - - -#define BLK_CAPACITY (500 * 1024 * 1024) - - - - -struct blk_state { - - struct vm_device * blk_dev; - - uint64_t capacity; - uint8_t * blk_space; - addr_t blk_base_addr; -}; - - - -static uint64_t blk_get_capacity(void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct blk_state * blk = (struct blk_state *)(dev->private_data); - - PrintDebug("SymBlk: Getting Capacity %d\n", (uint32_t)(blk->capacity)); - - return blk->capacity / HD_SECTOR_SIZE; -} - - - -static int blk_read(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct blk_state * blk = (struct blk_state *)(dev->private_data); - uint32_t offset = lba * HD_SECTOR_SIZE; - uint32_t length = sector_count * HD_SECTOR_SIZE; - - memcpy(buf, blk->blk_space + offset, length); - - return 0; -} - - - - -static int blk_write(uint8_t * buf, int sector_count, uint64_t lba, void * private_data) { - struct vm_device * dev = (struct vm_device *)private_data; - struct blk_state * blk = (struct blk_state *)(dev->private_data); - uint32_t offset = lba * HD_SECTOR_SIZE; - uint32_t length = sector_count * HD_SECTOR_SIZE; - - memcpy(blk->blk_space + offset, buf, length); - - return 0; -} - - -static int blk_free(struct vm_device * dev) { - return -1; -} - - -static struct v3_hd_ops hd_ops = { - .read = blk_read, - .write = blk_write, - .get_capacity = blk_get_capacity, -}; - - - -static struct v3_device_ops dev_ops = { - .free = blk_free, - .reset = NULL, - .start = NULL, - .stop = NULL, -}; - - - - -static int blk_init(struct guest_info * vm, void * cfg_data) { - struct blk_state * blk = NULL; - struct vm_device * virtio_blk = v3_find_dev(vm, (char *)cfg_data); - - if (!virtio_blk) { - PrintError("could not find Virtio backend\n"); - return -1; - } - - PrintDebug("Creating Blk Device\n"); - - if (virtio_blk == NULL) { - PrintError("Blk device requires a virtio block device\n"); - return -1; - } - - blk = (struct blk_state *)V3_Malloc(sizeof(struct blk_state) + ((BLK_CAPACITY / 4096) / 8)); - - blk->blk_dev = virtio_blk; - blk->capacity = BLK_CAPACITY; - - blk->blk_base_addr = (addr_t)V3_AllocPages(blk->capacity / 4096); - blk->blk_space = (uint8_t *)V3_VAddr((void *)(blk->blk_base_addr)); - memset(blk->blk_space, 0, BLK_CAPACITY); - - - struct vm_device * dev = v3_allocate_device("TMP_BLK", &dev_ops, blk); - - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", "TMP_BLK"); - return -1; - } - - - v3_virtio_register_harddisk(virtio_blk, &hd_ops, dev); - - - return 0; -} - -device_register("TMP_BLK", blk_init) diff --git a/palacios/src/devices/tmpdisk.c b/palacios/src/devices/tmpdisk.c new file mode 100644 index 0000000..a40aa55 --- /dev/null +++ b/palacios/src/devices/tmpdisk.c @@ -0,0 +1,126 @@ +/* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include + + +struct blk_state { + uint64_t capacity; + uint8_t * blk_space; + addr_t blk_base_addr; +}; + + + +static uint64_t blk_get_capacity(void * private_data) { + struct blk_state * blk = (struct blk_state *)private_data; + + PrintDebug("SymBlk: Getting Capacity %d\n", (uint32_t)(blk->capacity)); + + return blk->capacity; +} + + + +static int blk_read(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) { + struct blk_state * blk = (struct blk_state *)private_data; + + memcpy(buf, blk->blk_space + lba, num_bytes); + + return 0; +} + + + + +static int blk_write(uint8_t * buf, uint64_t lba, uint64_t num_bytes, void * private_data) { + struct blk_state * blk = (struct blk_state *)private_data; + + memcpy(blk->blk_space + lba, buf, num_bytes); + + return 0; +} + + +static int blk_free(struct vm_device * dev) { + return -1; +} + + +static struct v3_dev_blk_ops blk_ops = { + .read = blk_read, + .write = blk_write, + .get_capacity = blk_get_capacity, +}; + + + +static struct v3_device_ops dev_ops = { + .free = blk_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + + + + +static int blk_init(struct guest_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"); + uint64_t capacity = atoi(v3_cfg_val(cfg, "size")); + + if (!frontend_cfg) { + PrintError("Frontend Configuration not present\n"); + return -1; + } + + PrintDebug("Creating Blk Device\n"); + + + blk = (struct blk_state *)V3_Malloc(sizeof(struct blk_state) + ((capacity / 4096) / 8)); + + blk->capacity = capacity; + + blk->blk_base_addr = (addr_t)V3_AllocPages(capacity / 4096); + blk->blk_space = (uint8_t *)V3_VAddr((void *)(blk->blk_base_addr)); + memset(blk->blk_space, 0, capacity); + + + struct vm_device * dev = v3_allocate_device(name, &dev_ops, blk); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", name); + 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")); + return -1; + } + + + return 0; +} + +device_register("TMPDISK", blk_init) diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index ba7f5b3..09fe744 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -39,7 +39,6 @@ #include #include -#include #include #include @@ -267,18 +266,18 @@ static void Init_VMCB_BIOS(vmcb_t * vmcb, struct guest_info * vm_info) { } -static int init_svm_guest(struct guest_info * info, struct v3_vm_config * config_ptr) { - - - v3_pre_config_guest(info, config_ptr); +int v3_init_svm_vmcb(struct guest_info * info, v3_vm_class_t vm_class) { PrintDebug("Allocating VMCB\n"); info->vmm_data = (void*)Allocate_VMCB(); - - PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data); - Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info); - - v3_post_config_guest(info, config_ptr); + + if (vm_class == V3_PC_VM) { + PrintDebug("Initializing VMCB (addr=%p)\n", (void *)info->vmm_data); + Init_VMCB_BIOS((vmcb_t*)(info->vmm_data), info); + } else { + PrintError("Invalid VM class\n"); + return -1; + } return 0; } @@ -530,7 +529,7 @@ int v3_svm_enter(struct guest_info * info) { } -static int start_svm_guest(struct guest_info *info) { +int v3_start_svm_guest(struct guest_info *info) { // vmcb_saved_state_t * guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t*)(info->vmm_data)); // vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); @@ -690,15 +689,6 @@ void v3_init_svm_cpu(int cpu_id) { } -void v3_init_svm_hooks(struct v3_ctrl_ops * vmm_ops) { - - // Setup the SVM specific vmm operations - vmm_ops->init_guest = &init_svm_guest; - vmm_ops->start_guest = &start_svm_guest; - vmm_ops->has_nested_paging = &has_svm_nested_paging; - - return; -} diff --git a/palacios/src/palacios/svm_msr.c b/palacios/src/palacios/svm_msr.c index 82614f1..dabe82d 100644 --- a/palacios/src/palacios/svm_msr.c +++ b/palacios/src/palacios/svm_msr.c @@ -21,7 +21,7 @@ #include #include #include - +#include #define PENTIUM_MSRS_START 0x00000000 #define PENTIUM_MSRS_END 0x00001fff diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 1571c48..0a53a7f 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -38,6 +38,9 @@ struct v3_os_hooks * os_hooks = NULL; + + + static struct guest_info * allocate_guest() { void * info = V3_Malloc(sizeof(struct guest_info)); memset(info, 0, sizeof(struct guest_info)); @@ -45,24 +48,14 @@ static struct guest_info * allocate_guest() { } -struct vmm_init_arg { - int cpu_id; - struct v3_ctrl_ops * vmm_ops; -}; - static void init_cpu(void * arg) { - struct vmm_init_arg * vmm_arg = (struct vmm_init_arg *)arg; - int cpu_id = vmm_arg->cpu_id; - struct v3_ctrl_ops * vmm_ops = vmm_arg->vmm_ops; + uint32_t cpu_id = (uint32_t)(addr_t)arg; #ifdef CONFIG_SVM if (v3_is_svm_capable()) { PrintDebug("Machine is SVM Capable\n"); v3_init_svm_cpu(cpu_id); - if (cpu_id == 0) { - v3_init_svm_hooks(vmm_ops); - } } else #endif #ifdef CONFIG_VMX @@ -70,9 +63,6 @@ static void init_cpu(void * arg) { PrintDebug("Machine is VMX Capable\n"); v3_init_vmx_cpu(cpu_id); - if (cpu_id == 0) { - v3_init_vmx_hooks(vmm_ops); - } } else #endif { @@ -82,10 +72,10 @@ static void init_cpu(void * arg) { -void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops, int num_cpus) { + + +void Init_V3(struct v3_os_hooks * hooks, int num_cpus) { int i; - struct vmm_init_arg arg; - arg.vmm_ops = vmm_ops; // Set global variables. os_hooks = hooks; @@ -97,27 +87,68 @@ void Init_V3(struct v3_os_hooks * hooks, struct v3_ctrl_ops * vmm_ops, int num_c // Register all the possible device types v3_init_devices(); - #ifdef INSTRUMENT_VMM v3_init_instrumentation(); #endif - vmm_ops->allocate_guest = &allocate_guest; - - if ((hooks) && (hooks->call_on_cpu)) { for (i = 0; i < num_cpus; i++) { - arg.cpu_id = i; V3_Print("Initializing VMM extensions on cpu %d\n", i); - hooks->call_on_cpu(i, &init_cpu, &arg); + hooks->call_on_cpu(i, &init_cpu, (void *)(addr_t)i); } } +} + +v3_cpu_arch_t v3_get_cpu_type(int cpu_id) { + return v3_cpu_types[cpu_id]; +} +struct guest_info * v3_create_vm(void * cfg) { + struct guest_info * info = allocate_guest(); + + if (!info) { + PrintError("Could not allocate Guest\n"); + return NULL; + } + + if (v3_config_guest(info, cfg) == -1) { + PrintError("Could not configure guest\n"); + return NULL; + } + + return info; } +int v3_start_vm(struct guest_info * info, unsigned int cpu_mask) { + + info->cpu_id = v3_get_cpu_id(); + + V3_Print("V3 -- Starting VM\n"); + + switch (v3_cpu_types[info->cpu_id]) { +#ifdef CONFIG_SVM + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: + return v3_start_svm_guest(info); + break; +#endif +#if CONFIG_VMX && 0 + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + return v3_start_vmx_guest(info); + break; +#endif + default: + PrintError("Attemping to enter a guest on an invalid CPU\n"); + return -1; + } + + + return 0; +} #ifdef __V3_32BIT__ @@ -199,6 +230,21 @@ void v3_interrupt_cpu(struct guest_info * info, int logical_cpu) { +unsigned int v3_get_cpu_id() { + extern struct v3_os_hooks * os_hooks; + unsigned int ret = (unsigned int)-1; + + if ((os_hooks) && (os_hooks)->get_cpu) { + ret = os_hooks->get_cpu(); + } + + return ret; +} + + + + + int v3_vm_enter(struct guest_info * info) { switch (v3_cpu_types[info->cpu_id]) { #ifdef CONFIG_SVM @@ -218,3 +264,6 @@ int v3_vm_enter(struct guest_info * info) { return -1; } } + + + diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index 886aee7..627bb84 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -29,6 +29,9 @@ #include #include +#include +#include + #ifdef CONFIG_SYMBIOTIC #include @@ -38,96 +41,193 @@ #endif -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include "vmm_config_class.h" -/* -static const char * test_cfg_xml = \ -"\n \ -2048\n\ -\n\ -\n\ -\n\ -\n\ -"; -*/ +// This is used to access the configuration file index table +struct file_hdr { + uint32_t index; + uint32_t size; + uint64_t offset; +}; +struct file_idx_table { + uint64_t num_files; + struct file_hdr hdrs[0]; +}; -#include +static int setup_memory_map(struct guest_info * info, struct v3_config * config_ptr); +static int setup_devices(struct guest_info * info, struct v3_config * config_ptr); -#include + +char * v3_cfg_val(v3_cfg_tree_t * tree, char * tag) { + char * attrib = (char *)v3_xml_attr(tree, tag); + v3_cfg_tree_t * child_entry = v3_xml_child(tree, tag); + char * val = NULL; + + if ((child_entry != NULL) && (attrib != NULL)) { + PrintError("Duplicate Configuration parameters present for %s\n", tag); + return NULL; + } + + val = (attrib == NULL) ? v3_xml_txt(child_entry): attrib; + + return val; +} + +v3_cfg_tree_t * v3_cfg_subtree(v3_cfg_tree_t * tree, char * tag) { + return v3_xml_child(tree, tag); +} + +v3_cfg_tree_t * v3_cfg_next_branch(v3_cfg_tree_t * tree) { + return v3_xml_next(tree); +} -static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr); -static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr); -static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr); +struct v3_cfg_file * v3_cfg_get_file(struct guest_info * info, char * tag) { + struct v3_cfg_file * file = NULL; + file = (struct v3_cfg_file *)v3_htable_search(info->cfg_data->file_table, (addr_t)tag); + + return file; +} + + +static uint_t file_hash_fn(addr_t key) { + char * name = (char *)key; + return v3_hash_buffer((uchar_t *)name, strlen(name)); +} -#ifdef CONFIG_PASSTHROUGH_VIDEO -static int passthrough_mem_write(addr_t guest_addr, void * src, uint_t length, void * priv_data) { +static int file_eq_fn(addr_t key1, addr_t key2) { + char * name1 = (char *)key1; + char * name2 = (char *)key2; - return length; - // memcpy((void*)guest_addr, src, length); - PrintDebug("Write of %d bytes to %p\n", length, (void *)guest_addr); - PrintDebug("Write Value = %p\n", (void *)*(addr_t *)src); + return (strcmp(name1, name2) == 0); +} + +static struct v3_config * parse_config(void * cfg_blob) { + struct v3_config * cfg = NULL; + int offset = 0; + uint_t xml_len = 0; + struct file_idx_table * files = NULL; + v3_cfg_tree_t * file_tree = NULL; + + V3_Print("cfg data at %p\n", cfg_blob); + + if (memcmp(cfg_blob, "v3vee\0\0\0", 8) != 0) { + PrintError("Invalid Configuration Header\n"); + return NULL; + } + + offset += 8; + + cfg = (struct v3_config *)V3_Malloc(sizeof(struct v3_config)); + memset(cfg, 0, sizeof(struct v3_config)); + + cfg->blob = cfg_blob; + INIT_LIST_HEAD(&(cfg->file_list)); + cfg->file_table = v3_create_htable(0, file_hash_fn, file_eq_fn); - return length; + xml_len = *(uint32_t *)(cfg_blob + offset); + offset += 4; + + cfg->cfg = (v3_cfg_tree_t *)v3_xml_parse((uint8_t *)(cfg_blob + offset)); + offset += xml_len; + + offset += 8; + + files = (struct file_idx_table *)(cfg_blob + offset); + + V3_Print("Number of files in cfg: %d\n", (uint32_t)(files->num_files)); + + file_tree = v3_cfg_subtree(v3_cfg_subtree(cfg->cfg, "files"), "file"); + + while (file_tree) { + char * id = v3_cfg_val(file_tree, "id"); + char * index = v3_cfg_val(file_tree, "index"); + int idx = atoi(index); + struct file_hdr * hdr = &(files->hdrs[idx]); + struct v3_cfg_file * file = NULL; + + file = (struct v3_cfg_file *)V3_Malloc(sizeof(struct v3_cfg_file)); + + if (!file) { + PrintError("Could not allocate file structure\n"); + return NULL; + } + + + V3_Print("File index=%d id=%s\n", idx, id); + + strncpy(file->tag, id, 256); + file->size = hdr->size; + file->data = cfg_blob + hdr->offset; + + V3_Print("Storing file data offset = %d, size=%d\n", (uint32_t)hdr->offset, hdr->size); + V3_Print("file data at %p\n", file->data); + list_add( &(file->file_node), &(cfg->file_list)); + + V3_Print("Keying file to name\n"); + v3_htable_insert(cfg->file_table, (addr_t)(file->tag), (addr_t)(file)); + + V3_Print("Iterating to next file\n"); + + file_tree = v3_cfg_next_branch(file_tree); + } + + V3_Print("Configuration parsed successfully\n"); + + return cfg; } -#endif -int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) { - extern v3_cpu_arch_t v3_cpu_types[]; - - - /* - { - struct v3_xml * cfg = v3_xml_parse((char *)test_cfg_xml); - struct v3_xml * devs = NULL; - struct v3_xml * tmp = NULL; - PrintError("Parsed XML COnfig %s\n", v3_xml_name(cfg)); - - PrintError("memory=%s\n", v3_xml_txt(v3_xml_child(cfg, "memory"))); - - devs = v3_xml_child(cfg, "devices"); - - for (tmp = v3_xml_child(devs, "device"); tmp; tmp = v3_xml_next(tmp)) { - PrintError("Device: %s, id=%s\n", - v3_xml_name(tmp), - v3_xml_attr(tmp, "id")); - } - v3_xml_free(cfg); - - return -1; - } - */ - - // Amount of ram the Guest will have, rounded to a 4K page boundary - info->mem_size = config_ptr->mem_size & ~(addr_t)0xfff; - - info->cpu_id = config_ptr->guest_cpu; + +static int pre_config_guest(struct guest_info * info, struct v3_config * config_ptr) { + extern v3_cpu_arch_t v3_cpu_types[]; + char * memory_str = v3_cfg_val(config_ptr->cfg, "memory"); + char * paging = v3_cfg_val(config_ptr->cfg, "paging"); + char * schedule_hz_str = v3_cfg_val(config_ptr->cfg, "schedule_hz"); + char * vm_class = v3_cfg_val(config_ptr->cfg, "class"); + uint32_t sched_hz = 100; // set the schedule frequency to 100 HZ + + if (!memory_str) { + PrintError("Memory is a required configuration parameter\n"); + return -1; + } + + PrintDebug("Memory=%s\n", memory_str); + + // Amount of ram the Guest will have, always in MB + info->mem_size = atoi(memory_str) * 1024 * 1024; + + if (strcasecmp(vm_class, "PC") == 0) { + info->vm_class = V3_PC_VM; + } else { + PrintError("Invalid VM class\n"); + return -1; + } + /* * Initialize the subsystem data strutures */ #ifdef CONFIG_TELEMETRY - // This should go first, because other subsystems will depend on the guest_info flag - if (config_ptr->enable_telemetry) { - info->enable_telemetry = 1; - v3_init_telemetry(info); - } else { - info->enable_telemetry = 0; + { + char * telemetry = v3_cfg_val(config_ptr->cfg, "telemetry"); + + // This should go first, because other subsystems will depend on the guest_info flag + if ((telemetry) && (strcasecmp(telemetry, "enable") == 0)) { + info->enable_telemetry = 1; + v3_init_telemetry(info); + } else { + info->enable_telemetry = 0; + } } #endif @@ -144,7 +244,7 @@ int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_p } if ((v3_cpu_types[info->cpu_id] == V3_SVM_REV3_CPU) && - (config_ptr->enable_nested_paging == 1)) { + (paging) && (strcasecmp(paging, "nested") == 0)) { PrintDebug("Guest Page Mode: NESTED_PAGING\n"); info->shdw_pg_mode = NESTED_PAGING; } else { @@ -168,25 +268,22 @@ int v3_pre_config_guest(struct guest_info * info, struct v3_vm_config * config_p v3_init_sym_swap(info); #endif - - if (config_ptr->schedule_freq == 0) { - // set the schedule frequency to 100 HZ - config_ptr->schedule_freq = 100; + if (schedule_hz_str) { + sched_hz = atoi(schedule_hz_str); } - PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), (void *)config_ptr->schedule_freq); + PrintDebug("CPU_KHZ = %d, schedule_freq=%p\n", V3_CPU_KHZ(), + (void *)(addr_t)sched_hz); - info->yield_cycle_period = (V3_CPU_KHZ() * 1000) / config_ptr->schedule_freq; + info->yield_cycle_period = (V3_CPU_KHZ() * 1000) / sched_hz; - // Initial CPU operating mode - info->cpu_mode = REAL; - info->mem_mode = PHYSICAL_MEM; + return 0; } -int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ptr) { +static int post_config_guest(struct guest_info * info, struct v3_config * config_ptr) { // Configure the memory map for the guest if (setup_memory_map(info, config_ptr) == -1) { @@ -206,346 +303,134 @@ int v3_post_config_guest(struct guest_info * info, struct v3_vm_config * config_ info->run_state = VM_STOPPED; - info->vm_regs.rdi = 0; - info->vm_regs.rsi = 0; - info->vm_regs.rbp = 0; - info->vm_regs.rsp = 0; - info->vm_regs.rbx = 0; - info->vm_regs.rdx = 0; - info->vm_regs.rcx = 0; - info->vm_regs.rax = 0; - - return 0; -} - - - - - -/* TODO: - * The amount of guest memory is stored in info->mem_size - * We need to make sure the memory map extends to cover it - */ -static int setup_memory_map(struct guest_info * info, struct v3_vm_config * config_ptr) { - -#ifdef CONFIG_PASSTHROUGH_VIDEO - PrintDebug("Setting up memory map (memory size=%dMB)\n", (uint_t)(info->mem_size / (1024 * 1024))); - - // VGA frame buffer - if (1) { - if (v3_add_shadow_mem(info, 0xa0000, 0xc0000, 0xa0000) == -1) { - PrintError("Could not map VGA framebuffer\n"); + if (info->vm_class == V3_PC_VM) { + if (post_config_pc(info, config_ptr) == -1) { + PrintError("PC Post configuration failure\n"); return -1; } } else { - v3_hook_write_mem(info, 0xa0000, 0xc0000, 0xa0000, passthrough_mem_write, NULL); - } -#endif - -#define VGABIOS_START 0x000c0000 -#define ROMBIOS_START 0x000f0000 - - /* layout vgabios */ - { - extern uint8_t v3_vgabios_start[]; - extern uint8_t v3_vgabios_end[]; - - addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START); - memcpy(V3_VAddr((void *)vgabios_dst), v3_vgabios_start, v3_vgabios_end - v3_vgabios_start); - } - - /* layout rombios */ - { - extern uint8_t v3_rombios_start[]; - extern uint8_t v3_rombios_end[]; - - addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START); - memcpy(V3_VAddr((void *)rombios_dst), v3_rombios_start, v3_rombios_end - v3_rombios_start); - } - -#ifdef CONFIG_CRAY_XT - { -#define SEASTAR_START 0xffe00000 -#define SEASTAR_END 0xffffffff - // Map the Seastar straight through - if (v3_add_shadow_mem(info, SEASTAR_START, SEASTAR_END, SEASTAR_START) == -1) { - PrintError("Could not map through the seastar\n"); - return -1; - } + PrintError("Invalid VM Class\n"); + return -1; } -#endif - v3_print_mem_map(info); return 0; } -static int setup_devices(struct guest_info * info, struct v3_vm_config * config_ptr) { - - v3_create_device(info, "8259A", NULL); - v3_create_device(info, "KEYBOARD", NULL); - v3_create_device(info, "8254_PIT", NULL); - v3_create_device(info, "BOCHS_DEBUG", NULL); - v3_create_device(info, "OS_DEBUG", NULL); - v3_create_device(info, "LAPIC", NULL); - v3_create_device(info, "IOAPIC", "LAPIC"); - v3_create_device(info, "VMNET", NULL); - +int v3_config_guest(struct guest_info * info, void * cfg_blob) { + v3_cpu_arch_t cpu_type = v3_get_cpu_type(v3_get_cpu_id()); - v3_create_device(info, "CGA_VIDEO", (void *)1); - { - struct telnet_cons_cfg cons_cfg = {"CGA_VIDEO", 19997}; - v3_create_device(info, "TELNET_CONSOLE", &cons_cfg); + if (cpu_type == V3_INVALID_CPU) { + PrintError("Configuring guest on invalid CPU\n"); + return -1; } - if (config_ptr->enable_pci == 1) { - struct ide_cfg ide_config = {"PCI", "PIIX3"}; - struct pci_passthrough_cfg pci_qemu_pt_cfg = {"PCI", "E1000", 0x8086, 0x100e}; - struct pci_passthrough_cfg pci_hw_pt_cfg = {"PCI", "E1000", 0x8086, 0x107c}; - - v3_create_device(info, "PCI", NULL); - v3_create_device(info, "i440FX", "PCI"); - v3_create_device(info, "PIIX3", "PCI"); - - - v3_create_device(info, "LNX_VIRTIO_SYM", "PCI"); - v3_create_device(info, "LNX_VIRTIO_BLK", "PCI"); - v3_create_device(info, "LNX_VIRTIO_BALLOON", "PCI"); - v3_create_device(info, "SYM_SWAP", "LNX_VIRTIO_BLK"); - // v3_create_device(info, "TMP_BLK", "LNX_VIRTIO_BLK"); + info->cfg_data = parse_config(cfg_blob); - v3_create_device(info, "IDE", &ide_config); - - v3_create_device(info, "PCI_PASSTHROUGH", &pci_qemu_pt_cfg); - v3_create_device(info, "PCI_PASSTHROUGH", &pci_hw_pt_cfg); + if (!info->cfg_data) { + PrintError("Could not parse configuration\n"); + return -1; + } + V3_Print("Preconfiguration\n"); - } else { - v3_create_device(info, "IDE", NULL); + if (pre_config_guest(info, info->cfg_data) == -1) { + PrintError("Error in preconfiguration\n"); + return -1; } + V3_Print("Arch dependent configuration\n"); - if (config_ptr->pri_disk_type != NONE) { - if (config_ptr->pri_disk_type == CDROM) { - if (config_ptr->pri_disk_con == RAM) { - struct ram_cd_cfg cfg = {"IDE", 0, 0, - (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), - config_ptr->pri_disk_info.ram.size}; - - PrintDebug("Creating RAM CD\n"); - - v3_create_device(info, "RAM-CD", &cfg); - } else if (config_ptr->pri_disk_con == NETWORK) { - struct net_cd_cfg cfg = {"IDE", 0, 0, - config_ptr->pri_disk_info.net.ip_str, - config_ptr->pri_disk_info.net.port, - config_ptr->pri_disk_info.net.disk_name}; - PrintDebug("Creating NET CD\n"); - - v3_create_device(info, "NET-CD", &cfg); - } - } else if (config_ptr->pri_disk_type == HARDDRIVE) { - if (config_ptr->pri_disk_con == RAM) { - struct ram_hd_cfg cfg = {"IDE", 0, 0, - (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), - config_ptr->pri_disk_info.ram.size}; - - PrintDebug("Creating RAM HD\n"); - - v3_create_device(info, "RAM-HD", &cfg); - } else if (config_ptr->pri_disk_con == NETWORK) { - struct net_hd_cfg cfg = {"IDE", 0, 0, - config_ptr->pri_disk_info.net.ip_str, - config_ptr->pri_disk_info.net.port, - config_ptr->pri_disk_info.net.disk_name}; - PrintDebug("Creating NET HD\n"); - v3_create_device(info, "NET-HD", &cfg); - } - - } else if (config_ptr->pri_disk_type == VIRTIO) { - if (config_ptr->pri_disk_con == RAM) { - struct ram_hd_cfg cfg = {"LNX_VIRTIO_BLK", 0, 0, - (addr_t)(config_ptr->pri_disk_info.ram.data_ptr), - config_ptr->pri_disk_info.ram.size}; - - PrintDebug("Creating Virtio RAM HD\n"); - - v3_create_device(info, "RAM-HD", &cfg); - } - + // init SVM/VMX +#ifdef CONFIG_SVM + if ((cpu_type == V3_SVM_CPU) || (cpu_type == V3_SVM_REV3_CPU)) { + if (v3_init_svm_vmcb(info, info->vm_class) == -1) { + PrintError("Error in SVM initialization\n"); + return -1; + } + } +#endif +#ifdef CONFIG_VMX + else if ((cpu_type == V3_VMX_CPU) || (cpu_type == V3_VMX_EPT_CPU)) { + if (v3_init_vmx_vmcs(info, info->vm_class) == -1) { + PrintError("Error in VMX initialization\n"); + return -1; } } +#endif + else { + PrintError("Invalid CPU Type\n"); + return -1; + } + V3_Print("Post Configuration\n"); - - if (config_ptr->sec_disk_type != NONE) { - if (config_ptr->sec_disk_type == CDROM) { - if (config_ptr->sec_disk_con == RAM) { - struct ram_cd_cfg cfg = {"IDE", 0, 1, - (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), - config_ptr->sec_disk_info.ram.size}; - - PrintDebug("Creating RAM CD\n"); - v3_create_device(info, "RAM-CD", &cfg); - } else if (config_ptr->sec_disk_con == NETWORK) { - struct net_cd_cfg cfg = {"IDE", 0, 1, - config_ptr->sec_disk_info.net.ip_str, - config_ptr->sec_disk_info.net.port, - config_ptr->sec_disk_info.net.disk_name}; - - PrintDebug("Creating NET CD\n"); - v3_create_device(info, "NET-CD", &cfg); - } - } else if (config_ptr->sec_disk_type == HARDDRIVE) { - if (config_ptr->sec_disk_con == RAM) { - struct ram_hd_cfg cfg = {"IDE", 0, 1, - (addr_t)(config_ptr->sec_disk_info.ram.data_ptr), - config_ptr->sec_disk_info.ram.size}; - PrintDebug("Creating RAM HD\n"); - v3_create_device(info, "RAM-HD", &cfg); - } else if (config_ptr->sec_disk_con == NETWORK) { - struct net_hd_cfg cfg = {"IDE", 0, 1, - config_ptr->sec_disk_info.net.ip_str, - config_ptr->sec_disk_info.net.port, - config_ptr->sec_disk_info.net.disk_name}; - PrintDebug("Creating NET HD\n"); - v3_create_device(info, "NET-HD", &cfg); - } - } + if (post_config_guest(info, info->cfg_data) == -1) { + PrintError("Error in postconfiguration\n"); + return -1; } + V3_Print("Configuration successfull\n"); + return 0; +} -#ifdef CONFIG_GENERIC - configure_generic(info, config_ptr); -#endif - // This should go last because it requires information about the Harddrives - v3_create_device(info, "NVRAM", "IDE"); - - PrintDebugDevMgr(info); - return 0; -} +static int setup_memory_map(struct guest_info * info, struct v3_config * config_ptr) { + v3_cfg_tree_t * mem_region = v3_cfg_subtree(v3_cfg_subtree(config_ptr->cfg, "memmap"), "region"); -#ifdef CONFIG_GENERIC -static int configure_generic(struct guest_info * info, struct v3_vm_config * config_ptr) { - PrintDebug("Creating Generic Device\n"); - v3_create_device(info, "GENERIC", NULL); - + while (mem_region) { + addr_t start_addr = atox(v3_cfg_val(mem_region, "start")); + addr_t end_addr = atox(v3_cfg_val(mem_region, "end")); + addr_t host_addr = atox(v3_cfg_val(mem_region, "host_addr")); - struct vm_device * generic = v3_find_dev(info, "GENERIC"); + + if (v3_add_shadow_mem(info, start_addr, end_addr, host_addr) == -1) { + PrintError("Could not map memory region: %p-%p => %p\n", + (void *)start_addr, (void *)end_addr, (void *)host_addr); + return -1; + } - if (!generic) { - PrintError("Could not find generic device\n"); - return -1; + mem_region = v3_cfg_next_branch(mem_region); } - // port 0x92: A20 enable/disable (bit 2) (This causes an MMU flush) - - - // Make the DMA controller invisible - v3_generic_add_port_range(generic, 0x00, 0x07, GENERIC_PRINT_AND_IGNORE); // DMA 1 channels 0,1,2,3 (address, counter) - v3_generic_add_port_range(generic, 0xc0, 0xc7, GENERIC_PRINT_AND_IGNORE); // DMA 2 channels 4,5,6,7 (address, counter) - v3_generic_add_port_range(generic, 0x87, 0x87, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 0 page register - v3_generic_add_port_range(generic, 0x83, 0x83, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 1 page register - v3_generic_add_port_range(generic, 0x81, 0x81, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 2 page register - v3_generic_add_port_range(generic, 0x82, 0x82, GENERIC_PRINT_AND_IGNORE); // DMA 1 channel 3 page register - v3_generic_add_port_range(generic, 0x8f, 0x8f, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 4 page register - v3_generic_add_port_range(generic, 0x8b, 0x8b, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 5 page register - v3_generic_add_port_range(generic, 0x89, 0x89, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 6 page register - v3_generic_add_port_range(generic, 0x8a, 0x8a, GENERIC_PRINT_AND_IGNORE); // DMA 2 channel 7 page register - v3_generic_add_port_range(generic, 0x08, 0x0f, GENERIC_PRINT_AND_IGNORE); // DMA 1 misc registers (csr, req, smask,mode,clearff,reset,enable,mmask) - v3_generic_add_port_range(generic, 0xd0, 0xde, GENERIC_PRINT_AND_IGNORE); // DMA 2 misc registers - - - - - // Make the Serial ports invisible - - v3_generic_add_port_range(generic, 0x3f8, 0x3f8+7, GENERIC_PRINT_AND_IGNORE); // COM 1 - v3_generic_add_port_range(generic, 0x2f8, 0x2f8+7, GENERIC_PRINT_AND_IGNORE); // COM 2 - + return 0; +} - - v3_generic_add_port_range(generic, 0x3e8, 0x3e8+7, GENERIC_PRINT_AND_IGNORE); // COM 3 - v3_generic_add_port_range(generic, 0x2e8, 0x2e8+7, GENERIC_PRINT_AND_IGNORE); // COM 4 - - - // Make the PCI bus invisible (at least it's configuration) - - //v3_generic_add_port_range(generic, 0xcf8, 0xcf8, GENERIC_PRINT_AND_IGNORE); // PCI Config Address - //v3_generic_add_port_range(generic, 0xcfc, 0xcfc, GENERIC_PRINT_AND_IGNORE); // PCI Config Data - - - -#if 0 - if (!use_ramdisk) { - // Monitor the IDE controllers (very slow) - v3_generic_add_port_range(generic, 0x170, 0x178, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1 - v3_generic_add_port_range(generic, 0x376, 0x377, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 1 - } - - v3_generic_add_port_range(generic, 0x1f0, 0x1f8, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0 - v3_generic_add_port_range(generic, 0x3f6, 0x3f7, GENERIC_PRINT_AND_PASSTHROUGH); // IDE 0 -#endif - - -#if 0 - - // Make the floppy controllers invisible - - v3_generic_add_port_range(generic, 0x3f0, 0x3f2, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (base,statusa/statusb,DOR) - v3_generic_add_port_range(generic, 0x3f4, 0x3f5, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (mainstat/datarate,data) - v3_generic_add_port_range(generic, 0x3f7, 0x3f7, GENERIC_PRINT_AND_IGNORE); // Primary floppy controller (DIR) - v3_generic_add_port_range(generic, 0x370, 0x372, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (base,statusa/statusb,DOR) - v3_generic_add_port_range(generic, 0x374, 0x375, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (mainstat/datarate,data) - v3_generic_add_port_range(generic, 0x377, 0x377, GENERIC_PRINT_AND_IGNORE); // Secondary floppy controller (DIR) - -#endif -#if 1 - // Make the parallel port invisible - - v3_generic_add_port_range(generic, 0x378, 0x37f, GENERIC_PRINT_AND_IGNORE); -#endif -#ifdef CONFIG_PASTHROUGH_VIDEO +static int setup_devices(struct guest_info * info, struct v3_config * config_ptr) { + v3_cfg_tree_t * device = v3_cfg_subtree(v3_cfg_subtree(config_ptr->cfg, "devices"), "device"); - // Monitor graphics card operations - v3_generic_add_port_range(generic, 0x3b0, 0x3bb, GENERIC_PRINT_AND_PASSTHROUGH); - v3_generic_add_port_range(generic, 0x3c0, 0x3df, GENERIC_PRINT_AND_PASSTHROUGH); - -#endif + while (device) { + char * id = v3_cfg_val(device, "id"); + V3_Print("configuring device %s\n", id); -#if 1 - // Make the ISA PNP features invisible - - v3_generic_add_port_range(generic, 0x274, 0x277, GENERIC_PRINT_AND_IGNORE); - v3_generic_add_port_range(generic, 0x279, 0x279, GENERIC_PRINT_AND_IGNORE); - v3_generic_add_port_range(generic, 0xa79, 0xa79, GENERIC_PRINT_AND_IGNORE); -#endif + if (v3_create_device(info, id, device) == -1) { + PrintError("Error creating device %s\n", id); + return -1; + } + + device = v3_cfg_next_branch(device); + } -#if 1 - // Monitor any network card (realtek ne2000) operations - v3_generic_add_port_range(generic, 0xc100, 0xc1ff, GENERIC_PRINT_AND_PASSTHROUGH); -#endif + v3_print_dev_mgr(info); - // v3_generic_add_port_range(generic, 0x378, 0x400, GENERIC_PRINT_AND_IGNORE); - return 0; } -#endif + + diff --git a/palacios/src/palacios/vmm_config_class.h b/palacios/src/palacios/vmm_config_class.h new file mode 100644 index 0000000..36fee9b --- /dev/null +++ b/palacios/src/palacios/vmm_config_class.h @@ -0,0 +1,63 @@ + /* + * 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 + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +static int post_config_pc(struct guest_info * info, struct v3_config * config_ptr) { + + + info->cpu_mode = REAL; + info->mem_mode = PHYSICAL_MEM; + + + info->vm_regs.rdi = 0; + info->vm_regs.rsi = 0; + info->vm_regs.rbp = 0; + info->vm_regs.rsp = 0; + info->vm_regs.rbx = 0; + info->vm_regs.rdx = 0; + info->vm_regs.rcx = 0; + info->vm_regs.rax = 0; + + +#define VGABIOS_START 0x000c0000 +#define ROMBIOS_START 0x000f0000 + + /* layout vgabios */ + { + extern uint8_t v3_vgabios_start[]; + extern uint8_t v3_vgabios_end[]; + + addr_t vgabios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), VGABIOS_START); + memcpy(V3_VAddr((void *)vgabios_dst), v3_vgabios_start, v3_vgabios_end - v3_vgabios_start); + } + + /* layout rombios */ + { + extern uint8_t v3_rombios_start[]; + extern uint8_t v3_rombios_end[]; + + addr_t rombios_dst = v3_get_shadow_addr(&(info->mem_map.base_region), ROMBIOS_START); + memcpy(V3_VAddr((void *)rombios_dst), v3_rombios_start, v3_rombios_end - v3_rombios_start); + } + + v3_print_mem_map(info); + + return 0; +} + diff --git a/palacios/src/palacios/vmm_cpuid.c b/palacios/src/palacios/vmm_cpuid.c index d0c3a32..34040d8 100644 --- a/palacios/src/palacios/vmm_cpuid.c +++ b/palacios/src/palacios/vmm_cpuid.c @@ -20,7 +20,7 @@ #include #include #include - +#include void v3_init_cpuid_map(struct guest_info * info) { diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index c212958..c7a8f95 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -94,6 +94,14 @@ int v3_init_dev_mgr(struct guest_info * info) { mgr->dev_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); + INIT_LIST_HEAD(&(mgr->blk_list)); + INIT_LIST_HEAD(&(mgr->net_list)); + INIT_LIST_HEAD(&(mgr->console_list)); + + mgr->blk_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); + mgr->net_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); + mgr->console_table = v3_create_htable(0, dev_hash_fn, dev_eq_fn); + return 0; } @@ -113,7 +121,7 @@ int v3_dev_mgr_deinit(struct guest_info * info) { -int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg_data) { +int v3_create_device(struct guest_info * info, const char * dev_name, v3_cfg_tree_t * cfg) { int (*dev_init)(struct guest_info * info, void * cfg_data); dev_init = (void *)v3_htable_search(master_dev_table, (addr_t)dev_name); @@ -124,7 +132,7 @@ int v3_create_device(struct guest_info * info, const char * dev_name, void * cfg } - if (dev_init(info, cfg_data) == -1) { + if (dev_init(info, cfg) == -1) { PrintError("Could not initialize Device %s\n", dev_name); return -1; } @@ -142,6 +150,10 @@ void v3_free_device(struct vm_device * dev) { struct vm_device * v3_find_dev(struct guest_info * info, const char * dev_name) { struct vmm_dev_mgr * mgr = &(info->dev_mgr); + if (!dev_name) { + return NULL; + } + return (struct vm_device *)v3_htable_search(mgr->dev_table, (addr_t)dev_name); } @@ -213,31 +225,81 @@ int v3_attach_device(struct guest_info * vm, struct vm_device * dev ) { } -#ifdef CONFIG_DEBUG_DEV_MGR -void PrintDebugDevMgr(struct guest_info * info) { +void v3_print_dev_mgr(struct guest_info * info) { struct vmm_dev_mgr * mgr = &(info->dev_mgr); struct vm_device * dev; - PrintDebug("%d devices registered with manager\n", mgr->num_devs); + V3_Print("%d devices registered with manager\n", mgr->num_devs); list_for_each_entry(dev, &(mgr->dev_list), dev_link) { - PrintDebugDev(dev); - PrintDebug("next..\n"); + V3_Print("Device: %s\n", dev->name); } return; } -void PrintDebugDev(struct vm_device * dev) { - PrintDebug("Device: %s\n", dev->name); + + +struct blk_frontend { + int (*connect)(struct guest_info * info, + void * frontend_data, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * priv_data); + + + struct list_head blk_node; + + void * priv_data; +}; + + + +int v3_dev_add_blk_frontend(struct guest_info * info, + char * name, + int (*connect)(struct guest_info * info, + void * frontend_data, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * priv_data), + void * priv_data) { + + struct blk_frontend * frontend = NULL; + + frontend = (struct blk_frontend *)V3_Malloc(sizeof(struct blk_frontend)); + memset(frontend, 0, sizeof(struct blk_frontend)); + + frontend->connect = connect; + frontend->priv_data = priv_data; + + list_add(&(frontend->blk_node), &(info->dev_mgr.blk_list)); + v3_htable_insert(info->dev_mgr.blk_table, (addr_t)(name), (addr_t)frontend); + + return 0; } +int v3_dev_connect_blk(struct guest_info * info, + char * frontend_name, + struct v3_dev_blk_ops * ops, + v3_cfg_tree_t * cfg, + void * private_data) { + + struct blk_frontend * frontend = NULL; + frontend = (struct blk_frontend *)v3_htable_search(info->dev_mgr.blk_table, + (addr_t)frontend_name); + + if (frontend == NULL) { + PrintError("Could not find frontend blk device %s\n", frontend_name); + return 0; + } + if (frontend->connect(info, frontend->priv_data, ops, cfg, private_data) == -1) { + PrintError("Error connecting to block frontend %s\n", frontend_name); + return -1; + } -#else -void PrintDebugDevMgr(struct guest_info * info) {} -void PrintDebugDev(struct vm_device * dev) {} -#endif + return 0; +} diff --git a/palacios/src/palacios/vmm_excp.c b/palacios/src/palacios/vmm_excp.c index 61a1a6f..f1f9411 100644 --- a/palacios/src/palacios/vmm_excp.c +++ b/palacios/src/palacios/vmm_excp.c @@ -20,6 +20,7 @@ #include #include #include +#include void v3_init_exception_state(struct guest_info * info) { info->excp_state.excp_pending = 0; diff --git a/palacios/src/palacios/vmm_host_events.c b/palacios/src/palacios/vmm_host_events.c index 90eb032..791898c 100644 --- a/palacios/src/palacios/vmm_host_events.c +++ b/palacios/src/palacios/vmm_host_events.c @@ -19,7 +19,7 @@ #include #include - +#include int v3_init_host_events(struct guest_info * info) { struct v3_host_events * host_evts = &(info->host_event_hooks); diff --git a/palacios/src/palacios/vmm_hypercall.c b/palacios/src/palacios/vmm_hypercall.c index 3dc49f2..65749c1 100644 --- a/palacios/src/palacios/vmm_hypercall.c +++ b/palacios/src/palacios/vmm_hypercall.c @@ -19,7 +19,7 @@ #include #include - +#include void v3_init_hypercall_map(struct guest_info * info) { info->hcall_map.rb_node = NULL; diff --git a/palacios/src/palacios/vmm_io.c b/palacios/src/palacios/vmm_io.c index 77308d9..0211b99 100644 --- a/palacios/src/palacios/vmm_io.c +++ b/palacios/src/palacios/vmm_io.c @@ -20,7 +20,7 @@ #include #include #include - +#include diff --git a/palacios/src/palacios/vmm_mem.c b/palacios/src/palacios/vmm_mem.c index 8494f47..4248845 100644 --- a/palacios/src/palacios/vmm_mem.c +++ b/palacios/src/palacios/vmm_mem.c @@ -21,11 +21,11 @@ #include #include #include +#include #include #include - #define MEM_OFFSET_HCALL 0x1000 diff --git a/palacios/src/palacios/vmm_string.c b/palacios/src/palacios/vmm_string.c index 9160e41..effaf32 100644 --- a/palacios/src/palacios/vmm_string.c +++ b/palacios/src/palacios/vmm_string.c @@ -152,6 +152,22 @@ int strcmp(const char * s1, const char * s2) { } #endif +#ifdef CONFIG_BUILT_IN_STRCASECMP +int strcasecmp(const char * s1, const char * s2) { + while (1) { + int cmp = (tolower(*s1) - tolower(*s2)); + + if ((cmp != 0) || (*s1 == '\0') || (*s2 == '\0')) { + return cmp; + } + + ++s1; + ++s2; + } +} + +#endif + #ifdef CONFIG_BUILT_IN_STRNCMP int strncmp(const char * s1, const char * s2, size_t limit) { @@ -174,6 +190,26 @@ int strncmp(const char * s1, const char * s2, size_t limit) { } #endif +#ifdef CONFIG_BUILT_IN_STRNCASECMP +int strncasecmp(const char * s1, const char * s2, size_t limit) { + size_t i = 0; + + while (i < limit) { + int cmp = (tolower(*s1) - tolower(*s2)); + + if ((cmp != 0) || (*s1 == '\0') || (*s2 == '\0')) { + return cmp; + } + + ++s1; + ++s2; + ++i; + } + + return 0; +} +#endif + #ifdef CONFIG_BUILT_IN_STRCAT char * strcat(char * s1, const char * s2) { @@ -294,6 +330,10 @@ int strtoi(const char * nptr, char ** endptr) { uint64_t atox(const char * buf) { uint64_t ret = 0; + if (*(buf + 1) == 'x') { + buf += 2; + } + while (isxdigit(*buf)) { ret <<= 4; @@ -313,6 +353,10 @@ uint64_t strtox(const char * nptr, char ** endptr) { uint64_t ret = 0; char * buf = (char *)nptr; + if (*(buf + 1) == 'x') { + buf += 2; + } + while (isxdigit(*buf)) { ret <<= 4; @@ -445,3 +489,23 @@ char *strstr(const char *haystack, const char *needle) return NULL; } #endif + + +void str_tolower(char * s) { + while (isalpha(*s)) { + if (!islower(*s)) { + *s = tolower(*s); + } + s++; + } +} + + +void str_toupper(char * s) { + while (isalpha(*s)) { + if (!isupper(*s)) { + *s = toupper(*s); + } + s++; + } +} diff --git a/palacios/src/palacios/vmm_sym_iface.c b/palacios/src/palacios/vmm_sym_iface.c index 2a3caf0..1242cb4 100644 --- a/palacios/src/palacios/vmm_sym_iface.c +++ b/palacios/src/palacios/vmm_sym_iface.c @@ -22,6 +22,7 @@ #include #include #include +#include #define SYM_PAGE_MSR 0x535 diff --git a/palacios/src/palacios/vmm_sym_swap.c b/palacios/src/palacios/vmm_sym_swap.c index a4117b8..5c8cad8 100644 --- a/palacios/src/palacios/vmm_sym_swap.c +++ b/palacios/src/palacios/vmm_sym_swap.c @@ -21,7 +21,7 @@ #include #include - +#include #ifdef CONFIG_SYMBIOTIC_SWAP_TELEMETRY #include diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 86eaa02..319d158 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -17,9 +17,9 @@ * redistribute, and modify it as specified in the file "V3VEE_LICENSE". */ -#include "palacios/vmm_time.h" -#include "palacios/vmm.h" - +#include +#include +#include void v3_init_time(struct guest_info * info) { struct vm_time * time_state = &(info->time_state); diff --git a/palacios/src/palacios/vmm_xml.c b/palacios/src/palacios/vmm_xml.c index 2201ad9..e632a4f 100644 --- a/palacios/src/palacios/vmm_xml.c +++ b/palacios/src/palacios/vmm_xml.c @@ -112,12 +112,10 @@ struct v3_xml * v3_xml_child(struct v3_xml * xml, const char * name) { if (xml != NULL) { child = xml->child; - } + } - if (child != NULL) { - while (strcmp(name, child->name) != 0) { - child = child->sibling; - } + while ((child) && (strcasecmp(name, child->name) != 0)) { + child = child->sibling; } return child; @@ -143,7 +141,7 @@ const char * v3_xml_attr(struct v3_xml * xml, const char * attr) { return NULL; } - while ((xml->attr[i]) && (strcmp(attr, xml->attr[i]) != 0)) { + while ((xml->attr[i]) && (strcasecmp(attr, xml->attr[i]) != 0)) { i += 2; } @@ -157,14 +155,14 @@ const char * v3_xml_attr(struct v3_xml * xml, const char * attr) { for (i = 0; ( (root->attr[i] != NULL) && - (strcmp(xml->name, root->attr[i][0]) != 0) ); + (strcasecmp(xml->name, root->attr[i][0]) != 0) ); i++); if (! root->attr[i]) { return NULL; // no matching default attributes } - while ((root->attr[i][j] != NULL) && (strcmp(attr, root->attr[i][j]) != 0)) { + while ((root->attr[i][j] != NULL) && (strcasecmp(attr, root->attr[i][j]) != 0)) { j += 3; } @@ -356,7 +354,7 @@ static void v3_xml_char_content(struct v3_xml_root * root, char * s, size_t len, static int v3_xml_close_tag(struct v3_xml_root * root, char * name, char * s) { if ( (root->cur == NULL) || (root->cur->name == NULL) || - (strcmp(name, root->cur->name))) { + (strcasecmp(name, root->cur->name))) { v3_xml_err(root, s, "unexpected closing tag ", name); return -1; } @@ -484,7 +482,7 @@ static struct v3_xml * v3_xml_insert(struct v3_xml * xml, struct v3_xml * dest, // find tag type for (cur = head, prev = NULL; - ((cur) && (strcmp(cur->name, xml->name) != 0)); + ((cur) && (strcasecmp(cur->name, xml->name) != 0)); prev = cur, cur = cur->sibling); @@ -628,7 +626,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { // find attributes for correct tag for ((i = 0); ((tmp_attr = root->attr[i]) && - (strcmp(tmp_attr[0], tag_ptr) != 0)); + (strcasecmp(tmp_attr[0], tag_ptr) != 0)); (i++)) ; // 'tmp_attr' now points to the attribute list associated with 'tag_ptr' @@ -700,7 +698,7 @@ static struct v3_xml * parse_str(char * buf, size_t len) { for (j = 1; ( (tmp_attr) && (tmp_attr[j]) && - (strcmp(tmp_attr[j], attr[attr_idx]) != 0)); + (strcasecmp(tmp_attr[j], attr[attr_idx]) != 0)); j += 3); attr[val_idx] = v3_xml_decode(attr[val_idx], root->ent,