#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));
-
struct vnet_virtio_pkt {
uint32_t link_id;
uint32_t pkt_size;
uint8_t status = 0;
- PrintDebug("Descriptor Count=%d, index=%d, desc_idx=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
+ PrintDebug("VNET Bridge: CMD: Descriptor Count=%d, index=%d, desc_idx=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
if (desc_cnt < 3) {
PrintError("VNET Bridge cmd must include at least 3 descriptors (cnt=%d)\n", desc_cnt);
}
// add route
- PrintDebug("Adding VNET Route\n");
+ PrintDebug("VNET Bridge: Adding VNET Route\n");
tmp_status = v3_vnet_add_route(*route);
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);
}
-static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
+static int vnetbrg_io_read(struct guest_info * core, uint16_t port, void * dst, 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;
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>