#endif
--
--
++#ifdef CONFIG_VNET
++#include <palacios/vmm_vnet.h>
++#endif
#ifdef CONFIG_SYMBIOTIC
struct v3_vm_info * vm_info;
// the logical cpu this guest context is executing on
int cpu_id;
++
++#ifdef CONFIG_VNET_PROFILE
++ struct v3_vnet_profile vnet_times;
++#endif
};
#include <palacios/vmm.h>
--typedef enum {MAC_ANY, MAC_NOT, MAC_NONE} mac_type_t; //for 'src_mac_qual' and 'dst_mac_qual'
--typedef enum {LINK_INTERFACE, LINK_EDGE, LINK_ANY} link_type_t; //for 'type' and 'src_type' in struct routing
++typedef enum {MAC_ANY=0, MAC_NOT, MAC_NONE, MAC_ADDR} mac_type_t; //for 'src_mac_qual' and 'dst_mac_qual'
++typedef enum {LINK_INTERFACE=0, LINK_EDGE, LINK_ANY} link_type_t; //for 'type' and 'src_type' in struct routing
#define VNET_HASH_SIZE 17
return -1;
}
-- if (virtio->net_ops->send(buf, len, (void *)core, NULL) == -1) {
++ if (virtio->net_ops->send(buf, len, virtio->backend_data, NULL) == -1) {
return -1;
}
uint32_t num_cmds;
} __attribute__((packed));
- static int vnetbrg_reset(struct virtio_vnet_state * vnet_brg) {
-
+ struct vnet_virtio_pkt {
+ uint32_t link_id;
+ uint32_t pkt_size;
+ uint8_t pkt[1500];
+ };
- memset(vnet_brg->queue, 0, sizeof(struct virtio_queue) * 2);
+ static int virtio_reset(struct virtio_vnet_state * vnet_state) {
- vnet_brg->cur_queue = &(vnet_brg->queue[0]);
+ memset(vnet_state->queue, 0, sizeof(struct virtio_queue) * 2);
- vnet_brg->virtio_cfg.status = 0;
- vnet_brg->virtio_cfg.pci_isr = 0;
+ vnet_state->cur_queue = &(vnet_state->queue[0]);
- vnet_brg->queue[0].queue_size = QUEUE_SIZE;
- vnet_brg->queue[1].queue_size = QUEUE_SIZE;
- vnet_brg->queue[2].queue_size = QUEUE_SIZE;
+ vnet_state->virtio_cfg.status = 0;
+ vnet_state->virtio_cfg.pci_isr = 0;
- memset(&(vnet_brg->vnet_cfg), 0, sizeof(struct vnet_config));
- v3_lock_init(&(vnet_brg->lock));
+ vnet_state->queue[0].queue_size = QUEUE_SIZE;
+ vnet_state->queue[1].queue_size = QUEUE_SIZE;
+ vnet_state->queue[2].queue_size = QUEUE_SIZE;
+
+ memset(&(vnet_state->vnet_cfg), 0, sizeof(struct vnet_config));
+ v3_lock_init(&(vnet_state->lock));
return 0;
}
return 0;
}
- static int vnetbrg_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
- struct virtio_vnet_state * vnet_brg = (struct virtio_vnet_state *)private_data;
- int port_idx = port % vnet_brg->io_range_size;
-
+ static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
+ struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
+ int port_idx = port % vnet_state->io_range_size;
-
PrintDebug("VNET Bridge: VIRTIO VNET Write for port %d len=%d, value=%x\n",
port, length, *(uint32_t *)src);
PrintDebug("VNET Bridge: port idx=%d\n", port_idx);
struct vnet_nic_state {
char mac[6];
-- struct guest_info * core;
++ struct v3_vm_info * vm;
struct v3_dev_net_ops net_ops;
++ int vnet_dev_id;
};
#if 0
--//used when virtio_nic get a packet from guest and send it to the backend
++//Malloc/Free version of send
static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
struct v3_vnet_pkt * pkt = NULL;
struct guest_info *core = (struct guest_info *)private_data;
//alternative way, no malloc/free
static int vnet_send(uint8_t * buf, uint32_t len, void * private_data, struct vm_device *dest_dev){
struct v3_vnet_pkt pkt;
-- struct guest_info *core = (struct guest_info *)private_data;
--
--#ifdef CONFIG_DEBUG_VNET_NIC
-- {
-- PrintDebug("Virtio VNET-NIC: send pkt size: %d\n", len);
-- v3_hexdump(buf, len, NULL, 0);
-- }
--#endif
++ struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
++ struct guest_info *core = &(vnetnic->vm->cores[0]);
#ifdef CONFIG_VNET_PROFILE
uint64_t start, end;
pkt.size = len;
pkt.src_type = LINK_INTERFACE;
-- pkt.src_id = 0;
++ pkt.src_id = vnetnic->vnet_dev_id;
memcpy(pkt.data, buf, pkt.size);
++#ifdef CONFIG_DEBUG_VNET_NIC
++ {
++ PrintDebug("Virtio VNET-NIC: send pkt size: %d, pkt src_id: %d, src_type: %d\n",
++ len, pkt.src_id, pkt.src_type);
++ v3_hexdump(buf, len, NULL, 0);
++ }
++#endif
++
++
#ifdef CONFIG_VNET_PROFILE
rdtscll(end);
core->vnet_times.time_copy_from_guest = end - core->vnet_times.virtio_handle_start;
vnetnic->net_ops.send = vnet_send;
memcpy(vnetnic->mac, mac, 6);
++ vnetnic->vm = vm;
if (v3_dev_connect_net(vm, v3_cfg_val(frontend_cfg, "tag"),
&(vnetnic->net_ops), frontend_cfg, vnetnic) == -1) {
if ((vnet_dev_id = register_to_vnet(vm, vnetnic, name, vnetnic->mac)) == -1) {
PrintError("Vnet-nic device %s (mac: %s) fails to registered to VNET\n", name, macstr);
}
++ vnetnic->vnet_dev_id = vnet_dev_id;
PrintDebug("Vnet-nic device %s (mac: %s, %ld) registered to VNET\n", name, macstr, *((ulong_t *)vnetnic->mac));
--//for temporary hack
--#if 0
++//for temporary hack for vnet bridge test
++#if 1
++ {
++ uchar_t zeromac[6] = {0,0,0,0,0,0};
++
++ if(!strcmp(name, "vnet_nic")){
++ struct v3_vnet_route route;
++
++ route.dst_id = vnet_dev_id;
++ route.dst_type = LINK_INTERFACE;
++ route.src_id = 0;
++ route.src_type = LINK_EDGE;
++ memcpy(route.dst_mac, zeromac, 6);
++ route.dst_mac_qual = MAC_ANY;
++ memcpy(route.src_mac, zeromac, 6);
++ route.src_mac_qual = MAC_ANY;
++ v3_vnet_add_route(route);
++
++
++ route.dst_id = 0;
++ route.dst_type = LINK_EDGE;
++ route.src_id = vnet_dev_id;
++ route.src_type = LINK_INTERFACE;
++ memcpy(route.dst_mac, zeromac, 6);
++ route.dst_mac_qual = MAC_ANY;
++ memcpy(route.src_mac, zeromac, 6);
++ route.src_mac_qual = MAC_ANY;
++
++ v3_vnet_add_route(route);
++ }
++ }
++#endif
++#if 0 //temporay hacking for vnet virtio bridge
{
uchar_t tapmac[6] = {0x00,0x02,0x55,0x67,0x42,0x39}; //for Intel-VT test HW
//uchar_t tapmac[6] = {0x6e,0xa8,0x75,0xf4,0x82,0x95};
v3_vnet_add_route(route);
}
}
--
#endif
return 0;
return 0;
}
--
--
int guest_pa_to_host_pa(struct guest_info * info, addr_t guest_pa, addr_t * host_pa) {
struct v3_shadow_region * shdw_reg = v3_get_shadow_region(info->vm_info, info->cpu_id, guest_pa);
(void *)guest_pa, v3_shdw_region_type_to_str(shdw_reg->host_type));
return -1;
}
--
++
*host_pa = v3_get_shadow_addr(shdw_reg, info->cpu_id, guest_pa);
return 0;
--
/* At this point the GPRs are already copied into the guest_info state */
int v3_handle_vmx_exit(struct guest_info * info, struct vmx_exit_info * exit_info) {
struct vmx_data * vmx_info = (struct vmx_data *)(info->vmm_data);
v3_print_vmcs();
*/
++#ifdef CONFIG_VNET_PROFILE
++ uint64_t start, end;
++ rdtscll(start);
++#endif
++
#ifdef CONFIG_TELEMETRY
if (info->vm_info->enable_telemetry) {
v3_telemetry_start_exit(info);
}
#endif
++#ifdef CONFIG_VNET_PROFILE
++ rdtscll(end);
++ info->vnet_times.total_exit_time = end - start;
++ if(info->vnet_times.print)
++ PrintError("Vnet_profiling: total_exit_time: %ld, total_handle_time: %ld memcpy_time: %ld copy_from_guest: %ld copy_to_guest: %ld malloc_free: %ld, route_lookup: %ld\n",
++ (long)info->vnet_times.total_exit_time,
++ (long)info->vnet_times.total_handle_time,
++ (long)info->vnet_times.memcpy_time,
++ (long)info->vnet_times.time_copy_from_guest,
++ (long)info->vnet_times.time_copy_to_guest,
++ (long)info->vnet_times.time_mallocfree,
++ (long)info->vnet_times.time_route_lookup);
++
++ info->vnet_times.print = false;
++#endif
++
++
return 0;
}
<vm class="PC">
<!-- Memory in MB -->
-- <memory>256</memory>
++ <memory>512</memory>
<!-- Basic VMM system flags -->
<telemetry>enable</telemetry>
<paging mode="VTLB" />
-- <schedule_hz>100</schedule_hz>
++ <schedule_hz>1000</schedule_hz>
<cores count="1"><core /></cores>
<!-- This is where you add disk images -->
<files>
<!-- The file 'id' is used as a reference for other configuration components -->
-- <file id="boot-cd" filename="/home/ktpedre/google_code/smp_guest/kitten_guest/arch/x86_64/boot/image.iso" />
++ <file id="boot-cd" filename="image.iso" />
<!--<file id="harddisk" filename="firefox.img" />-->
</files>
<bus>pci0</bus>
<controller>southbridge</controller>
</device>
++
++ <device id="LNX_VIRTIO_NIC" name="net_virtio0">
++ <bus>pci0</bus>
++ </device>
++
++ <device id="LNX_VIRTIO_NIC" name="net_virtio1">
++ <bus>pci0</bus>
++ </device>
++
++ <device id="LNX_VIRTIO_NIC" name="net_virtio2">
++ <bus>pci0</bus>
++ </device>
++
++ <device id="PCI_PASSTHROUGH" name="e1000">
++ <bus>pci0</bus>
++ <vendor_id>0x8086</vendor_id>
++ <device_id>0x100e</device_id>
++ <irq>59</irq>
++ </device>
++
<!--
<device id="LNX_VIRTIO_SYM" name="sym_pci">
</frontend>
</device>
++ <device id="VNET_NIC", name="vnet_nic0">
++ <frontend tag="net_virtio0">
++ <mac>10:20:30:40:50:60</mac>
++ </frontend>
++ </device>
++
++ <device id="VNET_NIC", name="vnet_nic1">
++ <frontend tag="net_virtio1">
++ <mac>10:20:30:40:50:61</mac>
++ </frontend>
++ </device>
++
++ <device id="VNET_NIC", name="vnet_nic2">
++ <frontend tag="net_virtio2">
++ <mac>10:20:30:40:50:62</mac>
++ </frontend>
++ </device>
++
<!---
<device id="SYM_SWAP" name="sym swap">
<frontend tag="blk_virtio" />
<size>150</size>
</device>
---->
--
--
<device id="RAMDISK" name="HD0">
<file>harddisk</file>
<frontend tag="blk_virtio" />
</device>
--
++-->
<device id="NVRAM" name="nvram">
<storage>ide</storage>