#include <palacios/vmm_dev_mgr.h>
#include <palacios/vm_guest_mem.h>
#include <devices/lnx_virtio_pci.h>
-#include <palacios/vmm_vnet.h>
+#include <vnet/vnet.h>
#include <palacios/vmm_sprintf.h>
#include <devices/pci.h>
-#ifndef CONFIG_DEBUG_LINUX_VIRTIO_VNET
+#ifndef V3_CONFIG_DEBUG_LINUX_VIRTIO_VNET
#undef PrintDebug
#define PrintDebug(fmt, args...)
#endif
#define VNET_ADD_LINK 21
#define VNET_DEL_LINK 22
-// structure of the vnet command header
struct vnet_ctrl_hdr {
uint8_t cmd_type;
uint32_t num_cmds;
}
-
-
-static int handle_cmd_kick(struct guest_info * core, struct virtio_vnet_state * vnet_state) {
+static int handle_cmd_kick(struct guest_info * core,
+ struct virtio_vnet_state * vnet_state) {
struct virtio_queue * q = &(vnet_state->queue[0]);
PrintDebug("VNET Bridge: Handling command queue\n");
uint8_t * status_ptr = NULL;
uint8_t status = 0;
-
PrintDebug("VNET Bridge: CMD: Descriptor Count=%d, index=%d, desc_idx=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE, desc_idx);
if (desc_cnt < 3) {
desc_idx = hdr_desc->next;
- if (hdr->cmd_type == VNET_ADD_ROUTE) {
-
+ if (hdr->cmd_type == VNET_ADD_ROUTE) {
for (i = 0; i < hdr->num_cmds; i++) {
uint8_t tmp_status = 0;
struct v3_vnet_route * route = NULL;
return -1;
}
- // add route
- PrintDebug("VNET Bridge: Adding VNET Route\n");
-
tmp_status = v3_vnet_add_route(*route);
-
- PrintDebug("VNET Route Added\n");
-
if (tmp_status != 0) {
PrintError("Error adding VNET ROUTE\n");
+
status = tmp_status;
}
+ PrintDebug("VNET Route Added\n");
+
xfer_len += buf_desc->length;
desc_idx = buf_desc->next;
}
}
-
-
status_desc = &(q->desc[desc_idx]);
if (v3_gpa_to_hva(core, status_desc->addr_gpa, (addr_t *)&status_ptr) == -1) {
if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
PrintDebug("Raising IRQ %d\n", vnet_state->pci_dev->config_header.intr_line);
- v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
+ v3_pci_raise_irq(vnet_state->pci_bus, vnet_state->pci_dev, 0);
vnet_state->virtio_cfg.pci_isr = 1;
}
static int vnet_pkt_input_cb(struct v3_vm_info * vm,
- struct v3_vnet_pkt * pkt,
- void * private_data){
+ struct v3_vnet_pkt * pkt,
+ void * private_data){
struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
struct virtio_queue * q = &(vnet_state->queue[RECV_QUEUE]);
int ret_val = -1;
if (q->ring_avail_addr == 0) {
PrintError("Queue is not set\n");
+
goto exit;
}
struct vnet_bridge_pkt * virtio_pkt = NULL;
pkt_desc = &(q->desc[pkt_idx]);
- PrintDebug("VNET Bridge RX: buffer desc len: %d\n", pkt_desc->length);
if (v3_gpa_to_hva(&(vm->cores[0]), pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
PrintError("Could not translate buffer address\n");
}
if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
- v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
+ v3_pci_raise_irq(vnet_state->pci_bus, vnet_state->pci_dev, 0);
vnet_state->virtio_cfg.pci_isr = 0x1;
PrintDebug("Raising IRQ %d\n", vnet_state->pci_dev->config_header.intr_line);
}
return ret_val;
}
-static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state)
+static int do_tx_pkts(struct guest_info * core,
+ struct virtio_vnet_state * vnet_state)
{
struct virtio_queue * q = &(vnet_state->queue[XMIT_QUEUE]);
int recvd = 0;
struct vnet_bridge_pkt * virtio_pkt = NULL;
pkt_desc = &(q->desc[desc_idx]);
-
- PrintDebug("VNET Bridge: Handle TX desc buf_len: %d\n", pkt_desc->length);
if (v3_gpa_to_hva(core, pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
PrintError("Could not translate buffer address\n");
}
if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
- v3_pci_raise_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
- vnet_state->virtio_cfg.pci_isr = 0x1;
+ v3_pci_raise_irq(vnet_state->pci_bus, vnet_state->pci_dev, 0);
+ vnet_state->virtio_cfg.pci_isr = 0x1;
}
return 0;
}
-static void vnet_virtio_poll(struct v3_vm_info * vm, void *private_data){
+static void vnet_virtio_poll(struct v3_vm_info * vm, void * private_data){
struct virtio_vnet_state * vnet_state = (struct virtio_vnet_state *)private_data;
if(vm == vnet_state->vm){
- handle_pkt_kick(&(vm->cores[0]), vnet_state);
+ do_tx_pkts(&(vm->cores[0]), vnet_state);
}
}
-static int handle_rx_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state)
-{
- //v3_vnet_enable_bridge();
-
+static int handle_rx_queue_kick(struct guest_info *core,
+ struct virtio_vnet_state * vnet_state)
+{
return 0;
}
-static int vnet_virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) {
+static int vnet_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;
return -1;
}
} else if (queue_idx == 1) {
- if (handle_pkt_kick(core, vnet_state) == -1){
+ if (do_tx_pkts(core, vnet_state) == -1){
PrintError("Could not handle Virtio VNET TX\n");
return -1;
}
PrintError("Notify on TX\n");
} else if (queue_idx == 2) {
- if (handle_rx_kick(core, vnet_state) == -1){
+ if (handle_rx_queue_kick(core, vnet_state) == -1){
PrintError("Could not handle Virtio RX buffer refills Kick\n");
return -1;
}
}
-static int vnet_virtio_io_read(struct guest_info * core, uint16_t port, void * dst, uint_t length, void * private_data) {
+static int vnet_virtio_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;
case VIRTIO_ISR_PORT:
*(uint8_t *)dst = vnet_state->virtio_cfg.pci_isr;
vnet_state->virtio_cfg.pci_isr = 0;
- v3_pci_lower_irq(vnet_state->pci_bus, 0, vnet_state->pci_dev);
+ v3_pci_lower_irq(vnet_state->pci_bus, vnet_state->pci_dev, 0);
break;
default:
}
+static int virtio_free(struct virtio_vnet_state * vnet_state) {
+
+ // unregister from PCI
+
+ V3_Free(vnet_state);
+ return 0;
+}
+
static struct v3_device_ops dev_ops = {
- .free = NULL,
- .reset = NULL,
- .start = NULL,
- .stop = NULL,
+ .free = (int (*)(void *))virtio_free,
};
static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) {
}
vnet_state = (struct virtio_vnet_state *)V3_Malloc(sizeof(struct virtio_vnet_state));
+
+ if (!vnet_state) {
+ PrintError("Cannot allocate in init\n");
+ return -1;
+ }
+
memset(vnet_state, 0, sizeof(struct virtio_vnet_state));
vnet_state->vm = vm;
- struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnet_state);
+ struct vm_device * dev = v3_add_device(vm, name, &dev_ops, vnet_state);
- if (v3_attach_device(vm, dev) == -1) {
+ if (dev == NULL) {
PrintError("Could not attach device %s\n", name);
+ V3_Free(vnet_state);
return -1;
}
pci_dev = v3_pci_register_device(pci_bus, PCI_STD_DEVICE,
0, 5 /*PCI_AUTO_DEV_NUM*/, 0,
"LNX_VIRTIO_VNET", bars,
- NULL, NULL, NULL, vnet_state);
+ NULL, NULL, NULL, NULL, vnet_state);
if (!pci_dev) {
PrintError("Could not register PCI Device\n");
+ v3_remove_device(dev);
return -1;
}
brg_ops.poll = vnet_virtio_poll;
V3_Print("Registering Virtio device as vnet bridge\n");
+
v3_vnet_add_bridge(vm, &brg_ops, CTL_VM_BRIDGE, (void *)vnet_state);
return 0;