diff options
Diffstat (limited to 'sys/dev/netmap/netmap_freebsd.c')
| -rw-r--r-- | sys/dev/netmap/netmap_freebsd.c | 110 |
1 files changed, 40 insertions, 70 deletions
diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c index d83f21e255ec..2aecb53b47e4 100644 --- a/sys/dev/netmap/netmap_freebsd.c +++ b/sys/dev/netmap/netmap_freebsd.c @@ -626,38 +626,26 @@ DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass, NULL, NULL, SI_ORDER_MIDDLE + 1); /* - * I/O port read/write wrappers. - * Some are not used, so we keep them commented out until needed - */ -#define ptn_ioread16(ptn_dev, reg) bus_read_2((ptn_dev)->pci_io, (reg)) -#define ptn_ioread32(ptn_dev, reg) bus_read_4((ptn_dev)->pci_io, (reg)) -#if 0 -#define ptn_ioread8(ptn_dev, reg) bus_read_1((ptn_dev)->pci_io, (reg)) -#define ptn_iowrite8(ptn_dev, reg, val) bus_write_1((ptn_dev)->pci_io, (reg), (val)) -#define ptn_iowrite16(ptn_dev, reg, val) bus_write_2((ptn_dev)->pci_io, (reg), (val)) -#define ptn_iowrite32(ptn_dev, reg, val) bus_write_4((ptn_dev)->pci_io, (reg), (val)) -#endif /* unused */ - -/* * Map host netmap memory through PCI-BAR in the guest OS, * returning physical (nm_paddr) and virtual (nm_addr) addresses * of the netmap memory mapped in the guest. */ int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr, - void **nm_addr) + void **nm_addr, uint64_t *mem_size) { - uint32_t mem_size; int rid; D("ptn_memdev_driver iomap"); rid = PCIR_BAR(PTNETMAP_MEM_PCI_BAR); - mem_size = ptn_ioread32(ptn_dev, PTNETMAP_IO_PCI_MEMSIZE); + *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_HI); + *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_LO) | + (*mem_size << 32); /* map memory allocator */ ptn_dev->pci_mem = bus_alloc_resource(ptn_dev->dev, SYS_RES_MEMORY, - &rid, 0, ~0, mem_size, RF_ACTIVE); + &rid, 0, ~0, *mem_size, RF_ACTIVE); if (ptn_dev->pci_mem == NULL) { *nm_paddr = 0; *nm_addr = 0; @@ -667,14 +655,20 @@ nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr, *nm_paddr = rman_get_start(ptn_dev->pci_mem); *nm_addr = rman_get_virtual(ptn_dev->pci_mem); - D("=== BAR %d start %lx len %lx mem_size %x ===", + D("=== BAR %d start %lx len %lx mem_size %lx ===", PTNETMAP_MEM_PCI_BAR, (unsigned long)(*nm_paddr), (unsigned long)rman_get_size(ptn_dev->pci_mem), - mem_size); + (unsigned long)*mem_size); return (0); } +uint32_t +nm_os_pt_memdev_ioread(struct ptnetmap_memdev *ptn_dev, unsigned int reg) +{ + return bus_read_4(ptn_dev->pci_io, reg); +} + /* Unmap host netmap memory. */ void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *ptn_dev) @@ -730,7 +724,7 @@ ptn_memdev_attach(device_t dev) return (ENXIO); } - mem_id = ptn_ioread16(ptn_dev, PTNETMAP_IO_PCI_HOSTID); + mem_id = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMID); /* create guest allocator */ ptn_dev->nm_mem = netmap_mem_pt_guest_attach(ptn_dev, mem_id); @@ -740,7 +734,7 @@ ptn_memdev_attach(device_t dev) } netmap_mem_get(ptn_dev->nm_mem); - D("ptn_memdev_driver probe OK - host_id: %d", mem_id); + D("ptn_memdev_driver probe OK - host_mem_id: %d", mem_id); return (0); } @@ -993,12 +987,7 @@ nm_os_ncpus(void) struct nm_kthread_ctx { struct thread *user_td; /* thread user-space (kthread creator) to send ioctl */ - /* notification to guest (interrupt) */ - int irq_fd; /* ioctl fd */ - struct nm_kth_ioctl irq_ioctl; /* ioctl arguments */ - - /* notification from guest */ - void *ioevent_file; /* tsleep() argument */ + struct ptnetmap_cfgentry_bhyve cfg; /* worker function and parameter */ nm_kthread_worker_fn_t worker_fn; @@ -1034,8 +1023,8 @@ nm_os_kthread_wakeup_worker(struct nm_kthread *nmk) */ mtx_lock(&nmk->worker_lock); nmk->scheduled++; - if (nmk->worker_ctx.ioevent_file) { - wakeup(nmk->worker_ctx.ioevent_file); + if (nmk->worker_ctx.cfg.wchan) { + wakeup((void *)nmk->worker_ctx.cfg.wchan); } mtx_unlock(&nmk->worker_lock); } @@ -1046,11 +1035,13 @@ nm_os_kthread_send_irq(struct nm_kthread *nmk) struct nm_kthread_ctx *ctx = &nmk->worker_ctx; int err; - if (ctx->user_td && ctx->irq_fd > 0) { - err = kern_ioctl(ctx->user_td, ctx->irq_fd, ctx->irq_ioctl.com, (caddr_t)&ctx->irq_ioctl.data.msix); + if (ctx->user_td && ctx->cfg.ioctl_fd > 0) { + err = kern_ioctl(ctx->user_td, ctx->cfg.ioctl_fd, ctx->cfg.ioctl_cmd, + (caddr_t)&ctx->cfg.ioctl_data); if (err) { - D("kern_ioctl error: %d ioctl parameters: fd %d com %ju data %p", - err, ctx->irq_fd, (uintmax_t)ctx->irq_ioctl.com, &ctx->irq_ioctl.data); + D("kern_ioctl error: %d ioctl parameters: fd %d com %lu data %p", + err, ctx->cfg.ioctl_fd, (unsigned long)ctx->cfg.ioctl_cmd, + &ctx->cfg.ioctl_data); } } } @@ -1082,10 +1073,10 @@ nm_kthread_worker(void *data) } /* - * if ioevent_file is not defined, we don't have notification + * if wchan is not defined, we don't have notification * mechanism and we continually execute worker_fn() */ - if (!ctx->ioevent_file) { + if (!ctx->cfg.wchan) { ctx->worker_fn(ctx->worker_private); /* worker body */ } else { /* checks if there is a pending notification */ @@ -1099,7 +1090,7 @@ nm_kthread_worker(void *data) continue; } else if (nmk->run) { /* wait on event with one second timeout */ - msleep_spin(ctx->ioevent_file, &nmk->worker_lock, + msleep_spin((void *)ctx->cfg.wchan, &nmk->worker_lock, "nmk_ev", hz); nmk->scheduled++; } @@ -1110,29 +1101,6 @@ nm_kthread_worker(void *data) kthread_exit(); } -static int -nm_kthread_open_files(struct nm_kthread *nmk, struct nm_kthread_cfg *cfg) -{ - /* send irq through ioctl to bhyve (vmm.ko) */ - if (cfg->event.irqfd) { - nmk->worker_ctx.irq_fd = cfg->event.irqfd; - nmk->worker_ctx.irq_ioctl = cfg->event.ioctl; - } - /* ring.ioeventfd contains the chan where do tsleep to wait events */ - if (cfg->event.ioeventfd) { - nmk->worker_ctx.ioevent_file = (void *)cfg->event.ioeventfd; - } - - return 0; -} - -static void -nm_kthread_close_files(struct nm_kthread *nmk) -{ - nmk->worker_ctx.irq_fd = 0; - nmk->worker_ctx.ioevent_file = NULL; -} - void nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity) { @@ -1140,10 +1108,15 @@ nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity) } struct nm_kthread * -nm_os_kthread_create(struct nm_kthread_cfg *cfg) +nm_os_kthread_create(struct nm_kthread_cfg *cfg, unsigned int cfgtype, + void *opaque) { struct nm_kthread *nmk = NULL; - int error; + + if (cfgtype != PTNETMAP_CFGTYPE_BHYVE) { + D("Unsupported cfgtype %u", cfgtype); + return NULL; + } nmk = malloc(sizeof(*nmk), M_DEVBUF, M_NOWAIT | M_ZERO); if (!nmk) @@ -1158,15 +1131,12 @@ nm_os_kthread_create(struct nm_kthread_cfg *cfg) /* attach kthread to user process (ptnetmap) */ nmk->attach_user = cfg->attach_user; - /* open event fd */ - error = nm_kthread_open_files(nmk, cfg); - if (error) - goto err; + /* store kick/interrupt configuration */ + if (opaque) { + nmk->worker_ctx.cfg = *((struct ptnetmap_cfgentry_bhyve *)opaque); + } return nmk; -err: - free(nmk, M_DEVBUF); - return NULL; } int @@ -1194,7 +1164,7 @@ nm_os_kthread_start(struct nm_kthread *nmk) goto err; } - D("nm_kthread started td 0x%p", nmk->worker); + D("nm_kthread started td %p", nmk->worker); return 0; err: @@ -1228,7 +1198,7 @@ nm_os_kthread_delete(struct nm_kthread *nmk) nm_os_kthread_stop(nmk); } - nm_kthread_close_files(nmk); + memset(&nmk->worker_ctx.cfg, 0, sizeof(nmk->worker_ctx.cfg)); free(nmk, M_DEVBUF); } |
