From owner-svn-soc-all@freebsd.org Sun Jul 31 20:30:49 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0BF1CBA83FD for ; Sun, 31 Jul 2016 20:30:49 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E654D1A3D for ; Sun, 31 Jul 2016 20:30:48 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u6VKUm5i024554 for ; Sun, 31 Jul 2016 20:30:48 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u6VKUlQx024495 for svn-soc-all@FreeBSD.org; Sun, 31 Jul 2016 20:30:47 GMT (envelope-from iateaca@FreeBSD.org) Date: Sun, 31 Jul 2016 20:30:47 GMT Message-Id: <201607312030.u6VKUlQx024495@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307034 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Jul 2016 20:30:49 -0000 Author: iateaca Date: Sun Jul 31 20:30:47 2016 New Revision: 307034 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307034 Log: use the direction of the stream (input / output) when map the stream with the stream tag Windows guest set the same stream tag for both input and output stream from the same codec M bhyve/hda_codec.c M bhyve/pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun Jul 31 19:02:19 2016 (r307033) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun Jul 31 20:30:47 2016 (r307034) @@ -314,7 +314,7 @@ assert(!err); /* TODO Get the name of the sound device from the config string */ - st->aud = audio_init("/dev/dsp", 1); + st->aud = audio_init("/dev/dsp0", 1); if (!st->aud) { DPRINTF("Fail to init the output audio player\n"); return -1; @@ -329,7 +329,7 @@ assert(!err); /* TODO Get the name of the sound device from the config string */ - st->aud = audio_init("/dev/dsp", 0); + st->aud = audio_init("/dev/dsp1", 0); if (!st->aud) { DPRINTF("Fail to init the input audio player\n"); return -1; @@ -460,11 +460,8 @@ sc = (struct hda_codec_softc *)hci->priv; assert(sc); - for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) { - st = &sc->streams[i]; - if (st->stream == stream) - break; - } + i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT; + st = &sc->streams[i]; DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d\n", run, stream, st->stream, dir); Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun Jul 31 19:02:19 2016 (r307033) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sun Jul 31 20:30:47 2016 (r307034) @@ -98,7 +98,8 @@ void *dma_pib_vaddr; struct hda_stream_desc streams[HDA_IOSS_NO]; - uint8_t stream_map[HDA_STREAM_TAGS_CNT]; + /* 2 tables for output and input */ + uint8_t stream_map[2][HDA_STREAM_TAGS_CNT]; }; /* @@ -642,11 +643,11 @@ sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0); strm = (sdctl >> 20) & 0x0f; - dir = (sdctl >> 19) & 0x01; + dir = stream_ind >= HDA_ISS_NO; DPRINTF("strm: 0x%x, dir: 0x%x\n", strm, dir); - sc->stream_map[strm] = stream_ind; + sc->stream_map[dir][strm] = stream_ind; st->stream = strm; st->dir = dir; st->bp = 0; @@ -1120,7 +1121,7 @@ sc = hci->hda; assert(stream < HDA_STREAM_TAGS_CNT); - stream_ind = sc->stream_map[stream]; + stream_ind = sc->stream_map[dir][stream]; if (!dir) assert(stream_ind < HDA_ISS_NO); From owner-svn-soc-all@freebsd.org Sun Jul 31 21:48:19 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F29BEBAAA1B for ; Sun, 31 Jul 2016 21:48:19 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E5D0F1CE2 for ; Sun, 31 Jul 2016 21:48:19 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u6VLmJFd003404 for ; Sun, 31 Jul 2016 21:48:19 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u6VLmIgO003401 for svn-soc-all@FreeBSD.org; Sun, 31 Jul 2016 21:48:18 GMT (envelope-from iateaca@FreeBSD.org) Date: Sun, 31 Jul 2016 21:48:18 GMT Message-Id: <201607312148.u6VLmIgO003401@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307037 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 31 Jul 2016 21:48:20 -0000 Author: iateaca Date: Sun Jul 31 21:48:18 2016 New Revision: 307037 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307037 Log: improve logging (print the number of fragments and the fragmentsize after set the audio parameters) M bhyve/audio.c M bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c Sun Jul 31 20:13:00 2016 (r307036) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/audio.c Sun Jul 31 21:48:18 2016 (r307037) @@ -63,6 +63,9 @@ int audio_fd = -1; int format, channels, rate; int err; +#if DEBUG_HDA == 1 + audio_buf_info info; +#endif assert(aud); assert(params); @@ -126,6 +129,14 @@ return -1; } +#if DEBUG_HDA == 1 + err = ioctl(audio_fd, aud->dir ? SNDCTL_DSP_GETOSPACE : SNDCTL_DSP_GETISPACE, &info); + if (err == -1) { + DPRINTF("Fail to get audio buf info errno: %d\n", errno); + return -1; + } + DPRINTF("fragstotal: 0x%x fragsize: 0x%x\n", info.fragstotal, info.fragsize); +#endif return 0; } Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun Jul 31 20:13:00 2016 (r307036) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sun Jul 31 21:48:18 2016 (r307037) @@ -656,7 +656,7 @@ uint8_t mute = 0; uint8_t gain = 0; - DPRINTF("verb: 0x%x, payload, 0x%x\n", verb, payload); + DPRINTF("%s verb: 0x%x, payload, 0x%x\n", st->actx.name, verb, payload); switch (verb) { case HDA_CMD_VERB_GET_CONV_FMT: From owner-svn-soc-all@freebsd.org Mon Aug 1 08:02:12 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id EA58EBAA996 for ; Mon, 1 Aug 2016 08:02:12 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DDED611DC for ; Mon, 1 Aug 2016 08:02:12 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u7182C3u025153 for ; Mon, 1 Aug 2016 08:02:12 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u7182CHo024884 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 08:02:12 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 08:02:12 GMT Message-Id: <201608010802.u7182CHo024884@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307052 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 08:02:13 -0000 Author: vincenzo Date: Mon Aug 1 08:02:11 2016 New Revision: 307052 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307052 Log: pci_vtnet_proctx: optimize computation of plen and tlen Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 08:01:35 2016 (r307051) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 08:02:11 2016 (r307052) @@ -147,7 +147,7 @@ struct virtio_net_config vsc_config; pthread_mutex_t rx_mtx; - int rx_in_progress; + int rx_in_progress; /* XXX-VM: useless. */ int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ @@ -620,12 +620,11 @@ */ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); - plen = 0; - tlen = iov[0].iov_len; - for (i = 1; i < n; i++) { - plen += iov[i].iov_len; + tlen = 0; + for (i = 0; i < n; i++) { tlen += iov[i].iov_len; } + plen = tlen - iov[0].iov_len; DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, n)); sc->pci_vtnet_tx(sc, &iov[1], n - 1, plen); From owner-svn-soc-all@freebsd.org Mon Aug 1 08:02:32 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 917B1BAA9EC for ; Mon, 1 Aug 2016 08:02:32 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 81BEC1215 for ; Mon, 1 Aug 2016 08:02:32 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u7182Wt5031640 for ; Mon, 1 Aug 2016 08:02:32 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u7182VJ0031368 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 08:02:31 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 08:02:31 GMT Message-Id: <201608010802.u7182VJ0031368@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307053 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 08:02:32 -0000 Author: vincenzo Date: Mon Aug 1 08:02:31 2016 New Revision: 307053 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307053 Log: pci_virtio_net: remove useless rx_in_progress flag Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 08:02:11 2016 (r307052) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 08:02:31 2016 (r307053) @@ -147,7 +147,6 @@ struct virtio_net_config vsc_config; pthread_mutex_t rx_mtx; - int rx_in_progress; /* XXX-VM: useless. */ int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ @@ -197,17 +196,13 @@ /* * If the receive thread is active then stall until it is done. + * It is enough to lock and unlock the RX mutex. */ static void pci_vtnet_rxwait(struct pci_vtnet_softc *sc) { pthread_mutex_lock(&sc->rx_mtx); - while (sc->rx_in_progress) { - pthread_mutex_unlock(&sc->rx_mtx); - usleep(10000); - pthread_mutex_lock(&sc->rx_mtx); - } pthread_mutex_unlock(&sc->rx_mtx); } @@ -584,9 +579,7 @@ struct pci_vtnet_softc *sc = param; pthread_mutex_lock(&sc->rx_mtx); - sc->rx_in_progress = 1; sc->pci_vtnet_rx(sc); - sc->rx_in_progress = 0; pthread_mutex_unlock(&sc->rx_mtx); } @@ -901,7 +894,6 @@ sc->rx_merge = 1; sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); - sc->rx_in_progress = 0; pthread_mutex_init(&sc->rx_mtx, NULL); /* From owner-svn-soc-all@freebsd.org Mon Aug 1 08:01:37 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2EA9CBAA8EE for ; Mon, 1 Aug 2016 08:01:37 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 21D061175 for ; Mon, 1 Aug 2016 08:01:37 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u7181b3s015336 for ; Mon, 1 Aug 2016 08:01:37 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u7181apD015118 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 08:01:36 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 08:01:36 GMT Message-Id: <201608010801.u7181apD015118@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307051 - soc2016/vincenzo/head/sys/amd64/vmm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 08:01:37 -0000 Author: vincenzo Date: Mon Aug 1 08:01:35 2016 New Revision: 307051 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307051 Log: vmm: ioregh: use sx lock in place of spin lock Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 08:01:05 2016 (r307050) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 08:01:35 2016 (r307051) @@ -99,17 +99,15 @@ #ifdef VMM_IOPORT_REG_HANDLER #include +#include #include +#include #include -#include #include static MALLOC_DEFINE(M_IOREGH, "ioregh", "bhyve ioport reg handlers"); -#define IOREGH_LOCK(ioregh) mtx_lock_spin(&((ioregh)->mtx)) -#define IOREGH_UNLOCK(ioregh) mtx_unlock_spin(&((ioregh)->mtx)) - -#define IOPORT_MAX_REG_HANDLER 12 +#define IOPORT_MAX_REG_HANDLER 16 /* * ioport_reg_handler functions allows us to to catch VM write/read @@ -134,8 +132,8 @@ }; struct ioregh { - struct mtx mtx; - /* TODO: use hash table is better */ + struct sx lock; + /* TODO: use hash table */ struct ioport_reg_handler handlers[IOPORT_MAX_REG_HANDLER]; }; @@ -161,7 +159,7 @@ * - VM_IO_REGH_IOCTL: ioctl on fd */ -/* call with ioregh->mtx held */ +/* call with ioregh->lock held */ static struct ioport_reg_handler * vmm_ioport_find_handler(struct ioregh *ioregh, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data) @@ -184,7 +182,7 @@ return (NULL); } -/* call with ioregh->mtx held */ +/* call with ioregh->lock held */ static struct ioport_reg_handler * vmm_ioport_empty_handler(struct ioregh *ioregh) { @@ -212,7 +210,7 @@ ioregh = vm_ioregh(vm); - IOREGH_LOCK(ioregh); + sx_xlock(&ioregh->lock); regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); if (regh != NULL) { @@ -238,7 +236,7 @@ regh->handler_arg = handler_arg; err: - IOREGH_UNLOCK(ioregh); + sx_xunlock(&ioregh->lock); return (ret); } @@ -252,7 +250,7 @@ ioregh = vm_ioregh(vm); - IOREGH_LOCK(ioregh); + sx_xlock(&ioregh->lock); regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); @@ -263,7 +261,7 @@ bzero(regh, sizeof(struct ioport_reg_handler)); err: - IOREGH_UNLOCK(ioregh); + sx_xunlock(&ioregh->lock); return (ret); } @@ -298,7 +296,7 @@ */ static int invoke_reg_handler(struct vm *vm, int vcpuid, struct vm_exit *vmexit, - uint32_t *val, int *error) + uint32_t *val, int *error) { struct ioport_reg_handler *regh; struct ioregh *ioregh; @@ -307,16 +305,14 @@ mask_data = vie_size2mask(vmexit->u.inout.bytes); ioregh = vm_ioregh(vm); - IOREGH_LOCK(ioregh); + sx_slock(&ioregh->lock); regh = vmm_ioport_find_handler(ioregh, vmexit->u.inout.port, vmexit->u.inout.in, mask_data, vmexit->u.inout.eax); - if (regh == NULL) { - IOREGH_UNLOCK(ioregh); - return (0); + if (regh != NULL) { + *error = (*(regh->handler))(vm, regh, val); } - *error = (*(regh->handler))(vm, regh, val); - IOREGH_UNLOCK(ioregh); - return (1); + sx_sunlock(&ioregh->lock); + return (regh != NULL); } struct ioregh * @@ -325,8 +321,7 @@ struct ioregh *ioregh; ioregh = malloc(sizeof(struct ioregh), M_IOREGH, M_WAITOK | M_ZERO); - - mtx_init(&ioregh->mtx, "ioregh lock", NULL, MTX_SPIN); + sx_init(&ioregh->lock, "ioregh lock"); return (ioregh); } @@ -334,6 +329,7 @@ void ioregh_cleanup(struct ioregh *ioregh) { + sx_destroy(&ioregh->lock); free(ioregh, M_IOREGH); } #else /* !VMM_IOPORT_REG_HANDLER */ From owner-svn-soc-all@freebsd.org Mon Aug 1 08:01:12 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 97D57BAA6FF for ; Mon, 1 Aug 2016 08:01:12 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8A43D1FAB for ; Mon, 1 Aug 2016 08:01:12 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u7181CZv007171 for ; Mon, 1 Aug 2016 08:01:12 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u71818pt005292 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 08:01:08 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 08:01:08 GMT Message-Id: <201608010801.u71818pt005292@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307050 - in soc2016/vincenzo/head: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/modules/vmm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 08:01:12 -0000 Author: vincenzo Date: Mon Aug 1 08:01:05 2016 New Revision: 307050 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307050 Log: vmm: add support needed for ptnetmap Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h soc2016/vincenzo/head/sys/amd64/include/vmm.h soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h soc2016/vincenzo/head/sys/amd64/vmm/vmm.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h soc2016/vincenzo/head/sys/modules/vmm/Makefile Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c ============================================================================== --- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 08:01:05 2016 (r307050) @@ -883,6 +883,42 @@ } int +vm_get_fd(struct vmctx *ctx) +{ + return (ctx->fd); +} + +int +vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf) +{ + struct vm_user_buf user_buf; + + bzero(&user_buf, sizeof(user_buf)); + user_buf.gpa = gpa; + user_buf.len = len; + user_buf.addr = host_buf; + + return (ioctl(ctx->fd, VM_MAP_USER_BUF, &user_buf)); +} + +int +vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data, + enum vm_io_regh_type type, void *arg) +{ + struct vm_io_reg_handler ioregh; + + bzero(&ioregh, sizeof(ioregh)); + ioregh.port = port; + ioregh.in = in; + ioregh.mask_data = mask_data; + ioregh.data = data; + ioregh.type = type; + ioregh.arg = arg; + + return (ioctl(ctx->fd, VM_IO_REG_HANDLER, &ioregh)); +} + +int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h ============================================================================== --- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 08:01:05 2016 (r307050) @@ -161,7 +161,10 @@ int vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *i1, uint64_t *i2); int vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t exit_intinfo); - +int vm_get_fd(struct vmctx *ctx); +int vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf); +int vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg); /* * Return a pointer to the statistics buffer. Note that this is not MT-safe. */ Modified: soc2016/vincenzo/head/sys/amd64/include/vmm.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 08:01:05 2016 (r307050) @@ -183,6 +183,7 @@ int vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem); void vm_free_memseg(struct vm *vm, int ident); int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td); int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func); int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func); @@ -321,6 +322,7 @@ struct vatpit *vm_atpit(struct vm *vm); struct vpmtmr *vm_pmtmr(struct vm *vm); struct vrtc *vm_rtc(struct vm *vm); +struct ioregh *vm_ioregh(struct vm *vm); /* * Inject exception 'vector' into the guest vcpu. This function returns 0 on @@ -417,7 +419,13 @@ EDGE_TRIGGER, LEVEL_TRIGGER }; - + +enum vm_io_regh_type { + VM_IO_REGH_DELETE, + VM_IO_REGH_KWEVENTS, /* kernel wait events */ + VM_IO_REGH_MAX +}; + /* * The 'access' field has the format specified in Table 21-2 of the Intel * Architecture Manual vol 3b. Modified: soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 08:01:05 2016 (r307050) @@ -123,6 +123,21 @@ size_t len; }; +struct vm_user_buf { + vm_paddr_t gpa; + void *addr; + size_t len; +}; + +struct vm_io_reg_handler { + uint16_t port; /* I/O address */ + uint16_t in; /* 0 out, 1 in */ + uint32_t mask_data; /* 0 means match anything */ + uint32_t data; /* data to match */ + enum vm_io_regh_type type; /* handler type */ + void *arg; /* handler argument */ +}; + struct vm_pptdev_msi { int vcpu; int bus; @@ -286,6 +301,10 @@ IOCNUM_RTC_WRITE = 101, IOCNUM_RTC_SETTIME = 102, IOCNUM_RTC_GETTIME = 103, + + /* host mmap and IO handler */ + IOCNUM_MAP_USER_BUF = 104, + IOCNUM_IO_REG_HANDLER = 105, }; #define VM_RUN \ @@ -344,6 +363,10 @@ _IOW('v', IOCNUM_UNBIND_PPTDEV, struct vm_pptdev) #define VM_MAP_PPTDEV_MMIO \ _IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio) +#define VM_MAP_USER_BUF \ + _IOW('v', IOCNUM_MAP_USER_BUF, struct vm_user_buf) +#define VM_IO_REG_HANDLER \ + _IOW('v', IOCNUM_IO_REG_HANDLER, struct vm_io_reg_handler) #define VM_PPTDEV_MSI \ _IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi) #define VM_PPTDEV_MSIX \ Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 08:01:05 2016 (r307050) @@ -66,6 +66,7 @@ #include "vmm_ktr.h" #include "vmm_host.h" #include "vmm_mem.h" +#include "vmm_usermem.h" #include "vmm_util.h" #include "vatpic.h" #include "vatpit.h" @@ -148,6 +149,7 @@ struct vatpit *vatpit; /* (i) virtual atpit */ struct vpmtmr *vpmtmr; /* (i) virtual ACPI PM timer */ struct vrtc *vrtc; /* (o) virtual RTC */ + struct ioregh *ioregh; /* () I/O reg handler */ volatile cpuset_t active_cpus; /* (i) active vcpus */ int suspend; /* (i) stop VM execution */ volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */ @@ -419,6 +421,7 @@ vm->vpmtmr = vpmtmr_init(vm); if (create) vm->vrtc = vrtc_init(vm); + vm->ioregh = ioregh_init(vm); CPU_ZERO(&vm->active_cpus); @@ -475,11 +478,13 @@ vrtc_cleanup(vm->vrtc); else vrtc_reset(vm->vrtc); + ioregh_cleanup(vm->ioregh); vpmtmr_cleanup(vm->vpmtmr); vatpit_cleanup(vm->vatpit); vhpet_cleanup(vm->vhpet); vatpic_cleanup(vm->vatpic); vioapic_cleanup(vm->vioapic); + vmm_usermem_cleanup(vm->vmspace); for (i = 0; i < VM_MAXCPU; i++) vcpu_cleanup(vm, i, destroy); @@ -553,6 +558,17 @@ } int +vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td) +{ + vm_object_t obj; + + if ((obj = vmm_usermem_alloc(vm->vmspace, gpa, len, buf, td)) == NULL) + return (ENOMEM); + + return (0); +} + +int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len) { @@ -588,6 +604,9 @@ if (ppt_is_mmio(vm, gpa)) return (true); /* 'gpa' is pci passthru mmio */ + if (usermem_mapped(vm->vmspace, gpa)) + return (true); /* 'gpa' is user-space buffer mapped */ + return (false); } @@ -2457,6 +2476,12 @@ return (vm->vrtc); } +struct ioregh * +vm_ioregh(struct vm *vm) +{ + return (vm->ioregh); +} + enum vm_reg_name vm_segment_name(int seg) { Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 08:01:05 2016 (r307050) @@ -55,6 +55,7 @@ #include "vmm_lapic.h" #include "vmm_stat.h" #include "vmm_mem.h" +#include "vmm_ioport.h" #include "io/ppt.h" #include "io/vatpic.h" #include "io/vioapic.h" @@ -300,6 +301,8 @@ struct vm_pptdev_mmio *pptmmio; struct vm_pptdev_msi *pptmsi; struct vm_pptdev_msix *pptmsix; + struct vm_user_buf *usermem; + struct vm_io_reg_handler *ioregh; struct vm_nmi *vmnmi; struct vm_stats *vmstats; struct vm_stat_desc *statdesc; @@ -358,6 +361,7 @@ case VM_UNBIND_PPTDEV: case VM_ALLOC_MEMSEG: case VM_MMAP_MEMSEG: + case VM_MAP_USER_BUF: case VM_REINIT: /* * ioctls that operate on the entire virtual machine must @@ -433,6 +437,16 @@ pptmmio->func, pptmmio->gpa, pptmmio->len, pptmmio->hpa); break; + case VM_MAP_USER_BUF: + usermem = (struct vm_user_buf *)data; + error = vm_map_usermem(sc->vm, usermem->gpa, usermem->len, + usermem->addr, td); + break; + case VM_IO_REG_HANDLER: + ioregh = (struct vm_io_reg_handler *)data; + error = vmm_ioport_reg_handler(sc->vm, ioregh->port, ioregh->in, ioregh->mask_data, + ioregh->data, ioregh->type, ioregh->arg); + break; case VM_BIND_PPTDEV: pptdev = (struct vm_pptdev *)data; error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot, Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 08:01:05 2016 (r307050) @@ -97,31 +97,278 @@ } #endif /* KTR */ +#ifdef VMM_IOPORT_REG_HANDLER +#include +#include +#include +#include +#include + +static MALLOC_DEFINE(M_IOREGH, "ioregh", "bhyve ioport reg handlers"); + +#define IOREGH_LOCK(ioregh) mtx_lock_spin(&((ioregh)->mtx)) +#define IOREGH_UNLOCK(ioregh) mtx_unlock_spin(&((ioregh)->mtx)) + +#define IOPORT_MAX_REG_HANDLER 12 + +/* + * ioport_reg_handler functions allows us to to catch VM write/read + * on specific I/O address and send notification. + * + * When the VM writes or reads a specific value on I/O address, if the address + * and the value matches with the info stored durign the handler registration, + * then we send a notification (we can have multiple type of notification, + * but for now is implemented only the VM_IO_REGH_KWEVENTS handler. + */ + +typedef int (*ioport_reg_handler_func_t)(struct vm *vm, + struct ioport_reg_handler *regh, uint32_t *val); + +struct ioport_reg_handler { + uint16_t port; /* I/O address */ + uint16_t in; /* 0 out, 1 in */ + uint32_t mask_data; /* 0 means match anything */ + uint32_t data; /* data to match */ + ioport_reg_handler_func_t handler; /* handler pointer */ + void *handler_arg; /* handler argument */ +}; + +struct ioregh { + struct mtx mtx; + /* TODO: use hash table is better */ + struct ioport_reg_handler handlers[IOPORT_MAX_REG_HANDLER]; +}; + +/* ----- I/O reg handlers ----- */ + +/* + * VM_IO_REGH_KWEVENTS handler + * + * wakeup() on specified address that uniquely identifies the event + * + */ +static int +vmm_ioport_reg_wakeup(struct vm *vm, struct ioport_reg_handler *regh, uint32_t *val) +{ + wakeup(regh->handler_arg); + return (0); +} + +/* + * TODO: + * - VM_IO_REGH_CONDSIGNAL: pthread_cond_signal + * - VM_IO_REGH_WRITEFD: write on fd + * - VM_IO_REGH_IOCTL: ioctl on fd + */ + +/* call with ioregh->mtx held */ +static struct ioport_reg_handler * +vmm_ioport_find_handler(struct ioregh *ioregh, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data) +{ + struct ioport_reg_handler *regh; + uint32_t mask; + int i; + + regh = ioregh->handlers; + for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) { + if (regh[i].handler != NULL) { + mask = regh[i].mask_data & mask_data; + if ((regh[i].port == port) && (regh[i].in == in) + && ((mask & regh[i].data) == (mask & data))) { + return ®h[i]; + } + } + } + + return (NULL); +} + +/* call with ioregh->mtx held */ +static struct ioport_reg_handler * +vmm_ioport_empty_handler(struct ioregh *ioregh) +{ + struct ioport_reg_handler *regh; + int i; + + regh = ioregh->handlers; + for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) { + if (regh[i].handler == NULL) { + return ®h[i]; + } + } + + return (NULL); +} + + +static int +vmm_ioport_add_handler(struct vm *vm, uint16_t port, uint16_t in, uint32_t mask_data, + uint32_t data, ioport_reg_handler_func_t handler, void *handler_arg) +{ + struct ioport_reg_handler *regh; + struct ioregh *ioregh; + int ret = 0; + + ioregh = vm_ioregh(vm); + + IOREGH_LOCK(ioregh); + + regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); + if (regh != NULL) { + printf("%s: handler for port %d in %d mask_data %d data %d \ + already registered\n", + __FUNCTION__, port, in, mask_data, data); + ret = EEXIST; + goto err; + } + + regh = vmm_ioport_empty_handler(ioregh); + if (regh == NULL) { + printf("%s: empty reg_handler slot not found\n", __FUNCTION__); + ret = ENOMEM; + goto err; + } + + regh->port = port; + regh->in = in; + regh->mask_data = mask_data; + regh->data = data; + regh->handler = handler; + regh->handler_arg = handler_arg; + +err: + IOREGH_UNLOCK(ioregh); + return (ret); +} + +static int +vmm_ioport_del_handler(struct vm *vm, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data) +{ + struct ioport_reg_handler *regh; + struct ioregh *ioregh; + int ret = 0; + + ioregh = vm_ioregh(vm); + + IOREGH_LOCK(ioregh); + + regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); + + if (regh == NULL) { + ret = EINVAL; + goto err; + } + + bzero(regh, sizeof(struct ioport_reg_handler)); +err: + IOREGH_UNLOCK(ioregh); + return (ret); +} + +/* + * register or delete a new I/O event handler. + */ +int +vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg) +{ + int ret = 0; + + switch (type) { + case VM_IO_REGH_DELETE: + ret = vmm_ioport_del_handler(vm, port, in, mask_data, data); + break; + case VM_IO_REGH_KWEVENTS: + ret = vmm_ioport_add_handler(vm, port, in, mask_data, data, + vmm_ioport_reg_wakeup, arg); + break; + default: + printf("%s: unknown reg_handler type\n", __FUNCTION__); + ret = EINVAL; + break; + } + + return (ret); +} + +/* + * Invoke an handler, if the data matches. + */ +static int +invoke_reg_handler(struct vm *vm, int vcpuid, struct vm_exit *vmexit, + uint32_t *val, int *error) +{ + struct ioport_reg_handler *regh; + struct ioregh *ioregh; + uint32_t mask_data; + + mask_data = vie_size2mask(vmexit->u.inout.bytes); + ioregh = vm_ioregh(vm); + + IOREGH_LOCK(ioregh); + regh = vmm_ioport_find_handler(ioregh, vmexit->u.inout.port, + vmexit->u.inout.in, mask_data, vmexit->u.inout.eax); + if (regh == NULL) { + IOREGH_UNLOCK(ioregh); + return (0); + } + *error = (*(regh->handler))(vm, regh, val); + IOREGH_UNLOCK(ioregh); + return (1); +} + +struct ioregh * +ioregh_init(struct vm *vm) +{ + struct ioregh *ioregh; + + ioregh = malloc(sizeof(struct ioregh), M_IOREGH, M_WAITOK | M_ZERO); + + mtx_init(&ioregh->mtx, "ioregh lock", NULL, MTX_SPIN); + + return (ioregh); +} + +void +ioregh_cleanup(struct ioregh *ioregh) +{ + free(ioregh, M_IOREGH); +} +#else /* !VMM_IOPORT_REG_HANDLER */ +#define invoke_reg_handler(_1, _2, _3, _4, _5) (0) +#endif /* VMM_IOPORT_REG_HANDLER */ + static int emulate_inout_port(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu) { ioport_handler_func_t handler; uint32_t mask, val; - int error; + int regh = 0, error = 0; /* * If there is no handler for the I/O port then punt to userspace. */ - if (vmexit->u.inout.port >= MAX_IOPORTS || - (handler = ioport_handler[vmexit->u.inout.port]) == NULL) { + if ((vmexit->u.inout.port >= MAX_IOPORTS || + (handler = ioport_handler[vmexit->u.inout.port]) == NULL) && + (regh = invoke_reg_handler(vm, vcpuid, vmexit, &val, &error)) == 0) { *retu = true; return (0); } - mask = vie_size2mask(vmexit->u.inout.bytes); + if (!regh) { + mask = vie_size2mask(vmexit->u.inout.bytes); + + if (!vmexit->u.inout.in) { + val = vmexit->u.inout.eax & mask; + } - if (!vmexit->u.inout.in) { - val = vmexit->u.inout.eax & mask; + error = (*handler)(vm, vcpuid, vmexit->u.inout.in, + vmexit->u.inout.port, vmexit->u.inout.bytes, &val); } - error = (*handler)(vm, vcpuid, vmexit->u.inout.in, - vmexit->u.inout.port, vmexit->u.inout.bytes, &val); if (error) { /* * The value returned by this function is also the return value Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 08:01:05 2016 (r307050) @@ -29,6 +29,22 @@ #ifndef _VMM_IOPORT_H_ #define _VMM_IOPORT_H_ +#define VMM_IOPORT_REG_HANDLER +#ifdef VMM_IOPORT_REG_HANDLER +struct ioport_reg_handler; +struct ioregh; + +struct ioregh *ioregh_init(struct vm *vm); +void ioregh_cleanup(struct ioregh *ioregh); + +int vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg); +#else /* !VMM_IOPORT_REG_HANDLER */ +#define ioregh_init(_1) (NULL) +#define ioregh_cleanup(_1) +#define vmm_ioport_reg_handler(_1, _2, _3, _4,_5, _6, _7) (EINVAL) +#endif /* VMM_IOPORT_REG_HANDLER */ + typedef int (*ioport_handler_func_t)(struct vm *vm, int vcpuid, bool in, int port, int bytes, uint32_t *val); Modified: soc2016/vincenzo/head/sys/modules/vmm/Makefile ============================================================================== --- soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 06:59:35 2016 (r307049) +++ soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 08:01:05 2016 (r307050) @@ -21,6 +21,7 @@ vmm_ioport.c \ vmm_lapic.c \ vmm_mem.c \ + vmm_usermem.c \ vmm_stat.c \ vmm_util.c \ x86.c From owner-svn-soc-all@freebsd.org Mon Aug 1 11:12:08 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 935DFBABD0E for ; Mon, 1 Aug 2016 11:12:08 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 85B261475 for ; Mon, 1 Aug 2016 11:12:08 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u71BC8UP035922 for ; Mon, 1 Aug 2016 11:12:08 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u71BC40T035775 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 11:12:04 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 11:12:04 GMT Message-Id: <201608011112.u71BC40T035775@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307055 - in soc2016/vincenzo/head: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/modules/vmm usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 11:12:08 -0000 Author: vincenzo Date: Mon Aug 1 11:12:03 2016 New Revision: 307055 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307055 Log: undo commits Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h soc2016/vincenzo/head/sys/amd64/include/vmm.h soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h soc2016/vincenzo/head/sys/amd64/vmm/vmm.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h soc2016/vincenzo/head/sys/modules/vmm/Makefile soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c ============================================================================== --- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 11:12:03 2016 (r307055) @@ -883,42 +883,6 @@ } int -vm_get_fd(struct vmctx *ctx) -{ - return (ctx->fd); -} - -int -vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf) -{ - struct vm_user_buf user_buf; - - bzero(&user_buf, sizeof(user_buf)); - user_buf.gpa = gpa; - user_buf.len = len; - user_buf.addr = host_buf; - - return (ioctl(ctx->fd, VM_MAP_USER_BUF, &user_buf)); -} - -int -vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data, - enum vm_io_regh_type type, void *arg) -{ - struct vm_io_reg_handler ioregh; - - bzero(&ioregh, sizeof(ioregh)); - ioregh.port = port; - ioregh.in = in; - ioregh.mask_data = mask_data; - ioregh.data = data; - ioregh.type = type; - ioregh.arg = arg; - - return (ioctl(ctx->fd, VM_IO_REG_HANDLER, &ioregh)); -} - -int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h ============================================================================== --- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 11:12:03 2016 (r307055) @@ -161,10 +161,7 @@ int vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *i1, uint64_t *i2); int vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t exit_intinfo); -int vm_get_fd(struct vmctx *ctx); -int vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf); -int vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, - uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg); + /* * Return a pointer to the statistics buffer. Note that this is not MT-safe. */ Modified: soc2016/vincenzo/head/sys/amd64/include/vmm.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 11:12:03 2016 (r307055) @@ -183,7 +183,6 @@ int vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem); void vm_free_memseg(struct vm *vm, int ident); int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); -int vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td); int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func); int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func); @@ -322,7 +321,6 @@ struct vatpit *vm_atpit(struct vm *vm); struct vpmtmr *vm_pmtmr(struct vm *vm); struct vrtc *vm_rtc(struct vm *vm); -struct ioregh *vm_ioregh(struct vm *vm); /* * Inject exception 'vector' into the guest vcpu. This function returns 0 on @@ -419,13 +417,7 @@ EDGE_TRIGGER, LEVEL_TRIGGER }; - -enum vm_io_regh_type { - VM_IO_REGH_DELETE, - VM_IO_REGH_KWEVENTS, /* kernel wait events */ - VM_IO_REGH_MAX -}; - + /* * The 'access' field has the format specified in Table 21-2 of the Intel * Architecture Manual vol 3b. Modified: soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 11:12:03 2016 (r307055) @@ -123,21 +123,6 @@ size_t len; }; -struct vm_user_buf { - vm_paddr_t gpa; - void *addr; - size_t len; -}; - -struct vm_io_reg_handler { - uint16_t port; /* I/O address */ - uint16_t in; /* 0 out, 1 in */ - uint32_t mask_data; /* 0 means match anything */ - uint32_t data; /* data to match */ - enum vm_io_regh_type type; /* handler type */ - void *arg; /* handler argument */ -}; - struct vm_pptdev_msi { int vcpu; int bus; @@ -301,10 +286,6 @@ IOCNUM_RTC_WRITE = 101, IOCNUM_RTC_SETTIME = 102, IOCNUM_RTC_GETTIME = 103, - - /* host mmap and IO handler */ - IOCNUM_MAP_USER_BUF = 104, - IOCNUM_IO_REG_HANDLER = 105, }; #define VM_RUN \ @@ -363,10 +344,6 @@ _IOW('v', IOCNUM_UNBIND_PPTDEV, struct vm_pptdev) #define VM_MAP_PPTDEV_MMIO \ _IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio) -#define VM_MAP_USER_BUF \ - _IOW('v', IOCNUM_MAP_USER_BUF, struct vm_user_buf) -#define VM_IO_REG_HANDLER \ - _IOW('v', IOCNUM_IO_REG_HANDLER, struct vm_io_reg_handler) #define VM_PPTDEV_MSI \ _IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi) #define VM_PPTDEV_MSIX \ Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 11:12:03 2016 (r307055) @@ -66,7 +66,6 @@ #include "vmm_ktr.h" #include "vmm_host.h" #include "vmm_mem.h" -#include "vmm_usermem.h" #include "vmm_util.h" #include "vatpic.h" #include "vatpit.h" @@ -149,7 +148,6 @@ struct vatpit *vatpit; /* (i) virtual atpit */ struct vpmtmr *vpmtmr; /* (i) virtual ACPI PM timer */ struct vrtc *vrtc; /* (o) virtual RTC */ - struct ioregh *ioregh; /* () I/O reg handler */ volatile cpuset_t active_cpus; /* (i) active vcpus */ int suspend; /* (i) stop VM execution */ volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */ @@ -421,7 +419,6 @@ vm->vpmtmr = vpmtmr_init(vm); if (create) vm->vrtc = vrtc_init(vm); - vm->ioregh = ioregh_init(vm); CPU_ZERO(&vm->active_cpus); @@ -478,13 +475,11 @@ vrtc_cleanup(vm->vrtc); else vrtc_reset(vm->vrtc); - ioregh_cleanup(vm->ioregh); vpmtmr_cleanup(vm->vpmtmr); vatpit_cleanup(vm->vatpit); vhpet_cleanup(vm->vhpet); vatpic_cleanup(vm->vatpic); vioapic_cleanup(vm->vioapic); - vmm_usermem_cleanup(vm->vmspace); for (i = 0; i < VM_MAXCPU; i++) vcpu_cleanup(vm, i, destroy); @@ -558,17 +553,6 @@ } int -vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td) -{ - vm_object_t obj; - - if ((obj = vmm_usermem_alloc(vm->vmspace, gpa, len, buf, td)) == NULL) - return (ENOMEM); - - return (0); -} - -int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len) { @@ -604,9 +588,6 @@ if (ppt_is_mmio(vm, gpa)) return (true); /* 'gpa' is pci passthru mmio */ - if (usermem_mapped(vm->vmspace, gpa)) - return (true); /* 'gpa' is user-space buffer mapped */ - return (false); } @@ -2476,12 +2457,6 @@ return (vm->vrtc); } -struct ioregh * -vm_ioregh(struct vm *vm) -{ - return (vm->ioregh); -} - enum vm_reg_name vm_segment_name(int seg) { Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 11:12:03 2016 (r307055) @@ -55,7 +55,6 @@ #include "vmm_lapic.h" #include "vmm_stat.h" #include "vmm_mem.h" -#include "vmm_ioport.h" #include "io/ppt.h" #include "io/vatpic.h" #include "io/vioapic.h" @@ -301,8 +300,6 @@ struct vm_pptdev_mmio *pptmmio; struct vm_pptdev_msi *pptmsi; struct vm_pptdev_msix *pptmsix; - struct vm_user_buf *usermem; - struct vm_io_reg_handler *ioregh; struct vm_nmi *vmnmi; struct vm_stats *vmstats; struct vm_stat_desc *statdesc; @@ -361,7 +358,6 @@ case VM_UNBIND_PPTDEV: case VM_ALLOC_MEMSEG: case VM_MMAP_MEMSEG: - case VM_MAP_USER_BUF: case VM_REINIT: /* * ioctls that operate on the entire virtual machine must @@ -437,16 +433,6 @@ pptmmio->func, pptmmio->gpa, pptmmio->len, pptmmio->hpa); break; - case VM_MAP_USER_BUF: - usermem = (struct vm_user_buf *)data; - error = vm_map_usermem(sc->vm, usermem->gpa, usermem->len, - usermem->addr, td); - break; - case VM_IO_REG_HANDLER: - ioregh = (struct vm_io_reg_handler *)data; - error = vmm_ioport_reg_handler(sc->vm, ioregh->port, ioregh->in, ioregh->mask_data, - ioregh->data, ioregh->type, ioregh->arg); - break; case VM_BIND_PPTDEV: pptdev = (struct vm_pptdev *)data; error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot, Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 11:12:03 2016 (r307055) @@ -97,274 +97,31 @@ } #endif /* KTR */ -#ifdef VMM_IOPORT_REG_HANDLER -#include -#include -#include -#include -#include -#include - -static MALLOC_DEFINE(M_IOREGH, "ioregh", "bhyve ioport reg handlers"); - -#define IOPORT_MAX_REG_HANDLER 16 - -/* - * ioport_reg_handler functions allows us to to catch VM write/read - * on specific I/O address and send notification. - * - * When the VM writes or reads a specific value on I/O address, if the address - * and the value matches with the info stored durign the handler registration, - * then we send a notification (we can have multiple type of notification, - * but for now is implemented only the VM_IO_REGH_KWEVENTS handler. - */ - -typedef int (*ioport_reg_handler_func_t)(struct vm *vm, - struct ioport_reg_handler *regh, uint32_t *val); - -struct ioport_reg_handler { - uint16_t port; /* I/O address */ - uint16_t in; /* 0 out, 1 in */ - uint32_t mask_data; /* 0 means match anything */ - uint32_t data; /* data to match */ - ioport_reg_handler_func_t handler; /* handler pointer */ - void *handler_arg; /* handler argument */ -}; - -struct ioregh { - struct sx lock; - /* TODO: use hash table */ - struct ioport_reg_handler handlers[IOPORT_MAX_REG_HANDLER]; -}; - -/* ----- I/O reg handlers ----- */ - -/* - * VM_IO_REGH_KWEVENTS handler - * - * wakeup() on specified address that uniquely identifies the event - * - */ -static int -vmm_ioport_reg_wakeup(struct vm *vm, struct ioport_reg_handler *regh, uint32_t *val) -{ - wakeup(regh->handler_arg); - return (0); -} - -/* - * TODO: - * - VM_IO_REGH_CONDSIGNAL: pthread_cond_signal - * - VM_IO_REGH_WRITEFD: write on fd - * - VM_IO_REGH_IOCTL: ioctl on fd - */ - -/* call with ioregh->lock held */ -static struct ioport_reg_handler * -vmm_ioport_find_handler(struct ioregh *ioregh, uint16_t port, uint16_t in, - uint32_t mask_data, uint32_t data) -{ - struct ioport_reg_handler *regh; - uint32_t mask; - int i; - - regh = ioregh->handlers; - for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) { - if (regh[i].handler != NULL) { - mask = regh[i].mask_data & mask_data; - if ((regh[i].port == port) && (regh[i].in == in) - && ((mask & regh[i].data) == (mask & data))) { - return ®h[i]; - } - } - } - - return (NULL); -} - -/* call with ioregh->lock held */ -static struct ioport_reg_handler * -vmm_ioport_empty_handler(struct ioregh *ioregh) -{ - struct ioport_reg_handler *regh; - int i; - - regh = ioregh->handlers; - for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) { - if (regh[i].handler == NULL) { - return ®h[i]; - } - } - - return (NULL); -} - - -static int -vmm_ioport_add_handler(struct vm *vm, uint16_t port, uint16_t in, uint32_t mask_data, - uint32_t data, ioport_reg_handler_func_t handler, void *handler_arg) -{ - struct ioport_reg_handler *regh; - struct ioregh *ioregh; - int ret = 0; - - ioregh = vm_ioregh(vm); - - sx_xlock(&ioregh->lock); - - regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); - if (regh != NULL) { - printf("%s: handler for port %d in %d mask_data %d data %d \ - already registered\n", - __FUNCTION__, port, in, mask_data, data); - ret = EEXIST; - goto err; - } - - regh = vmm_ioport_empty_handler(ioregh); - if (regh == NULL) { - printf("%s: empty reg_handler slot not found\n", __FUNCTION__); - ret = ENOMEM; - goto err; - } - - regh->port = port; - regh->in = in; - regh->mask_data = mask_data; - regh->data = data; - regh->handler = handler; - regh->handler_arg = handler_arg; - -err: - sx_xunlock(&ioregh->lock); - return (ret); -} - -static int -vmm_ioport_del_handler(struct vm *vm, uint16_t port, uint16_t in, - uint32_t mask_data, uint32_t data) -{ - struct ioport_reg_handler *regh; - struct ioregh *ioregh; - int ret = 0; - - ioregh = vm_ioregh(vm); - - sx_xlock(&ioregh->lock); - - regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); - - if (regh == NULL) { - ret = EINVAL; - goto err; - } - - bzero(regh, sizeof(struct ioport_reg_handler)); -err: - sx_xunlock(&ioregh->lock); - return (ret); -} - -/* - * register or delete a new I/O event handler. - */ -int -vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in, - uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg) -{ - int ret = 0; - - switch (type) { - case VM_IO_REGH_DELETE: - ret = vmm_ioport_del_handler(vm, port, in, mask_data, data); - break; - case VM_IO_REGH_KWEVENTS: - ret = vmm_ioport_add_handler(vm, port, in, mask_data, data, - vmm_ioport_reg_wakeup, arg); - break; - default: - printf("%s: unknown reg_handler type\n", __FUNCTION__); - ret = EINVAL; - break; - } - - return (ret); -} - -/* - * Invoke an handler, if the data matches. - */ -static int -invoke_reg_handler(struct vm *vm, int vcpuid, struct vm_exit *vmexit, - uint32_t *val, int *error) -{ - struct ioport_reg_handler *regh; - struct ioregh *ioregh; - uint32_t mask_data; - - mask_data = vie_size2mask(vmexit->u.inout.bytes); - ioregh = vm_ioregh(vm); - - sx_slock(&ioregh->lock); - regh = vmm_ioport_find_handler(ioregh, vmexit->u.inout.port, - vmexit->u.inout.in, mask_data, vmexit->u.inout.eax); - if (regh != NULL) { - *error = (*(regh->handler))(vm, regh, val); - } - sx_sunlock(&ioregh->lock); - return (regh != NULL); -} - -struct ioregh * -ioregh_init(struct vm *vm) -{ - struct ioregh *ioregh; - - ioregh = malloc(sizeof(struct ioregh), M_IOREGH, M_WAITOK | M_ZERO); - sx_init(&ioregh->lock, "ioregh lock"); - - return (ioregh); -} - -void -ioregh_cleanup(struct ioregh *ioregh) -{ - sx_destroy(&ioregh->lock); - free(ioregh, M_IOREGH); -} -#else /* !VMM_IOPORT_REG_HANDLER */ -#define invoke_reg_handler(_1, _2, _3, _4, _5) (0) -#endif /* VMM_IOPORT_REG_HANDLER */ - static int emulate_inout_port(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu) { ioport_handler_func_t handler; uint32_t mask, val; - int regh = 0, error = 0; + int error; /* * If there is no handler for the I/O port then punt to userspace. */ - if ((vmexit->u.inout.port >= MAX_IOPORTS || - (handler = ioport_handler[vmexit->u.inout.port]) == NULL) && - (regh = invoke_reg_handler(vm, vcpuid, vmexit, &val, &error)) == 0) { + if (vmexit->u.inout.port >= MAX_IOPORTS || + (handler = ioport_handler[vmexit->u.inout.port]) == NULL) { *retu = true; return (0); } - if (!regh) { - mask = vie_size2mask(vmexit->u.inout.bytes); - - if (!vmexit->u.inout.in) { - val = vmexit->u.inout.eax & mask; - } + mask = vie_size2mask(vmexit->u.inout.bytes); - error = (*handler)(vm, vcpuid, vmexit->u.inout.in, - vmexit->u.inout.port, vmexit->u.inout.bytes, &val); + if (!vmexit->u.inout.in) { + val = vmexit->u.inout.eax & mask; } + error = (*handler)(vm, vcpuid, vmexit->u.inout.in, + vmexit->u.inout.port, vmexit->u.inout.bytes, &val); if (error) { /* * The value returned by this function is also the return value Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 11:12:03 2016 (r307055) @@ -29,22 +29,6 @@ #ifndef _VMM_IOPORT_H_ #define _VMM_IOPORT_H_ -#define VMM_IOPORT_REG_HANDLER -#ifdef VMM_IOPORT_REG_HANDLER -struct ioport_reg_handler; -struct ioregh; - -struct ioregh *ioregh_init(struct vm *vm); -void ioregh_cleanup(struct ioregh *ioregh); - -int vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in, - uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg); -#else /* !VMM_IOPORT_REG_HANDLER */ -#define ioregh_init(_1) (NULL) -#define ioregh_cleanup(_1) -#define vmm_ioport_reg_handler(_1, _2, _3, _4,_5, _6, _7) (EINVAL) -#endif /* VMM_IOPORT_REG_HANDLER */ - typedef int (*ioport_handler_func_t)(struct vm *vm, int vcpuid, bool in, int port, int bytes, uint32_t *val); Modified: soc2016/vincenzo/head/sys/modules/vmm/Makefile ============================================================================== --- soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 11:12:03 2016 (r307055) @@ -21,7 +21,6 @@ vmm_ioport.c \ vmm_lapic.c \ vmm_mem.c \ - vmm_usermem.c \ vmm_stat.c \ vmm_util.c \ x86.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 10:36:58 2016 (r307054) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 11:12:03 2016 (r307055) @@ -147,6 +147,7 @@ struct virtio_net_config vsc_config; pthread_mutex_t rx_mtx; + int rx_in_progress; int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ @@ -196,13 +197,17 @@ /* * If the receive thread is active then stall until it is done. - * It is enough to lock and unlock the RX mutex. */ static void pci_vtnet_rxwait(struct pci_vtnet_softc *sc) { pthread_mutex_lock(&sc->rx_mtx); + while (sc->rx_in_progress) { + pthread_mutex_unlock(&sc->rx_mtx); + usleep(10000); + pthread_mutex_lock(&sc->rx_mtx); + } pthread_mutex_unlock(&sc->rx_mtx); } @@ -579,7 +584,9 @@ struct pci_vtnet_softc *sc = param; pthread_mutex_lock(&sc->rx_mtx); + sc->rx_in_progress = 1; sc->pci_vtnet_rx(sc); + sc->rx_in_progress = 0; pthread_mutex_unlock(&sc->rx_mtx); } @@ -613,11 +620,12 @@ */ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); - tlen = 0; - for (i = 0; i < n; i++) { + plen = 0; + tlen = iov[0].iov_len; + for (i = 1; i < n; i++) { + plen += iov[i].iov_len; tlen += iov[i].iov_len; } - plen = tlen - iov[0].iov_len; DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, n)); sc->pci_vtnet_tx(sc, &iov[1], n - 1, plen); @@ -894,6 +902,7 @@ sc->rx_merge = 1; sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); + sc->rx_in_progress = 0; pthread_mutex_init(&sc->rx_mtx, NULL); /* From owner-svn-soc-all@freebsd.org Mon Aug 1 11:21:21 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 57629BA302D for ; Mon, 1 Aug 2016 11:21:21 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 49C7518BF for ; Mon, 1 Aug 2016 11:21:21 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u71BLLGr057928 for ; Mon, 1 Aug 2016 11:21:21 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u71BLGGn057186 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 11:21:16 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 11:21:16 GMT Message-Id: <201608011121.u71BLGGn057186@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307056 - in soc2016/vincenzo/head: lib/libvmmapi sys/amd64/include sys/amd64/vmm sys/modules/vmm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 11:21:21 -0000 Author: vincenzo Date: Mon Aug 1 11:21:15 2016 New Revision: 307056 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307056 Log: vmm: add support needed for ptnetmap (1) IO register handler (2) memory mapping of host memory in the guest memory This work was done from Stefano Garzarella on top of FreeBSD 10-STABLE. Minor modifications were necessary to port it to FreeBSD 10.3.0-RELEASE. Added: soc2016/vincenzo/head/sys/amd64/vmm/vmm_usermem.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_usermem.h Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h soc2016/vincenzo/head/sys/amd64/include/vmm.h soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h soc2016/vincenzo/head/sys/amd64/vmm/vmm.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h soc2016/vincenzo/head/sys/modules/vmm/Makefile Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c ============================================================================== --- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.c Mon Aug 1 11:21:15 2016 (r307056) @@ -883,6 +883,42 @@ } int +vm_get_fd(struct vmctx *ctx) +{ + return (ctx->fd); +} + +int +vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf) +{ + struct vm_user_buf user_buf; + + bzero(&user_buf, sizeof(user_buf)); + user_buf.gpa = gpa; + user_buf.len = len; + user_buf.addr = host_buf; + + return (ioctl(ctx->fd, VM_MAP_USER_BUF, &user_buf)); +} + +int +vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data, + enum vm_io_regh_type type, void *arg) +{ + struct vm_io_reg_handler ioregh; + + bzero(&ioregh, sizeof(ioregh)); + ioregh.port = port; + ioregh.in = in; + ioregh.mask_data = mask_data; + ioregh.data = data; + ioregh.type = type; + ioregh.arg = arg; + + return (ioctl(ctx->fd, VM_IO_REG_HANDLER, &ioregh)); +} + +int vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, uint64_t addr, uint64_t msg, int numvec) { Modified: soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h ============================================================================== --- soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/lib/libvmmapi/vmmapi.h Mon Aug 1 11:21:15 2016 (r307056) @@ -161,7 +161,10 @@ int vm_get_intinfo(struct vmctx *ctx, int vcpu, uint64_t *i1, uint64_t *i2); int vm_set_intinfo(struct vmctx *ctx, int vcpu, uint64_t exit_intinfo); - +int vm_get_fd(struct vmctx *ctx); +int vm_map_user_buf(struct vmctx *ctx, vm_paddr_t gpa, size_t len, void *host_buf); +int vm_io_reg_handler(struct vmctx *ctx, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg); /* * Return a pointer to the statistics buffer. Note that this is not MT-safe. */ Modified: soc2016/vincenzo/head/sys/amd64/include/vmm.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/amd64/include/vmm.h Mon Aug 1 11:21:15 2016 (r307056) @@ -183,6 +183,7 @@ int vm_alloc_memseg(struct vm *vm, int ident, size_t len, bool sysmem); void vm_free_memseg(struct vm *vm, int ident); int vm_map_mmio(struct vm *vm, vm_paddr_t gpa, size_t len, vm_paddr_t hpa); +int vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td); int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len); int vm_assign_pptdev(struct vm *vm, int bus, int slot, int func); int vm_unassign_pptdev(struct vm *vm, int bus, int slot, int func); @@ -321,6 +322,7 @@ struct vatpit *vm_atpit(struct vm *vm); struct vpmtmr *vm_pmtmr(struct vm *vm); struct vrtc *vm_rtc(struct vm *vm); +struct ioregh *vm_ioregh(struct vm *vm); /* * Inject exception 'vector' into the guest vcpu. This function returns 0 on @@ -417,7 +419,13 @@ EDGE_TRIGGER, LEVEL_TRIGGER }; - + +enum vm_io_regh_type { + VM_IO_REGH_DELETE, + VM_IO_REGH_KWEVENTS, /* kernel wait events */ + VM_IO_REGH_MAX +}; + /* * The 'access' field has the format specified in Table 21-2 of the Intel * Architecture Manual vol 3b. Modified: soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/amd64/include/vmm_dev.h Mon Aug 1 11:21:15 2016 (r307056) @@ -123,6 +123,21 @@ size_t len; }; +struct vm_user_buf { + vm_paddr_t gpa; + void *addr; + size_t len; +}; + +struct vm_io_reg_handler { + uint16_t port; /* I/O address */ + uint16_t in; /* 0 out, 1 in */ + uint32_t mask_data; /* 0 means match anything */ + uint32_t data; /* data to match */ + enum vm_io_regh_type type; /* handler type */ + void *arg; /* handler argument */ +}; + struct vm_pptdev_msi { int vcpu; int bus; @@ -286,6 +301,10 @@ IOCNUM_RTC_WRITE = 101, IOCNUM_RTC_SETTIME = 102, IOCNUM_RTC_GETTIME = 103, + + /* host mmap and IO handler */ + IOCNUM_MAP_USER_BUF = 104, + IOCNUM_IO_REG_HANDLER = 105, }; #define VM_RUN \ @@ -344,6 +363,10 @@ _IOW('v', IOCNUM_UNBIND_PPTDEV, struct vm_pptdev) #define VM_MAP_PPTDEV_MMIO \ _IOW('v', IOCNUM_MAP_PPTDEV_MMIO, struct vm_pptdev_mmio) +#define VM_MAP_USER_BUF \ + _IOW('v', IOCNUM_MAP_USER_BUF, struct vm_user_buf) +#define VM_IO_REG_HANDLER \ + _IOW('v', IOCNUM_IO_REG_HANDLER, struct vm_io_reg_handler) #define VM_PPTDEV_MSI \ _IOW('v', IOCNUM_PPTDEV_MSI, struct vm_pptdev_msi) #define VM_PPTDEV_MSIX \ Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm.c Mon Aug 1 11:21:15 2016 (r307056) @@ -66,6 +66,7 @@ #include "vmm_ktr.h" #include "vmm_host.h" #include "vmm_mem.h" +#include "vmm_usermem.h" #include "vmm_util.h" #include "vatpic.h" #include "vatpit.h" @@ -148,6 +149,7 @@ struct vatpit *vatpit; /* (i) virtual atpit */ struct vpmtmr *vpmtmr; /* (i) virtual ACPI PM timer */ struct vrtc *vrtc; /* (o) virtual RTC */ + struct ioregh *ioregh; /* () I/O reg handler */ volatile cpuset_t active_cpus; /* (i) active vcpus */ int suspend; /* (i) stop VM execution */ volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */ @@ -419,6 +421,7 @@ vm->vpmtmr = vpmtmr_init(vm); if (create) vm->vrtc = vrtc_init(vm); + vm->ioregh = ioregh_init(vm); CPU_ZERO(&vm->active_cpus); @@ -475,11 +478,13 @@ vrtc_cleanup(vm->vrtc); else vrtc_reset(vm->vrtc); + ioregh_cleanup(vm->ioregh); vpmtmr_cleanup(vm->vpmtmr); vatpit_cleanup(vm->vatpit); vhpet_cleanup(vm->vhpet); vatpic_cleanup(vm->vatpic); vioapic_cleanup(vm->vioapic); + vmm_usermem_cleanup(vm->vmspace); for (i = 0; i < VM_MAXCPU; i++) vcpu_cleanup(vm, i, destroy); @@ -553,6 +558,17 @@ } int +vm_map_usermem(struct vm *vm, vm_paddr_t gpa, size_t len, void *buf, struct thread *td) +{ + vm_object_t obj; + + if ((obj = vmm_usermem_alloc(vm->vmspace, gpa, len, buf, td)) == NULL) + return (ENOMEM); + + return (0); +} + +int vm_unmap_mmio(struct vm *vm, vm_paddr_t gpa, size_t len) { @@ -588,6 +604,9 @@ if (ppt_is_mmio(vm, gpa)) return (true); /* 'gpa' is pci passthru mmio */ + if (usermem_mapped(vm->vmspace, gpa)) + return (true); /* 'gpa' is user-space buffer mapped */ + return (false); } @@ -2457,6 +2476,12 @@ return (vm->vrtc); } +struct ioregh * +vm_ioregh(struct vm *vm) +{ + return (vm->ioregh); +} + enum vm_reg_name vm_segment_name(int seg) { Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_dev.c Mon Aug 1 11:21:15 2016 (r307056) @@ -55,6 +55,7 @@ #include "vmm_lapic.h" #include "vmm_stat.h" #include "vmm_mem.h" +#include "vmm_ioport.h" #include "io/ppt.h" #include "io/vatpic.h" #include "io/vioapic.h" @@ -300,6 +301,8 @@ struct vm_pptdev_mmio *pptmmio; struct vm_pptdev_msi *pptmsi; struct vm_pptdev_msix *pptmsix; + struct vm_user_buf *usermem; + struct vm_io_reg_handler *ioregh; struct vm_nmi *vmnmi; struct vm_stats *vmstats; struct vm_stat_desc *statdesc; @@ -358,6 +361,7 @@ case VM_UNBIND_PPTDEV: case VM_ALLOC_MEMSEG: case VM_MMAP_MEMSEG: + case VM_MAP_USER_BUF: case VM_REINIT: /* * ioctls that operate on the entire virtual machine must @@ -433,6 +437,16 @@ pptmmio->func, pptmmio->gpa, pptmmio->len, pptmmio->hpa); break; + case VM_MAP_USER_BUF: + usermem = (struct vm_user_buf *)data; + error = vm_map_usermem(sc->vm, usermem->gpa, usermem->len, + usermem->addr, td); + break; + case VM_IO_REG_HANDLER: + ioregh = (struct vm_io_reg_handler *)data; + error = vmm_ioport_reg_handler(sc->vm, ioregh->port, ioregh->in, ioregh->mask_data, + ioregh->data, ioregh->type, ioregh->arg); + break; case VM_BIND_PPTDEV: pptdev = (struct vm_pptdev *)data; error = vm_assign_pptdev(sc->vm, pptdev->bus, pptdev->slot, Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 11:21:15 2016 (r307056) @@ -97,31 +97,278 @@ } #endif /* KTR */ +#ifdef VMM_IOPORT_REG_HANDLER +#include +#include +#include +#include +#include + +static MALLOC_DEFINE(M_IOREGH, "ioregh", "bhyve ioport reg handlers"); + +#define IOREGH_LOCK(ioregh) mtx_lock_spin(&((ioregh)->mtx)) +#define IOREGH_UNLOCK(ioregh) mtx_unlock_spin(&((ioregh)->mtx)) + +#define IOPORT_MAX_REG_HANDLER 12 + +/* + * ioport_reg_handler functions allows us to to catch VM write/read + * on specific I/O address and send notification. + * + * When the VM writes or reads a specific value on I/O address, if the address + * and the value matches with the info stored durign the handler registration, + * then we send a notification (we can have multiple type of notification, + * but for now is implemented only the VM_IO_REGH_KWEVENTS handler. + */ + +typedef int (*ioport_reg_handler_func_t)(struct vm *vm, + struct ioport_reg_handler *regh, uint32_t *val); + +struct ioport_reg_handler { + uint16_t port; /* I/O address */ + uint16_t in; /* 0 out, 1 in */ + uint32_t mask_data; /* 0 means match anything */ + uint32_t data; /* data to match */ + ioport_reg_handler_func_t handler; /* handler pointer */ + void *handler_arg; /* handler argument */ +}; + +struct ioregh { + struct mtx mtx; + /* TODO: use hash table is better */ + struct ioport_reg_handler handlers[IOPORT_MAX_REG_HANDLER]; +}; + +/* ----- I/O reg handlers ----- */ + +/* + * VM_IO_REGH_KWEVENTS handler + * + * wakeup() on specified address that uniquely identifies the event + * + */ +static int +vmm_ioport_reg_wakeup(struct vm *vm, struct ioport_reg_handler *regh, uint32_t *val) +{ + wakeup(regh->handler_arg); + return (0); +} + +/* + * TODO: + * - VM_IO_REGH_CONDSIGNAL: pthread_cond_signal + * - VM_IO_REGH_WRITEFD: write on fd + * - VM_IO_REGH_IOCTL: ioctl on fd + */ + +/* call with ioregh->mtx held */ +static struct ioport_reg_handler * +vmm_ioport_find_handler(struct ioregh *ioregh, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data) +{ + struct ioport_reg_handler *regh; + uint32_t mask; + int i; + + regh = ioregh->handlers; + for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) { + if (regh[i].handler != NULL) { + mask = regh[i].mask_data & mask_data; + if ((regh[i].port == port) && (regh[i].in == in) + && ((mask & regh[i].data) == (mask & data))) { + return ®h[i]; + } + } + } + + return (NULL); +} + +/* call with ioregh->mtx held */ +static struct ioport_reg_handler * +vmm_ioport_empty_handler(struct ioregh *ioregh) +{ + struct ioport_reg_handler *regh; + int i; + + regh = ioregh->handlers; + for (i = 0; i < IOPORT_MAX_REG_HANDLER; i++) { + if (regh[i].handler == NULL) { + return ®h[i]; + } + } + + return (NULL); +} + + +static int +vmm_ioport_add_handler(struct vm *vm, uint16_t port, uint16_t in, uint32_t mask_data, + uint32_t data, ioport_reg_handler_func_t handler, void *handler_arg) +{ + struct ioport_reg_handler *regh; + struct ioregh *ioregh; + int ret = 0; + + ioregh = vm_ioregh(vm); + + IOREGH_LOCK(ioregh); + + regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); + if (regh != NULL) { + printf("%s: handler for port %d in %d mask_data %d data %d \ + already registered\n", + __FUNCTION__, port, in, mask_data, data); + ret = EEXIST; + goto err; + } + + regh = vmm_ioport_empty_handler(ioregh); + if (regh == NULL) { + printf("%s: empty reg_handler slot not found\n", __FUNCTION__); + ret = ENOMEM; + goto err; + } + + regh->port = port; + regh->in = in; + regh->mask_data = mask_data; + regh->data = data; + regh->handler = handler; + regh->handler_arg = handler_arg; + +err: + IOREGH_UNLOCK(ioregh); + return (ret); +} + +static int +vmm_ioport_del_handler(struct vm *vm, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data) +{ + struct ioport_reg_handler *regh; + struct ioregh *ioregh; + int ret = 0; + + ioregh = vm_ioregh(vm); + + IOREGH_LOCK(ioregh); + + regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); + + if (regh == NULL) { + ret = EINVAL; + goto err; + } + + bzero(regh, sizeof(struct ioport_reg_handler)); +err: + IOREGH_UNLOCK(ioregh); + return (ret); +} + +/* + * register or delete a new I/O event handler. + */ +int +vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg) +{ + int ret = 0; + + switch (type) { + case VM_IO_REGH_DELETE: + ret = vmm_ioport_del_handler(vm, port, in, mask_data, data); + break; + case VM_IO_REGH_KWEVENTS: + ret = vmm_ioport_add_handler(vm, port, in, mask_data, data, + vmm_ioport_reg_wakeup, arg); + break; + default: + printf("%s: unknown reg_handler type\n", __FUNCTION__); + ret = EINVAL; + break; + } + + return (ret); +} + +/* + * Invoke an handler, if the data matches. + */ +static int +invoke_reg_handler(struct vm *vm, int vcpuid, struct vm_exit *vmexit, + uint32_t *val, int *error) +{ + struct ioport_reg_handler *regh; + struct ioregh *ioregh; + uint32_t mask_data; + + mask_data = vie_size2mask(vmexit->u.inout.bytes); + ioregh = vm_ioregh(vm); + + IOREGH_LOCK(ioregh); + regh = vmm_ioport_find_handler(ioregh, vmexit->u.inout.port, + vmexit->u.inout.in, mask_data, vmexit->u.inout.eax); + if (regh == NULL) { + IOREGH_UNLOCK(ioregh); + return (0); + } + *error = (*(regh->handler))(vm, regh, val); + IOREGH_UNLOCK(ioregh); + return (1); +} + +struct ioregh * +ioregh_init(struct vm *vm) +{ + struct ioregh *ioregh; + + ioregh = malloc(sizeof(struct ioregh), M_IOREGH, M_WAITOK | M_ZERO); + + mtx_init(&ioregh->mtx, "ioregh lock", NULL, MTX_SPIN); + + return (ioregh); +} + +void +ioregh_cleanup(struct ioregh *ioregh) +{ + free(ioregh, M_IOREGH); +} +#else /* !VMM_IOPORT_REG_HANDLER */ +#define invoke_reg_handler(_1, _2, _3, _4, _5) (0) +#endif /* VMM_IOPORT_REG_HANDLER */ + static int emulate_inout_port(struct vm *vm, int vcpuid, struct vm_exit *vmexit, bool *retu) { ioport_handler_func_t handler; uint32_t mask, val; - int error; + int regh = 0, error = 0; /* * If there is no handler for the I/O port then punt to userspace. */ - if (vmexit->u.inout.port >= MAX_IOPORTS || - (handler = ioport_handler[vmexit->u.inout.port]) == NULL) { + if ((vmexit->u.inout.port >= MAX_IOPORTS || + (handler = ioport_handler[vmexit->u.inout.port]) == NULL) && + (regh = invoke_reg_handler(vm, vcpuid, vmexit, &val, &error)) == 0) { *retu = true; return (0); } - mask = vie_size2mask(vmexit->u.inout.bytes); + if (!regh) { + mask = vie_size2mask(vmexit->u.inout.bytes); + + if (!vmexit->u.inout.in) { + val = vmexit->u.inout.eax & mask; + } - if (!vmexit->u.inout.in) { - val = vmexit->u.inout.eax & mask; + error = (*handler)(vm, vcpuid, vmexit->u.inout.in, + vmexit->u.inout.port, vmexit->u.inout.bytes, &val); } - error = (*handler)(vm, vcpuid, vmexit->u.inout.in, - vmexit->u.inout.port, vmexit->u.inout.bytes, &val); if (error) { /* * The value returned by this function is also the return value Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.h Mon Aug 1 11:21:15 2016 (r307056) @@ -29,6 +29,22 @@ #ifndef _VMM_IOPORT_H_ #define _VMM_IOPORT_H_ +#define VMM_IOPORT_REG_HANDLER +#ifdef VMM_IOPORT_REG_HANDLER +struct ioport_reg_handler; +struct ioregh; + +struct ioregh *ioregh_init(struct vm *vm); +void ioregh_cleanup(struct ioregh *ioregh); + +int vmm_ioport_reg_handler(struct vm *vm, uint16_t port, uint16_t in, + uint32_t mask_data, uint32_t data, enum vm_io_regh_type type, void *arg); +#else /* !VMM_IOPORT_REG_HANDLER */ +#define ioregh_init(_1) (NULL) +#define ioregh_cleanup(_1) +#define vmm_ioport_reg_handler(_1, _2, _3, _4,_5, _6, _7) (EINVAL) +#endif /* VMM_IOPORT_REG_HANDLER */ + typedef int (*ioport_handler_func_t)(struct vm *vm, int vcpuid, bool in, int port, int bytes, uint32_t *val); Added: soc2016/vincenzo/head/sys/amd64/vmm/vmm_usermem.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_usermem.c Mon Aug 1 11:21:15 2016 (r307056) @@ -0,0 +1,186 @@ +/* + * Copyright (C) 2015 Stefano Garzarella (stefano.garzarella@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "vmm_mem.h" +#include "vmm_usermem.h" + +/* + * usermem functions allow us to map an host userspace buffer (eg. from bhyve) + * in the guest VM. + * + * This feature is used to implement ptnetmap on bhyve, mapping the netmap memory + * (returned by the mmap() in the byvhe userspace application) in the guest VM. + */ + +/* TODO: we can create a dynamical list of usermem */ +#define MAX_USERMEMS 64 + +static struct usermem { + struct vmspace *vmspace; /* guest address space */ + vm_paddr_t gpa; /* guest physical address */ + size_t len; +} usermems[MAX_USERMEMS]; + +static int +vmm_usermem_add(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].len == 0) { + usermems[i].vmspace = vmspace; + usermems[i].gpa = gpa; + usermems[i].len = len; + break; + } + } + + if (i == MAX_USERMEMS) { + printf("vmm_usermem_add: empty usermem slot not found\n"); + return (ENOMEM); + } + + return 0; +} + +static int +vmm_usermem_del(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].vmspace == vmspace && usermems[i].gpa == gpa + && usermems[i].len == len) { + bzero(&usermems[i], sizeof(struct usermem)); + return 1; + } + } + + return 0; +} + +boolean_t +usermem_mapped(struct vmspace *vmspace, vm_paddr_t gpa) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].vmspace != vmspace || usermems[i].len == 0) + continue; + if (gpa >= usermems[i].gpa && + gpa < usermems[i].gpa + usermems[i].len) + return (TRUE); + } + return (FALSE); +} + +vm_object_t +vmm_usermem_alloc(struct vmspace *vmspace, vm_paddr_t gpa, size_t len, + void *buf, struct thread *td) +{ + int error; + vm_object_t obj; + vm_map_t map; + vm_map_entry_t entry; + vm_pindex_t index; + vm_prot_t prot; + boolean_t wired; + + map = &td->td_proc->p_vmspace->vm_map; + /* lookup the vm_object that describe user addr */ + error = vm_map_lookup(&map, (unsigned long)buf, VM_PROT_RW, &entry, + &obj, &index, &prot, &wired); + + /* map th vm_object in the vmspace */ + if (obj != NULL) { + error = vm_map_find(&vmspace->vm_map, obj, index, &gpa, len, 0, + VMFS_NO_SPACE, VM_PROT_RW, VM_PROT_RW, 0); + if (error != KERN_SUCCESS) { + vm_object_deallocate(obj); + obj = NULL; + } + } + vm_map_lookup_done(map, entry); + + /* acquire the reference to the vm_object */ + if (obj != NULL) { + vm_object_reference(obj); + vmm_usermem_add(vmspace, gpa, len); + } + + return (obj); +} + +void +vmm_usermem_free(struct vmspace *vmspace, vm_paddr_t gpa, size_t len) +{ + int ret; + + ret = vmm_usermem_del(vmspace, gpa, len); + if (ret) { + //TODO check return value of vm_map_remove ? + vm_map_remove(&vmspace->vm_map, gpa, gpa + len); + //TODO should we call vm_object_deallocate ? + } +} + +void +vmm_usermem_cleanup(struct vmspace *vmspace) +{ + int i; + + for (i = 0; i < MAX_USERMEMS; i++) { + if (usermems[i].vmspace == vmspace) { + //TODO same as above + vm_map_remove(&vmspace->vm_map, usermems[i].gpa, + usermems[i].gpa + usermems[i].len); + bzero(&usermems[i], sizeof(struct usermem)); + } + } +} Added: soc2016/vincenzo/head/sys/amd64/vmm/vmm_usermem.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_usermem.h Mon Aug 1 11:21:15 2016 (r307056) @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Stefano Garzarella (stefano.garzarella@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _VMM_USERMEM_H_ +#define _VMM_USERMEM_H_ + +struct vm; + +struct vm_object *vmm_usermem_alloc(struct vmspace *, vm_paddr_t gpa, + size_t len, void *buf, struct thread *td); +void vmm_usermem_free(struct vmspace *, vm_paddr_t gpa, size_t len); +void vmm_usermem_cleanup(struct vmspace *); +boolean_t usermem_mapped(struct vmspace *, vm_paddr_t gpa); + +#endif Modified: soc2016/vincenzo/head/sys/modules/vmm/Makefile ============================================================================== --- soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 11:12:03 2016 (r307055) +++ soc2016/vincenzo/head/sys/modules/vmm/Makefile Mon Aug 1 11:21:15 2016 (r307056) @@ -21,6 +21,7 @@ vmm_ioport.c \ vmm_lapic.c \ vmm_mem.c \ + vmm_usermem.c \ vmm_stat.c \ vmm_util.c \ x86.c From owner-svn-soc-all@freebsd.org Mon Aug 1 11:22:37 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DE45FBA3149 for ; Mon, 1 Aug 2016 11:22:37 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D1CF019E5 for ; Mon, 1 Aug 2016 11:22:37 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u71BMbRj063993 for ; Mon, 1 Aug 2016 11:22:37 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u71BMbg2063939 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 11:22:37 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 11:22:37 GMT Message-Id: <201608011122.u71BMbg2063939@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307057 - soc2016/vincenzo/head/sys/amd64/vmm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 11:22:38 -0000 Author: vincenzo Date: Mon Aug 1 11:22:36 2016 New Revision: 307057 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307057 Log: vmm: ioregh: use sx lock in place of spin lock Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Modified: soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c ============================================================================== --- soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 11:21:15 2016 (r307056) +++ soc2016/vincenzo/head/sys/amd64/vmm/vmm_ioport.c Mon Aug 1 11:22:36 2016 (r307057) @@ -99,17 +99,15 @@ #ifdef VMM_IOPORT_REG_HANDLER #include +#include #include +#include #include -#include #include static MALLOC_DEFINE(M_IOREGH, "ioregh", "bhyve ioport reg handlers"); -#define IOREGH_LOCK(ioregh) mtx_lock_spin(&((ioregh)->mtx)) -#define IOREGH_UNLOCK(ioregh) mtx_unlock_spin(&((ioregh)->mtx)) - -#define IOPORT_MAX_REG_HANDLER 12 +#define IOPORT_MAX_REG_HANDLER 16 /* * ioport_reg_handler functions allows us to to catch VM write/read @@ -134,8 +132,8 @@ }; struct ioregh { - struct mtx mtx; - /* TODO: use hash table is better */ + struct sx lock; + /* TODO: use hash table */ struct ioport_reg_handler handlers[IOPORT_MAX_REG_HANDLER]; }; @@ -161,7 +159,7 @@ * - VM_IO_REGH_IOCTL: ioctl on fd */ -/* call with ioregh->mtx held */ +/* call with ioregh->lock held */ static struct ioport_reg_handler * vmm_ioport_find_handler(struct ioregh *ioregh, uint16_t port, uint16_t in, uint32_t mask_data, uint32_t data) @@ -184,7 +182,7 @@ return (NULL); } -/* call with ioregh->mtx held */ +/* call with ioregh->lock held */ static struct ioport_reg_handler * vmm_ioport_empty_handler(struct ioregh *ioregh) { @@ -212,7 +210,7 @@ ioregh = vm_ioregh(vm); - IOREGH_LOCK(ioregh); + sx_xlock(&ioregh->lock); regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); if (regh != NULL) { @@ -238,7 +236,7 @@ regh->handler_arg = handler_arg; err: - IOREGH_UNLOCK(ioregh); + sx_xunlock(&ioregh->lock); return (ret); } @@ -252,7 +250,7 @@ ioregh = vm_ioregh(vm); - IOREGH_LOCK(ioregh); + sx_xlock(&ioregh->lock); regh = vmm_ioport_find_handler(ioregh, port, in, mask_data, data); @@ -263,7 +261,7 @@ bzero(regh, sizeof(struct ioport_reg_handler)); err: - IOREGH_UNLOCK(ioregh); + sx_xunlock(&ioregh->lock); return (ret); } @@ -298,7 +296,7 @@ */ static int invoke_reg_handler(struct vm *vm, int vcpuid, struct vm_exit *vmexit, - uint32_t *val, int *error) + uint32_t *val, int *error) { struct ioport_reg_handler *regh; struct ioregh *ioregh; @@ -307,16 +305,14 @@ mask_data = vie_size2mask(vmexit->u.inout.bytes); ioregh = vm_ioregh(vm); - IOREGH_LOCK(ioregh); + sx_slock(&ioregh->lock); regh = vmm_ioport_find_handler(ioregh, vmexit->u.inout.port, vmexit->u.inout.in, mask_data, vmexit->u.inout.eax); - if (regh == NULL) { - IOREGH_UNLOCK(ioregh); - return (0); + if (regh != NULL) { + *error = (*(regh->handler))(vm, regh, val); } - *error = (*(regh->handler))(vm, regh, val); - IOREGH_UNLOCK(ioregh); - return (1); + sx_sunlock(&ioregh->lock); + return (regh != NULL); } struct ioregh * @@ -325,8 +321,7 @@ struct ioregh *ioregh; ioregh = malloc(sizeof(struct ioregh), M_IOREGH, M_WAITOK | M_ZERO); - - mtx_init(&ioregh->mtx, "ioregh lock", NULL, MTX_SPIN); + sx_init(&ioregh->lock, "ioregh lock"); return (ioregh); } @@ -334,6 +329,7 @@ void ioregh_cleanup(struct ioregh *ioregh) { + sx_destroy(&ioregh->lock); free(ioregh, M_IOREGH); } #else /* !VMM_IOPORT_REG_HANDLER */ From owner-svn-soc-all@freebsd.org Mon Aug 1 11:23:54 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7677BBA31DF for ; Mon, 1 Aug 2016 11:23:54 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 69F331A0F for ; Mon, 1 Aug 2016 11:23:54 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u71BNs2W066055 for ; Mon, 1 Aug 2016 11:23:54 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u71BNrcO065998 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 11:23:53 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 11:23:53 GMT Message-Id: <201608011123.u71BNrcO065998@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307058 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 11:23:54 -0000 Author: vincenzo Date: Mon Aug 1 11:23:53 2016 New Revision: 307058 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307058 Log: pci_vtnet_proctx: optimize computation of plen and tlen Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 11:22:36 2016 (r307057) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 11:23:53 2016 (r307058) @@ -147,7 +147,7 @@ struct virtio_net_config vsc_config; pthread_mutex_t rx_mtx; - int rx_in_progress; + int rx_in_progress; /* XXX-VM: useless. */ int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ @@ -620,12 +620,11 @@ */ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); - plen = 0; - tlen = iov[0].iov_len; - for (i = 1; i < n; i++) { - plen += iov[i].iov_len; + tlen = 0; + for (i = 0; i < n; i++) { tlen += iov[i].iov_len; } + plen = tlen - iov[0].iov_len; DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, n)); sc->pci_vtnet_tx(sc, &iov[1], n - 1, plen); From owner-svn-soc-all@freebsd.org Mon Aug 1 11:24:10 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id A7D1BBA3212 for ; Mon, 1 Aug 2016 11:24:10 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9B5341A2F for ; Mon, 1 Aug 2016 11:24:10 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u71BOA3g066624 for ; Mon, 1 Aug 2016 11:24:10 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u71BOA9e066521 for svn-soc-all@FreeBSD.org; Mon, 1 Aug 2016 11:24:10 GMT (envelope-from vincenzo@FreeBSD.org) Date: Mon, 1 Aug 2016 11:24:10 GMT Message-Id: <201608011124.u71BOA9e066521@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307059 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Aug 2016 11:24:10 -0000 Author: vincenzo Date: Mon Aug 1 11:24:09 2016 New Revision: 307059 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307059 Log: pci_virtio_net: remove useless rx_in_progress flag Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 11:23:53 2016 (r307058) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Mon Aug 1 11:24:09 2016 (r307059) @@ -147,7 +147,6 @@ struct virtio_net_config vsc_config; pthread_mutex_t rx_mtx; - int rx_in_progress; /* XXX-VM: useless. */ int rx_vhdrlen; int rx_merge; /* merged rx bufs in use */ @@ -197,17 +196,13 @@ /* * If the receive thread is active then stall until it is done. + * It is enough to lock and unlock the RX mutex. */ static void pci_vtnet_rxwait(struct pci_vtnet_softc *sc) { pthread_mutex_lock(&sc->rx_mtx); - while (sc->rx_in_progress) { - pthread_mutex_unlock(&sc->rx_mtx); - usleep(10000); - pthread_mutex_lock(&sc->rx_mtx); - } pthread_mutex_unlock(&sc->rx_mtx); } @@ -584,9 +579,7 @@ struct pci_vtnet_softc *sc = param; pthread_mutex_lock(&sc->rx_mtx); - sc->rx_in_progress = 1; sc->pci_vtnet_rx(sc); - sc->rx_in_progress = 0; pthread_mutex_unlock(&sc->rx_mtx); } @@ -901,7 +894,6 @@ sc->rx_merge = 1; sc->rx_vhdrlen = sizeof(struct virtio_net_rxhdr); - sc->rx_in_progress = 0; pthread_mutex_init(&sc->rx_mtx, NULL); /* From owner-svn-soc-all@freebsd.org Fri Aug 5 13:50:39 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 457B7BAFB6C for ; Fri, 5 Aug 2016 13:50:39 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3785118B1 for ; Fri, 5 Aug 2016 13:50:39 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75DodCS025663 for ; Fri, 5 Aug 2016 13:50:39 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75Docov025660 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:50:38 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:50:38 GMT Message-Id: <201608051350.u75Docov025660@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307216 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:50:39 -0000 Author: vincenzo Date: Fri Aug 5 13:50:37 2016 New Revision: 307216 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307216 Log: net: add net_backends module Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 09:08:00 2016 (r307215) +++ soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 13:50:37 2016 (r307216) @@ -25,6 +25,7 @@ mem.c \ mevent.c \ mptbl.c \ + net_backends.c \ pci_ahci.c \ pci_emul.c \ pci_hostbridge.c \ @@ -50,6 +51,8 @@ LIBADD= vmmapi md pthread +CFLAGS=-I/home/vmaffione/git/netmap/sys + WARNS?= 2 .include Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 09:08:00 2016 (r307215) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 13:50:37 2016 (r307216) @@ -58,34 +58,12 @@ #include "pci_emul.h" #include "mevent.h" #include "virtio.h" +#include "net_backends.h" #define VTNET_RINGSZ 1024 #define VTNET_MAXSEGS 256 -/* - * Host capabilities. Note that we only offer a few of these. - */ -#define VIRTIO_NET_F_CSUM (1 << 0) /* host handles partial cksum */ -#define VIRTIO_NET_F_GUEST_CSUM (1 << 1) /* guest handles partial cksum */ -#define VIRTIO_NET_F_MAC (1 << 5) /* host supplies MAC */ -#define VIRTIO_NET_F_GSO_DEPREC (1 << 6) /* deprecated: host handles GSO */ -#define VIRTIO_NET_F_GUEST_TSO4 (1 << 7) /* guest can rcv TSOv4 */ -#define VIRTIO_NET_F_GUEST_TSO6 (1 << 8) /* guest can rcv TSOv6 */ -#define VIRTIO_NET_F_GUEST_ECN (1 << 9) /* guest can rcv TSO with ECN */ -#define VIRTIO_NET_F_GUEST_UFO (1 << 10) /* guest can rcv UFO */ -#define VIRTIO_NET_F_HOST_TSO4 (1 << 11) /* host can rcv TSOv4 */ -#define VIRTIO_NET_F_HOST_TSO6 (1 << 12) /* host can rcv TSOv6 */ -#define VIRTIO_NET_F_HOST_ECN (1 << 13) /* host can rcv TSO with ECN */ -#define VIRTIO_NET_F_HOST_UFO (1 << 14) /* host can rcv UFO */ -#define VIRTIO_NET_F_MRG_RXBUF (1 << 15) /* host can merge RX buffers */ -#define VIRTIO_NET_F_STATUS (1 << 16) /* config status field available */ -#define VIRTIO_NET_F_CTRL_VQ (1 << 17) /* control channel available */ -#define VIRTIO_NET_F_CTRL_RX (1 << 18) /* control channel RX mode support */ -#define VIRTIO_NET_F_CTRL_VLAN (1 << 19) /* control channel VLAN filtering */ -#define VIRTIO_NET_F_GUEST_ANNOUNCE \ - (1 << 21) /* guest can send gratuitous pkts */ - #define VTNET_S_HOSTCAPS \ ( VIRTIO_NET_F_MAC | VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_STATUS | \ VIRTIO_F_NOTIFY_ON_EMPTY | VIRTIO_RING_F_INDIRECT_DESC) @@ -96,6 +74,7 @@ struct virtio_net_config { uint8_t mac[6]; uint16_t status; + uint16_t max_virtqueue_pairs; } __packed; /* @@ -108,19 +87,6 @@ #define VTNET_MAXQ 3 /* - * Fixed network header size - */ -struct virtio_net_rxhdr { - uint8_t vrh_flags; - uint8_t vrh_gso_type; - uint16_t vrh_hdr_len; - uint16_t vrh_gso_size; - uint16_t vrh_csum_start; - uint16_t vrh_csum_offset; - uint16_t vrh_bufs; -} __packed; - -/* * Debug printf */ static int pci_vtnet_debug; @@ -134,10 +100,8 @@ struct virtio_softc vsc_vs; struct vqueue_info vsc_queues[VTNET_MAXQ - 1]; pthread_mutex_t vsc_mtx; - struct mevent *vsc_mevp; - int vsc_tapfd; - struct nm_desc *vsc_nmd; + struct net_backend *vsc_be; int vsc_rx_ready; volatile int resetting; /* set and checked outside lock */ @@ -154,10 +118,6 @@ pthread_mutex_t tx_mtx; pthread_cond_t tx_cond; int tx_in_progress; - - void (*pci_vtnet_rx)(struct pci_vtnet_softc *sc); - void (*pci_vtnet_tx)(struct pci_vtnet_softc *sc, struct iovec *iov, - int iovcnt, int len); }; static void pci_vtnet_reset(void *); @@ -233,280 +193,47 @@ } /* - * Called to send a buffer chain out to the tap device - */ -static void -pci_vtnet_tap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt, - int len) -{ - static char pad[60]; /* all zero bytes */ - - if (sc->vsc_tapfd == -1) - return; - - /* - * If the length is < 60, pad out to that and add the - * extra zero'd segment to the iov. It is guaranteed that - * there is always an extra iov available by the caller. - */ - if (len < 60) { - iov[iovcnt].iov_base = pad; - iov[iovcnt].iov_len = 60 - len; - iovcnt++; - } - (void) writev(sc->vsc_tapfd, iov, iovcnt); -} - -/* * Called when there is read activity on the tap file descriptor. * Each buffer posted by the guest is assumed to be able to contain * an entire ethernet frame + rx header. * MP note: the dummybuf is only used for discarding frames, so there * is no need for it to be per-vtnet or locked. */ -static uint8_t dummybuf[2048]; - -static __inline struct iovec * -rx_iov_trim(struct iovec *iov, int *niov, int tlen) -{ - struct iovec *riov; - - /* XXX short-cut: assume first segment is >= tlen */ - assert(iov[0].iov_len >= tlen); - - iov[0].iov_len -= tlen; - if (iov[0].iov_len == 0) { - assert(*niov > 1); - *niov -= 1; - riov = &iov[1]; - } else { - iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base + tlen); - riov = &iov[0]; - } - return (riov); -} - -static void -pci_vtnet_tap_rx(struct pci_vtnet_softc *sc) +void +pci_vtnet_rx_discard(struct pci_vtnet_softc *sc, struct iovec *iov) { - struct iovec iov[VTNET_MAXSEGS], *riov; - struct vqueue_info *vq; - void *vrx; - int len, n; - uint16_t idx; - - /* - * Should never be called without a valid tap fd - */ - assert(sc->vsc_tapfd != -1); - /* - * But, will be called when the rx ring hasn't yet - * been set up or the guest is resetting the device. + * MP note: the dummybuf is only used to discard frames, + * so there is no need for it to be per-vtnet or locked. + * We only make it large enough for TSO-sized segment. */ - if (!sc->vsc_rx_ready || sc->resetting) { - /* - * Drop the packet and try later. - */ - (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); - return; - } - - /* - * Check for available rx buffers - */ - vq = &sc->vsc_queues[VTNET_RXQ]; - if (!vq_has_descs(vq)) { - /* - * Drop the packet and try later. Interrupt on - * empty, if that's negotiated. - */ - (void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf)); - vq_endchains(vq, 1); - return; - } - - do { - /* - * Get descriptor chain. - */ - n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); - assert(n >= 1 && n <= VTNET_MAXSEGS); - - /* - * Get a pointer to the rx header, and use the - * data immediately following it for the packet buffer. - */ - vrx = iov[0].iov_base; - riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen); - - len = readv(sc->vsc_tapfd, riov, n); - - if (len < 0 && errno == EWOULDBLOCK) { - /* - * No more packets, but still some avail ring - * entries. Interrupt if needed/appropriate. - */ - vq_retchain(vq); - vq_endchains(vq, 0); - return; - } - - /* - * The only valid field in the rx packet header is the - * number of buffers if merged rx bufs were negotiated. - */ - memset(vrx, 0, sc->rx_vhdrlen); - - if (sc->rx_merge) { - struct virtio_net_rxhdr *vrxh; + static uint8_t dummybuf[65536+64]; + int more; - vrxh = vrx; - vrxh->vrh_bufs = 1; - } - - /* - * Release this chain and handle more chains. - */ - vq_relchain(vq, idx, len + sc->rx_vhdrlen); - } while (vq_has_descs(vq)); - - /* Interrupt if needed, including for NOTIFY_ON_EMPTY. */ - vq_endchains(vq, 1); -} - -static __inline int -pci_vtnet_netmap_writev(struct nm_desc *nmd, struct iovec *iov, int iovcnt) -{ - int r, i; - int len = 0; - - for (r = nmd->cur_tx_ring; ; ) { - struct netmap_ring *ring = NETMAP_TXRING(nmd->nifp, r); - uint32_t cur, idx; - char *buf; - - if (nm_ring_empty(ring)) { - r++; - if (r > nmd->last_tx_ring) - r = nmd->first_tx_ring; - if (r == nmd->cur_tx_ring) - break; - continue; - } - cur = ring->cur; - idx = ring->slot[cur].buf_idx; - buf = NETMAP_BUF(ring, idx); - - for (i = 0; i < iovcnt; i++) { - if (len + iov[i].iov_len > 2048) - break; - memcpy(&buf[len], iov[i].iov_base, iov[i].iov_len); - len += iov[i].iov_len; - } - ring->slot[cur].len = len; - ring->head = ring->cur = nm_ring_next(ring, cur); - nmd->cur_tx_ring = r; - ioctl(nmd->fd, NIOCTXSYNC, NULL); - break; - } - - return (len); -} - -static __inline int -pci_vtnet_netmap_readv(struct nm_desc *nmd, struct iovec *iov, int iovcnt) -{ - int len = 0; - int i = 0; - int r; - - for (r = nmd->cur_rx_ring; ; ) { - struct netmap_ring *ring = NETMAP_RXRING(nmd->nifp, r); - uint32_t cur, idx; - char *buf; - size_t left; - - if (nm_ring_empty(ring)) { - r++; - if (r > nmd->last_rx_ring) - r = nmd->first_rx_ring; - if (r == nmd->cur_rx_ring) - break; - continue; - } - cur = ring->cur; - idx = ring->slot[cur].buf_idx; - buf = NETMAP_BUF(ring, idx); - left = ring->slot[cur].len; - - for (i = 0; i < iovcnt && left > 0; i++) { - if (iov[i].iov_len > left) - iov[i].iov_len = left; - memcpy(iov[i].iov_base, &buf[len], iov[i].iov_len); - len += iov[i].iov_len; - left -= iov[i].iov_len; - } - ring->head = ring->cur = nm_ring_next(ring, cur); - nmd->cur_rx_ring = r; - ioctl(nmd->fd, NIOCRXSYNC, NULL); - break; - } - for (; i < iovcnt; i++) - iov[i].iov_len = 0; - - return (len); -} - -/* - * Called to send a buffer chain out to the vale port - */ -static void -pci_vtnet_netmap_tx(struct pci_vtnet_softc *sc, struct iovec *iov, int iovcnt, - int len) -{ - static char pad[60]; /* all zero bytes */ - - if (sc->vsc_nmd == NULL) - return; - - /* - * If the length is < 60, pad out to that and add the - * extra zero'd segment to the iov. It is guaranteed that - * there is always an extra iov available by the caller. - */ - if (len < 60) { - iov[iovcnt].iov_base = pad; - iov[iovcnt].iov_len = 60 - len; - iovcnt++; - } - (void) pci_vtnet_netmap_writev(sc->vsc_nmd, iov, iovcnt); + iov[0].iov_base = dummybuf; + iov[0].iov_len = sizeof(dummybuf); + netbe_recv(sc->vsc_be, iov, 1, &more); } static void -pci_vtnet_netmap_rx(struct pci_vtnet_softc *sc) +pci_vtnet_rx(struct pci_vtnet_softc *sc) { - struct iovec iov[VTNET_MAXSEGS], *riov; + struct iovec iov[VTNET_MAXSEGS + 1]; struct vqueue_info *vq; - void *vrx; int len, n; uint16_t idx; + int more; /* - * Should never be called without a valid netmap descriptor - */ - assert(sc->vsc_nmd != NULL); - - /* - * But, will be called when the rx ring hasn't yet + * This will be called when the rx ring hasn't yet * been set up or the guest is resetting the device. */ if (!sc->vsc_rx_ready || sc->resetting) { /* * Drop the packet and try later. */ - (void) nm_nextpkt(sc->vsc_nmd, (void *)dummybuf); + pci_vtnet_rx_discard(sc, iov); return; } @@ -519,7 +246,7 @@ * Drop the packet and try later. Interrupt on * empty, if that's negotiated. */ - (void) nm_nextpkt(sc->vsc_nmd, (void *)dummybuf); + pci_vtnet_rx_discard(sc, iov); vq_endchains(vq, 1); return; } @@ -531,14 +258,7 @@ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); - /* - * Get a pointer to the rx header, and use the - * data immediately following it for the packet buffer. - */ - vrx = iov[0].iov_base; - riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen); - - len = pci_vtnet_netmap_readv(sc->vsc_nmd, riov, n); + len = netbe_recv(sc->vsc_be, iov, n, &more); if (len == 0) { /* @@ -551,19 +271,6 @@ } /* - * The only valid field in the rx packet header is the - * number of buffers if merged rx bufs were negotiated. - */ - memset(vrx, 0, sc->rx_vhdrlen); - - if (sc->rx_merge) { - struct virtio_net_rxhdr *vrxh; - - vrxh = vrx; - vrxh->vrh_bufs = 1; - } - - /* * Release this chain and handle more chains. */ vq_relchain(vq, idx, len + sc->rx_vhdrlen); @@ -579,7 +286,7 @@ struct pci_vtnet_softc *sc = param; pthread_mutex_lock(&sc->rx_mtx); - sc->pci_vtnet_rx(sc); + pci_vtnet_rx(sc); pthread_mutex_unlock(&sc->rx_mtx); } @@ -603,27 +310,24 @@ { struct iovec iov[VTNET_MAXSEGS + 1]; int i, n; - int plen, tlen; + int len; uint16_t idx; /* - * Obtain chain of descriptors. The first one is - * really the header descriptor, so we need to sum - * up two lengths: packet length and transfer length. + * Obtain chain of descriptors. The first descriptor also + * contains the virtio-net header. */ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); - tlen = 0; + len = 0; for (i = 0; i < n; i++) { - tlen += iov[i].iov_len; + len += iov[i].iov_len; } - plen = tlen - iov[0].iov_len; - DPRINTF(("virtio: packet send, %d bytes, %d segs\n\r", plen, n)); - sc->pci_vtnet_tx(sc, &iov[1], n - 1, plen); + netbe_send(sc->vsc_be, iov, n, len, 0 /* more */); - /* chain is processed, release it and set tlen */ - vq_relchain(vq, idx, tlen); + /* chain is processed, release it and set len */ + vq_relchain(vq, idx, len); } static void @@ -731,68 +435,6 @@ return (0); } -static void -pci_vtnet_tap_setup(struct pci_vtnet_softc *sc, char *devname) -{ - char tbuf[80]; - - strcpy(tbuf, "/dev/"); - strlcat(tbuf, devname, sizeof(tbuf)); - - sc->pci_vtnet_rx = pci_vtnet_tap_rx; - sc->pci_vtnet_tx = pci_vtnet_tap_tx; - - sc->vsc_tapfd = open(tbuf, O_RDWR); - if (sc->vsc_tapfd == -1) { - WPRINTF(("open of tap device %s failed\n", tbuf)); - return; - } - - /* - * Set non-blocking and register for read - * notifications with the event loop - */ - int opt = 1; - if (ioctl(sc->vsc_tapfd, FIONBIO, &opt) < 0) { - WPRINTF(("tap device O_NONBLOCK failed\n")); - close(sc->vsc_tapfd); - sc->vsc_tapfd = -1; - } - - sc->vsc_mevp = mevent_add(sc->vsc_tapfd, - EVF_READ, - pci_vtnet_rx_callback, - sc); - if (sc->vsc_mevp == NULL) { - WPRINTF(("Could not register event\n")); - close(sc->vsc_tapfd); - sc->vsc_tapfd = -1; - } -} - -static void -pci_vtnet_netmap_setup(struct pci_vtnet_softc *sc, char *ifname) -{ - sc->pci_vtnet_rx = pci_vtnet_netmap_rx; - sc->pci_vtnet_tx = pci_vtnet_netmap_tx; - - sc->vsc_nmd = nm_open(ifname, NULL, 0, 0); - if (sc->vsc_nmd == NULL) { - WPRINTF(("open of netmap device %s failed\n", ifname)); - return; - } - - sc->vsc_mevp = mevent_add(sc->vsc_nmd->fd, - EVF_READ, - pci_vtnet_rx_callback, - sc); - if (sc->vsc_mevp == NULL) { - WPRINTF(("Could not register event\n")); - nm_close(sc->vsc_nmd); - sc->vsc_nmd = NULL; - } -} - static int pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { @@ -804,12 +446,20 @@ char *devname; char *vtopts; int mac_provided; + struct virtio_consts *vc; - sc = calloc(1, sizeof(struct pci_vtnet_softc)); + /* sc also contains a copy of the vtnet_vi_consts, + * because the capabilities change depending on + * the backend. + */ + sc = calloc(1, sizeof(struct pci_vtnet_softc) + + sizeof(struct virtio_consts)); + vc = (struct virtio_consts *)(sc + 1); + memcpy(vc, &vtnet_vi_consts, sizeof(*vc)); pthread_mutex_init(&sc->vsc_mtx, NULL); - vi_softc_linkup(&sc->vsc_vs, &vtnet_vi_consts, sc, pi, sc->vsc_queues); + vi_softc_linkup(&sc->vsc_vs, vc, sc, pi, sc->vsc_queues); sc->vsc_vs.vs_mtx = &sc->vsc_mtx; sc->vsc_queues[VTNET_RXQ].vq_qsize = VTNET_RINGSZ; @@ -822,12 +472,10 @@ #endif /* - * Attempt to open the tap device and read the MAC address + * Attempt to open the backend device and read the MAC address * if specified */ mac_provided = 0; - sc->vsc_tapfd = -1; - sc->vsc_nmd = NULL; if (opts != NULL) { int err; @@ -843,11 +491,12 @@ mac_provided = 1; } - if (strncmp(devname, "vale", 4) == 0) - pci_vtnet_netmap_setup(sc, devname); - if (strncmp(devname, "tap", 3) == 0 || - strncmp(devname, "vmnet", 5) == 0) - pci_vtnet_tap_setup(sc, devname); + sc->vsc_be = netbe_init(devname, pci_vtnet_rx_callback, sc); + if (!sc->vsc_be) { + WPRINTF(("net backend initialization failed\n")); + } else { + vc->vc_hv_caps |= netbe_get_features(sc->vsc_be); + } free(devname); } @@ -879,9 +528,8 @@ pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_TYPE_NET); pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_VENDOR); - /* Link is up if we managed to open tap device or vale port. */ - sc->vsc_config.status = (opts == NULL || sc->vsc_tapfd >= 0 || - sc->vsc_nmd != NULL); + /* Link is up if we managed to open backend device. */ + sc->vsc_config.status = (opts == NULL || sc->vsc_be); /* use BAR 1 to map MSI-X table and PBA, if we're using MSI-X */ if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix())) @@ -951,11 +599,14 @@ sc->vsc_features = negotiated_features; - if (!(sc->vsc_features & VIRTIO_NET_F_MRG_RXBUF)) { + if (!(negotiated_features & VIRTIO_NET_F_MRG_RXBUF)) { sc->rx_merge = 0; /* non-merge rx header is 2 bytes shorter */ sc->rx_vhdrlen -= 2; } + + /* Tell the backend to enable some features it has advertised. */ + netbe_set_features(sc->vsc_be, negotiated_features, sc->rx_vhdrlen); } struct pci_devemu pci_de_vnet = { From owner-svn-soc-all@freebsd.org Fri Aug 5 13:51:57 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D6A94BAFD72 for ; Fri, 5 Aug 2016 13:51:57 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C99CA1A0A for ; Fri, 5 Aug 2016 13:51:57 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75DpvjG032266 for ; Fri, 5 Aug 2016 13:51:57 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75DpuLB032225 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:51:56 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:51:56 GMT Message-Id: <201608051351.u75DpuLB032225@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307217 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:51:57 -0000 Author: vincenzo Date: Fri Aug 5 13:51:56 2016 New Revision: 307217 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307217 Log: net: add net_backends missing files Added: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Added: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:51:56 2016 (r307217) @@ -0,0 +1,933 @@ +/*- + * Copyright (c) 2014-2015 Vincenzo Maffione + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include /* u_short etc */ +#include /* ETHER_ADDR_LEN */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mevent.h" +#include "net_backends.h" + +#include + +#define NETMAP_WITH_LIBS +#include +#if (NETMAP_API < 11) +#error "Netmap API version must be >= 11" +#endif + +/* + * The API for network backends. This might need to be exposed + * if we implement them in separate files. + */ +struct net_backend { + const char *name; /* name of the backend */ + /* + * The init and cleanup functions are used internally, + * virtio-net should never use it. + */ + int (*init)(struct net_backend *be, const char *devname, + net_backend_cb_t cb, void *param); + void (*cleanup)(struct net_backend *be); + + + /* + * Called to serve a guest transmit request. The scatter-gather + * vector provided by the caller has 'iovcnt' elements and contains + * the packet to send. 'len' is the length of whole packet in bytes. + */ + int (*send)(struct net_backend *be, struct iovec *iov, + int iovcnt, int len, int more); + + /* + * Called to serve guest receive request. When the function + * returns a positive value, the scatter-gather vector + * provided by the caller (having 'iovcnt' elements in it) will + * contain a chunk of the received packet. The 'more' flag will + * be set if the returned chunk was the last one for the current + * packet, and 0 otherwise. The function returns the chunk size + * in bytes, or 0 if the backend doesn't have a new packet to + * receive. + * Note that it may be necessary to call this callback many + * times to receive a single packet, depending of how big is + * buffers you provide. + */ + int (*recv)(struct net_backend *be, struct iovec *iov, + int iovcnt, int *more); + + /* + * Ask the backend for the virtio-net features it is able to + * support. Possible features are TSO, UFO and checksum offloading + * in both rx and tx direction and for both IPv4 and IPv6. + */ + uint64_t (*get_features)(struct net_backend *be); + + /* + * Tell the backend to enable/disable the specified virtio-net + * features. + */ + int (*set_features)(struct net_backend *be, uint64_t features, + unsigned int vnet_hdr_len); + + /* + * Get ptnetmap_state if the backend support ptnetmap + */ + struct ptnetmap_state * (*get_ptnetmap)(struct net_backend *be); + + struct pci_vtnet_softc *sc; + int fd; + unsigned int be_vnet_hdr_len; + unsigned int fe_vnet_hdr_len; + void *priv; /* Pointer to backend-specific data. */ +}; + +SET_DECLARE(net_backend_set, struct net_backend); + +#define WPRINTF(params) printf params + +/* the null backend */ +static int +netbe_null_init(struct net_backend *be, const char *devname, + net_backend_cb_t cb, void *param) +{ + D("initializing null backend"); + be->fd = -1; + return 0; +} + +static void +netbe_null_cleanup(struct net_backend *be) +{ + D(""); +} + +static uint64_t +netbe_null_get_features(struct net_backend *be) +{ + D(""); + return 0; +} + +static int +netbe_null_set_features(struct net_backend *be, uint64_t features, + unsigned vnet_hdr_len) +{ + D("setting 0x%lx", features); + return 0; +} + +static int +netbe_null_send(struct net_backend *be, struct iovec *iov, + int iovcnt, int len, int more) +{ + return 0; /* pretend we send */ +} + +static int +netbe_null_recv(struct net_backend *be, struct iovec *iov, + int iovcnt, int *more) +{ + fprintf(stderr, "netbe_null_recv called ?\n"); + return -1; /* never called, i believe */ +} + +static struct ptnetmap_state * +netbe_null_get_ptnetmap(struct net_backend *be) +{ + return NULL; +} + +static struct net_backend null_backend = { + .name = "null", + .init = netbe_null_init, + .cleanup = netbe_null_cleanup, + .send = netbe_null_send, + .recv = netbe_null_recv, + .get_features = netbe_null_get_features, + .set_features = netbe_null_set_features, + .get_ptnetmap = netbe_null_get_ptnetmap, +}; + +DATA_SET(net_backend_set, null_backend); + + +/* the tap backend */ + +struct tap_priv { + struct mevent *mevp; +}; + +static void +tap_cleanup(struct net_backend *be) +{ + struct tap_priv *priv = be->priv; + + if (be->priv) { + mevent_delete(priv->mevp); + free(be->priv); + be->priv = NULL; + } + if (be->fd != -1) { + close(be->fd); + be->fd = -1; + } +} + +static int +tap_init(struct net_backend *be, const char *devname, + net_backend_cb_t cb, void *param) +{ + char tbuf[80]; + int fd; + int opt = 1; + struct tap_priv *priv; + + priv = calloc(1, sizeof(struct tap_priv)); + if (priv == NULL) { + WPRINTF(("tap_priv alloc failed\n")); + return -1; + } + + strcpy(tbuf, "/dev/"); + strlcat(tbuf, devname, sizeof(tbuf)); + + fd = open(tbuf, O_RDWR); + if (fd == -1) { + WPRINTF(("open of tap device %s failed\n", tbuf)); + goto error; + } + + /* + * Set non-blocking and register for read + * notifications with the event loop + */ + if (ioctl(fd, FIONBIO, &opt) < 0) { + WPRINTF(("tap device O_NONBLOCK failed\n")); + goto error; + } + + priv->mevp = mevent_add(fd, EVF_READ, cb, param); + if (priv->mevp == NULL) { + WPRINTF(("Could not register event\n")); + goto error; + } + + be->fd = fd; + be->priv = priv; + + return 0; + +error: + tap_cleanup(be); + return -1; +} + +/* + * Called to send a buffer chain out to the tap device + */ +static int +tap_send(struct net_backend *be, struct iovec *iov, int iovcnt, int len, + int more) +{ + static char pad[60]; /* all zero bytes */ + + /* + * If the length is < 60, pad out to that and add the + * extra zero'd segment to the iov. It is guaranteed that + * there is always an extra iov available by the caller. + */ + if (len < 60) { + iov[iovcnt].iov_base = pad; + iov[iovcnt].iov_len = 60 - len; + iovcnt++; + } + + return writev(be->fd, iov, iovcnt); +} + +static int +tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more) +{ + int ret; + + /* Should never be called without a valid tap fd */ + assert(be->fd != -1); + *more = 0; + + ret = readv(be->fd, iov, iovcnt); + + if (ret < 0 && errno == EWOULDBLOCK) { + return 0; + } + + return ret; +} + +static uint64_t +tap_get_features(struct net_backend *be) +{ + return 0; // nothing extra +} + +static int +tap_set_features(struct net_backend *be, uint64_t features, + unsigned vnet_hdr_len) +{ + return 0; /* success */ +} + +static struct net_backend tap_backend = { + .name = "tap|vmmnet", + .init = tap_init, + .cleanup = tap_cleanup, + .send = tap_send, + .recv = tap_recv, + .get_features = tap_get_features, + .set_features = tap_set_features, +}; + +DATA_SET(net_backend_set, tap_backend); + + +/* + * The netmap backend + */ + +/* The virtio-net features supported by netmap. */ +#define NETMAP_FEATURES (VIRTIO_NET_F_CSUM | VIRTIO_NET_F_HOST_TSO4 | \ + VIRTIO_NET_F_HOST_TSO6 | VIRTIO_NET_F_HOST_UFO | \ + VIRTIO_NET_F_GUEST_CSUM | VIRTIO_NET_F_GUEST_TSO4 | \ + VIRTIO_NET_F_GUEST_TSO6 | VIRTIO_NET_F_GUEST_UFO) + +#define NETMAP_POLLMASK (POLLIN | POLLRDNORM | POLLRDBAND) + +struct netmap_priv { + char ifname[IFNAMSIZ]; + struct nm_desc *nmd; + struct netmap_ring *rx; + struct netmap_ring *tx; + pthread_t evloop_tid; + net_backend_cb_t cb; + void *cb_param; + + /* Support for splitted receives. */ + int rx_continue; + int rx_idx; + uint8_t *rx_buf; + int rx_avail; + int rx_morefrag; + int rx_avail_slots; +}; + +static void * +netmap_evloop_thread(void *param) +{ + struct net_backend *be = param; + struct netmap_priv *priv = be->priv; + struct pollfd pfd; + int ret; + + for (;;) { + pfd.fd = be->fd; + pfd.events = NETMAP_POLLMASK; + ret = poll(&pfd, 1, INFTIM); + if (ret == -1 && errno != EINTR) { + WPRINTF(("netmap poll failed, %d\n", errno)); + } else if (ret == 1 && (pfd.revents & NETMAP_POLLMASK)) { + priv->cb(pfd.fd, EVF_READ, priv->cb_param); + } + } + + return NULL; +} + +static int +netmap_set_vnet_hdr_len(struct net_backend *be, int vnet_hdr_len) +{ + int err; + struct nmreq req; + struct netmap_priv *priv = be->priv; + + memset(&req, 0, sizeof(req)); + strcpy(req.nr_name, priv->ifname); + req.nr_version = NETMAP_API; + req.nr_cmd = NETMAP_BDG_VNET_HDR; + req.nr_arg1 = vnet_hdr_len; + err = ioctl(be->fd, NIOCREGIF, &req); + if (err) { + WPRINTF(("Unable to set vnet header length %d\n", + vnet_hdr_len)); + return err; + } + + be->be_vnet_hdr_len = vnet_hdr_len; + + return 0; +} + +static uint64_t +netmap_get_features(struct net_backend *be) +{ + return NETMAP_FEATURES; +} + +static int +netmap_set_features(struct net_backend *be, uint64_t features, + unsigned vnet_hdr_len) +{ + return netmap_set_vnet_hdr_len(be, vnet_hdr_len); +} + +/* used by netmap and ptnetmap during the initialization */ +static int +netmap_common_init(struct net_backend *be, struct netmap_priv *priv, + uint32_t nr_flags, const char *devname, + net_backend_cb_t cb, void *param) +{ + const char *ndname = "/dev/netmap"; + struct nmreq req; + char tname[40]; + + strncpy(priv->ifname, devname, sizeof(priv->ifname)); + priv->ifname[sizeof(priv->ifname) - 1] = '\0'; + + memset(&req, 0, sizeof(req)); + req.nr_flags = nr_flags; + + priv->nmd = nm_open(priv->ifname, &req, NETMAP_NO_TX_POLL, NULL); + if (priv->nmd == NULL) { + WPRINTF(("Unable to nm_open(): device '%s', " + "interface '%s', errno (%s)\n", + ndname, devname, strerror(errno))); + goto err_open; + } + + priv->tx = NETMAP_TXRING(priv->nmd->nifp, 0); + priv->rx = NETMAP_RXRING(priv->nmd->nifp, 0); + + priv->cb = cb; + priv->cb_param = param; + priv->rx_continue = 0; + + be->fd = priv->nmd->fd; + + /* Create a thread for netmap poll. */ + pthread_create(&priv->evloop_tid, NULL, netmap_evloop_thread, (void *)be); + snprintf(tname, sizeof(tname), "netmap-evloop-%p", priv); + pthread_set_name_np(priv->evloop_tid, tname); + + return 0; + +err_open: + return -1; +} + +static int +netmap_init(struct net_backend *be, const char *devname, + net_backend_cb_t cb, void *param) +{ + struct netmap_priv *priv = NULL; + + priv = calloc(1, sizeof(struct netmap_priv)); + if (priv == NULL) { + WPRINTF(("Unable alloc netmap private data\n")); + return -1; + } + + if (netmap_common_init(be, priv, 0, devname, cb, param)) { + goto err; + } + + be->priv = priv; + + return 0; + +err: + free(priv); + + return -1; +} + +static void +netmap_cleanup(struct net_backend *be) +{ + struct netmap_priv *priv = be->priv; + + if (be->priv) { + nm_close(priv->nmd); + free(be->priv); + be->priv = NULL; + } + be->fd = -1; +} + +/* A fast copy routine only for multiples of 64 bytes, non overlapped. */ +static inline void +pkt_copy(const void *_src, void *_dst, int l) +{ + const uint64_t *src = _src; + uint64_t *dst = _dst; + if (l >= 1024) { + bcopy(src, dst, l); + return; + } + for (; l > 0; l -= 64) { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + } +} + +static int +netmap_send(struct net_backend *be, struct iovec *iov, + int iovcnt, int size, int more) +{ + struct netmap_priv *priv = be->priv; + struct netmap_ring *ring; + uint32_t last; + uint32_t idx; + uint8_t *dst; + int j; + uint32_t i; + + if (iovcnt <= 0) + goto txsync; + + ring = priv->tx; + last = i = ring->cur; + + if (nm_ring_space(ring) < iovcnt) { + static int c; + c++; + RD(5, "no space, txsync %d", c); + /* Not enough netmap slots. */ + goto txsync; + } + + for (j = 0; j < iovcnt; j++) { + int iov_frag_size = iov[j].iov_len; + int offset = 0; + int nm_frag_size; + + /* Split each iovec fragment over more netmap slots, if + necessary (without performing data copy). */ + while (iov_frag_size) { + nm_frag_size = iov_frag_size; + if (nm_frag_size > ring->nr_buf_size) { + nm_frag_size = ring->nr_buf_size; + } + + if (nm_ring_empty(ring)) { + /* We run out of netmap slots while splitting the + iovec fragments. */ + goto txsync; + } + + idx = ring->slot[i].buf_idx; + dst = (uint8_t *)NETMAP_BUF(ring, idx); + + ring->slot[i].len = nm_frag_size; +// #define USE_INDIRECT_BUFFERS +#ifdef USE_INDIRECT_BUFFERS + ring->slot[i].flags = NS_MOREFRAG | NS_INDIRECT; + ring->slot[i].ptr = (uintptr_t)(iov[j].iov_base + offset); +#else /* !USE_INDIRECT_BUFFERS */ + ring->slot[i].flags = NS_MOREFRAG; + pkt_copy(iov[j].iov_base + offset, dst, nm_frag_size); +#endif /* !USING_INDIRECT_BUFFERS */ + + last = i; + i = nm_ring_next(ring, i); + + offset += nm_frag_size; + iov_frag_size -= nm_frag_size; + } + } + /* The last slot must not have NS_MOREFRAG set. */ + ring->slot[last].flags &= ~NS_MOREFRAG; + + /* Now update ring->cur and ring->avail. */ + ring->cur = ring->head = i; + +txsync: + if (!more) {// || nm_ring_space(ring) < 64) { + // IFRATE(vq->vq_vs->rate.cur.var2[vq->vq_num]++); + // netmap_ioctl_counter++; + ioctl(be->fd, NIOCTXSYNC, NULL); + } + + return 0; +} + +static int +netmap_recv(struct net_backend *be, struct iovec *iov, + int iovcnt, int *more) +{ + struct netmap_priv *priv = be->priv; + struct netmap_ring *ring; + int tot = 0; + int copylen; + int iov_avail; + uint8_t *iov_buf; + + assert(iovcnt); + + ring = priv->rx; + + /* Init iovec pointers. */ + iov_buf = iov->iov_base; + iov_avail = iov->iov_len; + + if (!priv->rx_continue) { + /* Init netmap pointers. */ + priv->rx_idx = ring->cur; + priv->rx_avail_slots = nm_ring_space(ring); + priv->rx_buf = NETMAP_BUF(ring, + ring->slot[priv->rx_idx].buf_idx); + priv->rx_avail = ring->slot[priv->rx_idx].len; + priv->rx_morefrag = (ring->slot[priv->rx_idx].flags + & NS_MOREFRAG); + + if (!priv->rx_avail_slots) { + goto out; + } + priv->rx_continue = 1; + } + + for (;;) { + copylen = priv->rx_avail; + if (copylen > iov_avail) { + copylen = iov_avail; + } + + /* Copy and update pointers. */ + bcopy(priv->rx_buf, iov_buf, copylen); + iov_buf += copylen; + iov_avail -= copylen; + priv->rx_buf += copylen; + priv->rx_avail -= copylen; + tot += copylen; + + if (!priv->rx_avail) { + priv->rx_avail_slots--; + if (!priv->rx_morefrag || !priv->rx_avail_slots) { + priv->rx_continue = 0; + break; + } + /* Go to the next netmap slot. */ + priv->rx_idx = nm_ring_next(ring, priv->rx_idx); + priv->rx_buf = NETMAP_BUF(ring, + ring->slot[priv->rx_idx].buf_idx); + priv->rx_avail = ring->slot[priv->rx_idx].len; + priv->rx_morefrag = + (ring->slot[priv->rx_idx].flags + & NS_MOREFRAG); + } + + if (!iov_avail) { + iovcnt--; + if (!iovcnt) { + break; + } + /* Go to the next iovec descriptor. */ + iov++; + iov_buf = iov->iov_base; + iov_avail = iov->iov_len; + } + } + + if (!priv->rx_continue) { + /* End of reception: Update the ring now. */ + ring->cur = ring->head = nm_ring_next(ring, priv->rx_idx); + } +out: + *more = priv->rx_continue; + + return tot; +} + +static struct net_backend netmap_backend = { + .name = "netmap|vale", + .init = netmap_init, + .cleanup = netmap_cleanup, + .send = netmap_send, + .recv = netmap_recv, + .get_features = netmap_get_features, + .set_features = netmap_set_features, +}; + +DATA_SET(net_backend_set, netmap_backend); + +/* + * make sure a backend is properly initialized + */ +static void +netbe_fix(struct net_backend *be) +{ + if (be == NULL) + return; + if (be->name == NULL) { + fprintf(stderr, "missing name for %p\n", be); + be->name = "unnamed netbe"; + } + if (be->init == NULL) { + fprintf(stderr, "missing init for %p %s\n", be, be->name); + be->init = netbe_null_init; + } + if (be->cleanup == NULL) { + fprintf(stderr, "missing cleanup for %p %s\n", be, be->name); + be->cleanup = netbe_null_cleanup; + } + if (be->send == NULL) { + fprintf(stderr, "missing send for %p %s\n", be, be->name); + be->send = netbe_null_send; + } + if (be->recv == NULL) { + fprintf(stderr, "missing recv for %p %s\n", be, be->name); + be->recv = netbe_null_recv; + } + if (be->get_features == NULL) { + fprintf(stderr, "missing get_features for %p %s\n", + be, be->name); + be->get_features = netbe_null_get_features; + } + if (be->set_features == NULL) { + fprintf(stderr, "missing set_features for %p %s\n", + be, be->name); + be->set_features = netbe_null_set_features; + } + if (be->get_ptnetmap == NULL) { + /*fprintf(stderr, "missing set_features for %p %s\n", + be, be->name);*/ + be->get_ptnetmap = netbe_null_get_ptnetmap; + } +} + +/* + * keys is a set of prefixes separated by '|', + * return 1 if the leftmost part of name matches one prefix. + */ +static const char * +netbe_name_match(const char *keys, const char *name) +{ + const char *n = name, *good = keys; + char c; + + if (!keys || !name) + return NULL; + while ( (c = *keys++) ) { + if (c == '|') { /* reached the separator */ + if (good) + break; + /* prepare for new round */ + n = name; + good = keys; + } else if (good && c != *n++) { + good = NULL; /* drop till next keyword */ + } + } + return good; +} + +struct net_backend * +netbe_init(const char *devname, net_backend_cb_t cb, void *param) +{ + /* + * Choose the network backend depending on the user + * provided device name. + */ + struct net_backend **pbe, *ret, *be = NULL; + int err; + + SET_FOREACH(pbe, net_backend_set) { + netbe_fix(*pbe); /* make sure we have all fields */ + if (netbe_name_match((*pbe)->name, devname)) { + be = *pbe; + break; + } + } + if (be == NULL) + return NULL; /* or null backend ? */ + ret = calloc(1, sizeof(*ret)); + *ret = *be; + ret->fd = -1; + ret->priv = NULL; + ret->sc = param; + ret->be_vnet_hdr_len = 0; + ret->fe_vnet_hdr_len = 0; + + err = be->init(ret, devname, cb, param); + if (err) { + free(ret); + ret = NULL; + } + return ret; +} + +void +netbe_cleanup(struct net_backend *be) +{ + if (be == NULL) + return; + be->cleanup(be); + free(be); +} + +uint64_t +netbe_get_features(struct net_backend *be) +{ + if (be == NULL) + return 0; + return be->get_features(be); +} + +int +netbe_set_features(struct net_backend *be, uint64_t features, + unsigned vnet_hdr_len) +{ + int ret; + + if (be == NULL) + return 0; + + /* There are only three valid lengths. */ + if (vnet_hdr_len && vnet_hdr_len != sizeof(struct virtio_net_rxhdr) + && vnet_hdr_len != (sizeof(struct virtio_net_rxhdr) - + sizeof(uint16_t))) + return -1; + + be->fe_vnet_hdr_len = vnet_hdr_len; + + ret = be->set_features(be, features, vnet_hdr_len); + assert(be->be_vnet_hdr_len == 0 || + be->be_vnet_hdr_len == be->fe_vnet_hdr_len); + + return ret; +} + +static __inline struct iovec * +iov_trim(struct iovec *iov, int *iovcnt, int tlen) +{ + struct iovec *riov; + + /* XXX short-cut: assume first segment is >= tlen */ + assert(iov[0].iov_len >= tlen); + + iov[0].iov_len -= tlen; + if (iov[0].iov_len == 0) { + assert(*iovcnt > 1); + *iovcnt -= 1; + riov = &iov[1]; + } else { + iov[0].iov_base = (void *)((uintptr_t)iov[0].iov_base + tlen); + riov = &iov[0]; + } + + return (riov); +} + +void +netbe_send(struct net_backend *be, struct iovec *iov, int iovcnt, int len, + int more) +{ + if (be == NULL) + return; +#if 0 + int i; + D("sending iovcnt %d len %d iovec %p", iovcnt, len, iov); + for (i=0; i < iovcnt; i++) + D(" %3d: %4d %p", i, (int)iov[i].iov_len, iov[i].iov_base); +#endif + if (be->be_vnet_hdr_len != be->fe_vnet_hdr_len) { + /* Here we are sure be->be_vnet_hdr_len is 0. */ + iov = iov_trim(iov, &iovcnt, be->fe_vnet_hdr_len); + } + + be->send(be, iov, iovcnt, len, more); +} + +int +netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more) +{ + int hlen = 0; + int ret; + + if (be == NULL) + return -1; + + if (be->be_vnet_hdr_len != be->fe_vnet_hdr_len) { + struct virtio_net_rxhdr *vh; + + /* Here we are sure be->be_vnet_hdr_len is 0. */ + hlen = be->fe_vnet_hdr_len; + /* + * Get a pointer to the rx header, and use the + * data immediately following it for the packet buffer. + */ + vh = iov[0].iov_base; + iov = iov_trim(iov, &iovcnt, hlen); + + /* + * Here we are sure be->fe_vnet_hdr_len is 0. + * The only valid field in the rx packet header is the + * number of buffers if merged rx bufs were negotiated. + */ + memset(vh, 0, hlen); + + if (hlen == sizeof(struct virtio_net_rxhdr)) { + vh->vrh_bufs = 1; + } + } + + ret = be->recv(be, iov, iovcnt, more); + if (ret > 0) { + ret += hlen; + } + + return ret; +} Added: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:51:56 2016 (r307217) @@ -0,0 +1,87 @@ +/*- + * Copyright (c) 2014 Vincenzo Maffione + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __NET_BACKENDS_H__ +#define __NET_BACKENDS_H__ + +#include + +extern int netmap_ioctl_counter; + +typedef void (*net_backend_cb_t)(int, enum ev_type, void *param); + +/* Interface between virtio-net and the network backend. */ +struct net_backend; + +struct net_backend *netbe_init(const char *devname, + net_backend_cb_t cb, void *param); +void netbe_cleanup(struct net_backend *be); +uint64_t netbe_get_features(struct net_backend *be); +int netbe_set_features(struct net_backend *be, uint64_t features, + unsigned vnet_hdr_len); +void netbe_send(struct net_backend *be, struct iovec *iov, + int iovcnt, int len, int more); +int netbe_recv(struct net_backend *be, struct iovec *iov, + int iovcnt, int *more); + + +/* + * VirtIO network device capabilities. Note that we only offer a few of these. + */ +#define VIRTIO_NET_F_CSUM (1 << 0) /* host handles partial cksum */ +#define VIRTIO_NET_F_GUEST_CSUM (1 << 1) /* guest handles partial cksum */ +#define VIRTIO_NET_F_MAC (1 << 5) /* host supplies MAC */ +#define VIRTIO_NET_F_GSO_DEPREC (1 << 6) /* deprecated: host handles GSO */ +#define VIRTIO_NET_F_GUEST_TSO4 (1 << 7) /* guest can rcv TSOv4 */ +#define VIRTIO_NET_F_GUEST_TSO6 (1 << 8) /* guest can rcv TSOv6 */ +#define VIRTIO_NET_F_GUEST_ECN (1 << 9) /* guest can rcv TSO with ECN */ +#define VIRTIO_NET_F_GUEST_UFO (1 << 10) /* guest can rcv UFO */ *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@freebsd.org Fri Aug 5 13:53:36 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C4973BAFDE1 for ; Fri, 5 Aug 2016 13:53:36 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A45671CE3 for ; Fri, 5 Aug 2016 13:53:36 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75Drat3036187 for ; Fri, 5 Aug 2016 13:53:36 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75DrZQF036169 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:53:35 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:53:35 GMT Message-Id: <201608051353.u75DrZQF036169@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307218 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:53:36 -0000 Author: vincenzo Date: Fri Aug 5 13:53:35 2016 New Revision: 307218 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307218 Log: add support for ptnetmap PCI device Added: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 13:51:56 2016 (r307217) +++ soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 13:53:35 2016 (r307218) @@ -32,6 +32,7 @@ pci_irq.c \ pci_lpc.c \ pci_passthru.c \ + pci_ptnetmap_memdev.c \ pci_virtio_block.c \ pci_virtio_net.c \ pci_virtio_rnd.c \ Added: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c Fri Aug 5 13:53:35 2016 (r307218) @@ -0,0 +1,319 @@ +/* + * Copyright (C) 2015 Stefano Garzarella (stefano.garzarella@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include /* IFNAMSIZ */ +#include +#include + +#include +#include + +#include "bhyverun.h" +#include "pci_emul.h" + +/* + * ptnetmap memdev PCI device + * + * This device is used to map a netmap memory allocator on the guest VM + * through PCI_BAR. The same allocator can be shared between multiple ptnetmap + * ports in the guest. + * + * Each netmap allocator has a unique ID assigned by the netmap host module. + * + * The implementation here is based on the QEMU/KVM one. + */ +struct ptn_memdev_softc { + struct pci_devinst *pi; /* PCI device instance */ + + void *mem_ptr; /* netmap shared memory */ + uint64_t mem_size; /* netmap shared memory size */ + uint16_t mem_id; /* netmap memory allocator ID */ + + TAILQ_ENTRY(ptn_memdev_softc) next; +}; +static TAILQ_HEAD(, ptn_memdev_softc) ptn_memdevs = TAILQ_HEAD_INITIALIZER(ptn_memdevs); + +/* + * ptn_memdev_softc can be created by pe_init or ptnetmap backend, + * this depends on the order of initialization. + */ +static struct ptn_memdev_softc * +ptn_memdev_create() +{ + struct ptn_memdev_softc *sc; + + sc = calloc(1, sizeof(struct ptn_memdev_softc)); + if (sc != NULL) { + TAILQ_INSERT_TAIL(&ptn_memdevs, sc, next); + } + + return sc; +} + +static void +ptn_memdev_delete(struct ptn_memdev_softc *sc) +{ + TAILQ_REMOVE(&ptn_memdevs, sc, next); + + free(sc); +} + +/* + * Find ptn_memdev through mem_id (netmap memory allocator ID) + */ +static struct ptn_memdev_softc * +ptn_memdev_find_memid(uint16_t mem_id) +{ + struct ptn_memdev_softc *sc; + + TAILQ_FOREACH(sc, &ptn_memdevs, next) { + if (sc->mem_ptr != NULL && mem_id == sc->mem_id) { + return sc; + } + } + + return NULL; +} + +/* + * Find ptn_memdev that has not netmap memory (attached by ptnetmap backend) + */ +static struct ptn_memdev_softc * +ptn_memdev_find_empty_mem() +{ + struct ptn_memdev_softc *sc; + + TAILQ_FOREACH(sc, &ptn_memdevs, next) { + if (sc->mem_ptr == NULL) { + return sc; + } + } + + return NULL; +} + +/* + * Find ptn_memdev that has not PCI device istance (created by pe_init) + */ +static struct ptn_memdev_softc * +ptn_memdev_find_empty_pi() +{ + struct ptn_memdev_softc *sc; + + TAILQ_FOREACH(sc, &ptn_memdevs, next) { + if (sc->pi == NULL) { + return sc; + } + } + + return NULL; +} + +/* + * Handle read on ptnetmap-memdev register + */ +static uint64_t +ptn_pci_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + struct ptn_memdev_softc *sc = pi->pi_arg; + + if (sc == NULL) + return 0; + + if (baridx == PTNETMAP_IO_PCI_BAR) { + switch (offset) { + case PTNETMAP_IO_PCI_MEMSIZE: + return sc->mem_size; + case PTNETMAP_IO_PCI_HOSTID: + return sc->mem_id; + } + } + + printf("%s: Unexpected register read [bar %u, offset %lx size %d]\n", + __func__, baridx, offset, size); + + return 0; +} + +/* + * Handle write on ptnetmap-memdev register (unused for now) + */ +static void +ptn_pci_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct ptn_memdev_softc *sc = pi->pi_arg; + + if (sc == NULL) + return; + + printf("%s: Unexpected register write [bar %u, offset %lx size %d " + "value %lx]\n", __func__, baridx, offset, size, value); +} + +/* + * Configure the ptnetmap-memdev PCI BARs. PCI BARs can only be created + * when the PCI device is created and the netmap memory is attached. + */ +static int +ptn_memdev_configure_bars(struct ptn_memdev_softc *sc) +{ + int ret; + + if (sc->pi == NULL || sc->mem_ptr == NULL) + return 0; + + /* Allocate a BAR for an I/O region. */ + ret = pci_emul_alloc_bar(sc->pi, PTNETMAP_IO_PCI_BAR, PCIBAR_IO, + PTNETMAP_IO_SIZE); + if (ret) { + printf("ptnetmap_memdev: iobar allocation error %d\n", ret); + return ret; + } + + /* Allocate a BAR for a memory region. */ + ret = pci_emul_alloc_bar(sc->pi, PTNETMAP_MEM_PCI_BAR, PCIBAR_MEM32, + sc->mem_size); + if (ret) { + printf("ptnetmap_memdev: membar allocation error %d\n", ret); + return ret; + } + + /* Map netmap memory on the memory BAR. */ + ret = vm_map_user_buf(sc->pi->pi_vmctx, + sc->pi->pi_bar[PTNETMAP_MEM_PCI_BAR].addr, + sc->mem_size, sc->mem_ptr); + if (ret) { + printf("ptnetmap_memdev: membar map error %d\n", ret); + return ret; + } + + return 0; +} + +/* + * PCI device initialization + */ +static int +ptn_memdev_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct ptn_memdev_softc *sc; + int ret; + + sc = ptn_memdev_find_empty_pi(); + if (sc == NULL) { + sc = ptn_memdev_create(); + if (sc == NULL) { + printf("ptnetmap_memdev: calloc error\n"); + return (ENOMEM); + } + } + + /* Link our softc in the pci_devinst. */ + pi->pi_arg = sc; + sc->pi = pi; + + /* Initialize PCI configuration space. */ + pci_set_cfgdata16(pi, PCIR_VENDOR, PTNETMAP_PCI_VENDOR_ID); + pci_set_cfgdata16(pi, PCIR_DEVICE, PTNETMAP_PCI_DEVICE_ID); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, 1); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, PTNETMAP_PCI_VENDOR_ID); + + /* Configure PCI-BARs. */ + ret = ptn_memdev_configure_bars(sc); + if (ret) { + printf("ptnetmap_memdev: configure error\n"); + goto err; + } + + return 0; +err: + ptn_memdev_delete(sc); + pi->pi_arg = NULL; + return ret; +} + +/* + * used by ptnetmap backend to attach the netmap memory allocator to the + * ptnetmap-memdev. (shared with the guest VM through PCI-BAR) + */ +int +ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id) +{ + struct ptn_memdev_softc *sc; + int ret; + + /* if a device with the same mem_id is already attached, we are done */ + if (ptn_memdev_find_memid(mem_id)) { + printf("ptnetmap_memdev: already attched\n"); + return 0; + } + + sc = ptn_memdev_find_empty_mem(); + if (sc == NULL) { + sc = ptn_memdev_create(); + if (sc == NULL) { + printf("ptnetmap_memdev: calloc error\n"); + return (ENOMEM); + } + } + + sc->mem_ptr = mem_ptr; + sc->mem_size = mem_size; + sc->mem_id = mem_id; + + /* configure device PCI-BARs */ + ret = ptn_memdev_configure_bars(sc); + if (ret) { + printf("ptnetmap_memdev: configure error\n"); + goto err; + } + + + return 0; +err: + ptn_memdev_delete(sc); + sc->pi->pi_arg = NULL; + return ret; +} + +struct pci_devemu pci_de_ptnetmap = { + .pe_emu = PTN_MEMDEV_NAME, + .pe_init = ptn_memdev_init, + .pe_barwrite = ptn_pci_write, + .pe_barread = ptn_pci_read +}; +PCI_EMUL_SET(pci_de_ptnetmap); From owner-svn-soc-all@freebsd.org Fri Aug 5 13:54:57 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6CEB7BAFE8A for ; Fri, 5 Aug 2016 13:54:57 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 536B21E4D for ; Fri, 5 Aug 2016 13:54:57 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75Dsv82037850 for ; Fri, 5 Aug 2016 13:54:57 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75Dsuw1037808 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:54:56 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:54:56 GMT Message-Id: <201608051354.u75Dsuw1037808@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307219 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:54:57 -0000 Author: vincenzo Date: Fri Aug 5 13:54:55 2016 New Revision: 307219 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307219 Log: ptnetmap: add backend-side support Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:53:35 2016 (r307218) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:54:55 2016 (r307219) @@ -55,6 +55,7 @@ #if (NETMAP_API < 11) #error "Netmap API version must be >= 11" #endif +#include /* * The API for network backends. This might need to be exposed @@ -109,11 +110,6 @@ int (*set_features)(struct net_backend *be, uint64_t features, unsigned int vnet_hdr_len); - /* - * Get ptnetmap_state if the backend support ptnetmap - */ - struct ptnetmap_state * (*get_ptnetmap)(struct net_backend *be); - struct pci_vtnet_softc *sc; int fd; unsigned int be_vnet_hdr_len; @@ -171,12 +167,6 @@ return -1; /* never called, i believe */ } -static struct ptnetmap_state * -netbe_null_get_ptnetmap(struct net_backend *be) -{ - return NULL; -} - static struct net_backend null_backend = { .name = "null", .init = netbe_null_init, @@ -185,7 +175,6 @@ .recv = netbe_null_recv, .get_features = netbe_null_get_features, .set_features = netbe_null_set_features, - .get_ptnetmap = netbe_null_get_ptnetmap, }; DATA_SET(net_backend_set, null_backend); @@ -341,6 +330,8 @@ #define NETMAP_POLLMASK (POLLIN | POLLRDNORM | POLLRDBAND) +#define VNET_HDR_LEN sizeof(struct virtio_net_rxhdr) + struct netmap_priv { char ifname[IFNAMSIZ]; struct nm_desc *nmd; @@ -357,6 +348,8 @@ int rx_avail; int rx_morefrag; int rx_avail_slots; + + struct ptnetmap_state ptnetmap; }; static void * @@ -405,10 +398,31 @@ return 0; } +static int +netmap_has_vnet_hdr_len(struct net_backend *be, unsigned vnet_hdr_len) +{ + int prev_hdr_len = be->be_vnet_hdr_len; + int ret; + + if (vnet_hdr_len == prev_hdr_len) { + return 1; + } + + ret = netmap_set_vnet_hdr_len(be, vnet_hdr_len); + if (ret) { + return 0; + } + + netmap_set_vnet_hdr_len(be, prev_hdr_len); + + return 1; +} + static uint64_t netmap_get_features(struct net_backend *be) { - return NETMAP_FEATURES; + return netmap_has_vnet_hdr_len(be, VNET_HDR_LEN) ? + NETMAP_FEATURES : 0; } static int @@ -418,7 +432,125 @@ return netmap_set_vnet_hdr_len(be, vnet_hdr_len); } -/* used by netmap and ptnetmap during the initialization */ +/* Store and return the features we agreed upon. */ +uint32_t +ptnetmap_ack_features(struct ptnetmap_state *ptn, uint32_t wanted_features) +{ + ptn->acked_features = ptn->features & wanted_features; + + return ptn->acked_features; +} + +struct ptnetmap_state * +get_ptnetmap(struct net_backend *be) +{ + struct netmap_priv *priv = be->priv; + + /* Check that this is a netmap backend. */ + if (be->set_features != netmap_set_features) { + return NULL; + } + + return &priv->ptnetmap; +} + +int +ptnetmap_get_netmap_if(struct ptnetmap_state *ptn, struct netmap_if_info *nif) +{ + struct netmap_priv *priv = ptn->netmap_priv; + + memset(nif, 0, sizeof(*nif)); + if (priv->nmd == NULL) { + return EINVAL; + } + + nif->nifp_offset = priv->nmd->req.nr_offset; + nif->num_tx_rings = priv->nmd->req.nr_tx_rings; + nif->num_rx_rings = priv->nmd->req.nr_rx_rings; + nif->num_tx_slots = priv->nmd->req.nr_tx_slots; + nif->num_rx_slots = priv->nmd->req.nr_rx_slots; + + return 0; +} + +int +ptnetmap_get_host_memid(struct ptnetmap_state *ptn) +{ + struct netmap_priv *priv = ptn->netmap_priv; + + if (priv->nmd == NULL) { + return EINVAL; + } + + return priv->nmd->req.nr_arg2; +} + +int +ptnetmap_create(struct ptnetmap_state *ptn, struct ptnetmap_cfg *cfg) +{ + struct netmap_priv *priv = ptn->netmap_priv; + struct nmreq req; + int err; + + if (!(ptn->acked_features & NET_PTN_FEATURES_BASE)) { + fprintf(stderr, "%s: ptnetmap features not acked\n", + __func__); + return EINVAL; + } + + if (ptn->running) { + return 0; + } + + /* XXX We should stop the netmap evloop here. */ + + /* Ask netmap to create kthreads for this interface. */ + memset(&req, 0, sizeof(req)); + strncpy(req.nr_name, priv->ifname, sizeof(req.nr_name)); + req.nr_version = NETMAP_API; + ptnetmap_write_cfg(&req, cfg); + req.nr_cmd = NETMAP_PT_HOST_CREATE; + err = ioctl(priv->nmd->fd, NIOCREGIF, &req); + if (err) { + fprintf(stderr, "%s: Unable to create ptnetmap kthreads on " + "%s [errno=%d]", __func__, priv->ifname, errno); + return err; + } + + ptn->running = 1; + + return 0; +} + +int +ptnetmap_delete(struct ptnetmap_state *ptn) +{ + struct netmap_priv *priv = ptn->netmap_priv; + struct nmreq req; + int err; + + if (!ptn->running) { + return 0; + } + + /* Ask netmap to delete kthreads for this interface. */ + memset(&req, 0, sizeof(req)); + strncpy(req.nr_name, priv->ifname, sizeof(req.nr_name)); + req.nr_version = NETMAP_API; + req.nr_cmd = NETMAP_PT_HOST_DELETE; + err = ioctl(priv->nmd->fd, NIOCREGIF, &req); + if (err) { + fprintf(stderr, "%s: Unable to create ptnetmap kthreads on " + "%s [errno=%d]", __func__, priv->ifname, errno); + return err; + } + + ptn->running = 0; + + return 0; +} + +/* Used by netmap at initialization time. */ static int netmap_common_init(struct net_backend *be, struct netmap_priv *priv, uint32_t nr_flags, const char *devname, @@ -467,6 +599,7 @@ net_backend_cb_t cb, void *param) { struct netmap_priv *priv = NULL; + int ptnetmap = 0; priv = calloc(1, sizeof(struct netmap_priv)); if (priv == NULL) { @@ -474,10 +607,24 @@ return -1; } - if (netmap_common_init(be, priv, 0, devname, cb, param)) { + if (netmap_common_init(be, priv, ptnetmap ? NR_PTNETMAP_HOST : 0, + devname, cb, param)) { goto err; } + if (ptnetmap) { + priv->ptnetmap.netmap_priv = priv; + priv->ptnetmap.features = NET_PTN_FEATURES_BASE; + priv->ptnetmap.acked_features = 0; + priv->ptnetmap.running = 0; + if (netmap_has_vnet_hdr_len(be, VNET_HDR_LEN)) { + priv->ptnetmap.features |= NET_PTN_FEATURES_VNET_HDR; + } + /* XXX Call ptn_memdev_attach() here or in get_ptnetmap ? */ + ptn_memdev_attach(priv->nmd->mem, priv->nmd->memsize, + priv->nmd->req.nr_arg2); + } + be->priv = priv; return 0; @@ -494,6 +641,9 @@ struct netmap_priv *priv = be->priv; if (be->priv) { + if (priv->ptnetmap.running) { + ptnetmap_delete(&priv->ptnetmap); + } nm_close(priv->nmd); free(be->priv); be->priv = NULL; @@ -741,11 +891,6 @@ be, be->name); be->set_features = netbe_null_set_features; } - if (be->get_ptnetmap == NULL) { - /*fprintf(stderr, "missing set_features for %p %s\n", - be, be->name);*/ - be->get_ptnetmap = netbe_null_get_ptnetmap; - } } /* @@ -836,9 +981,8 @@ return 0; /* There are only three valid lengths. */ - if (vnet_hdr_len && vnet_hdr_len != sizeof(struct virtio_net_rxhdr) - && vnet_hdr_len != (sizeof(struct virtio_net_rxhdr) - - sizeof(uint16_t))) + if (vnet_hdr_len && vnet_hdr_len != VNET_HDR_LEN + && vnet_hdr_len != (VNET_HDR_LEN - sizeof(uint16_t))) return -1; be->fe_vnet_hdr_len = vnet_hdr_len; @@ -919,7 +1063,7 @@ */ memset(vh, 0, hlen); - if (hlen == sizeof(struct virtio_net_rxhdr)) { + if (hlen == VNET_HDR_LEN) { vh->vrh_bufs = 1; } } Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:53:35 2016 (r307218) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:54:55 2016 (r307219) @@ -84,4 +84,33 @@ uint16_t vrh_bufs; } __packed; +/* + * ptnetmap definitions + */ +struct ptnetmap_state { + void *netmap_priv; + + /* True if ptnetmap kthreads are running. */ + int running; + + /* Feature acknoweledgement support. */ + unsigned long features; + unsigned long acked_features; + + /* Info about netmap memory. */ + uint32_t memsize; + void *mem; +}; + +/* Used to get read-only info. */ +struct netmap_if_info { + uint32_t nifp_offset; + uint16_t num_tx_rings; + uint16_t num_rx_rings; + uint16_t num_tx_slots; + uint16_t num_rx_slots; +}; + +int ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id); + #endif /* __NET_BACKENDS_H__ */ From owner-svn-soc-all@freebsd.org Fri Aug 5 13:55:48 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 383D0BAFEB2 for ; Fri, 5 Aug 2016 13:55:48 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1DE5A1E72 for ; Fri, 5 Aug 2016 13:55:48 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75DtlZr039004 for ; Fri, 5 Aug 2016 13:55:47 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75Dtlc6038963 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:55:47 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:55:47 GMT Message-Id: <201608051355.u75Dtlc6038963@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307220 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:55:48 -0000 Author: vincenzo Date: Fri Aug 5 13:55:46 2016 New Revision: 307220 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307220 Log: ptnet: add PCI device stub Added: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 13:54:55 2016 (r307219) +++ soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 13:55:46 2016 (r307220) @@ -33,6 +33,7 @@ pci_lpc.c \ pci_passthru.c \ pci_ptnetmap_memdev.c \ + pci_ptnetmap_netif.c \ pci_virtio_block.c \ pci_virtio_net.c \ pci_virtio_rnd.c \ Added: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 13:55:46 2016 (r307220) @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2016 Vincenzo Maffione + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include /* IFNAMSIZ */ +#include +#include + +#include +#include + +#include "bhyverun.h" +#include "pci_emul.h" + +#ifndef PTNET_CSB_ALLOC +#error "Hypervisor-allocated CSB not supported" +#endif + + +struct ptnet_softc { + struct pci_devinst *pi; /* PCI device instance */ +}; + +static uint64_t +ptnet_bar_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + struct ptnet_softc *sc = pi->pi_arg; + + if (sc == NULL) + return 0; + + if (baridx == PTNETMAP_IO_PCI_BAR) { + switch (offset) { + } + } + + printf("%s: Unexpected register read [bar %u, offset %lx size %d]\n", + __func__, baridx, offset, size); + + return 0; +} + +static void +ptnet_bar_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size, uint64_t value) +{ + struct ptnet_softc *sc = pi->pi_arg; + + if (sc == NULL) + return; + + printf("%s: Unexpected register write [bar %u, offset %lx size %d " + "value %lx]\n", __func__, baridx, offset, size, value); +} + +/* PCI device initialization. */ +static int +ptnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) +{ + struct ptnet_softc *sc; + int ret; + + sc = calloc(1, sizeof(*sc)); + if (sc == NULL) { + fprintf(stderr, "%s: out of memory\n", __func__); + return -1; + } + + /* Link our softc in the pci_devinst. */ + pi->pi_arg = sc; + sc->pi = pi; + + /* Initialize PCI configuration space. */ + pci_set_cfgdata16(pi, PCIR_VENDOR, PTNETMAP_PCI_VENDOR_ID); + pci_set_cfgdata16(pi, PCIR_DEVICE, PTNETMAP_PCI_NETIF_ID); + pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_NETWORK); + pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_NETWORK_ETHERNET); + pci_set_cfgdata16(pi, PCIR_SUBDEV_0, 1); + pci_set_cfgdata16(pi, PCIR_SUBVEND_0, PTNETMAP_PCI_VENDOR_ID); + + /* Allocate a BAR for an I/O region. */ + ret = pci_emul_alloc_bar(pi, PTNETMAP_IO_PCI_BAR, PCIBAR_IO, + PTNET_IO_MASK + 1); + if (ret) { + fprintf(stderr, "%s: failed to allocate BAR [%d]\n", + __func__, ret); + return ret; + } + + return 0; +} + +struct pci_devemu pci_de_ptnet = { + .pe_emu = "ptnet", + .pe_init = ptnet_init, + .pe_barwrite = ptnet_bar_write, + .pe_barread = ptnet_bar_read, +}; +PCI_EMUL_SET(pci_de_ptnet); From owner-svn-soc-all@freebsd.org Fri Aug 5 13:56:39 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 9CBDABAFEEC for ; Fri, 5 Aug 2016 13:56:39 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 903AB1E98 for ; Fri, 5 Aug 2016 13:56:39 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75DudqO040049 for ; Fri, 5 Aug 2016 13:56:39 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75DudHj040039 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:56:39 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:56:39 GMT Message-Id: <201608051356.u75DudHj040039@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307221 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:56:39 -0000 Author: vincenzo Date: Fri Aug 5 13:56:38 2016 New Revision: 307221 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307221 Log: bhyve: ptnet: add I/O register data structure Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 13:55:46 2016 (r307220) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 13:56:38 2016 (r307221) @@ -31,6 +31,7 @@ #include #include #include +#include #include /* IFNAMSIZ */ #include @@ -48,7 +49,12 @@ struct ptnet_softc { - struct pci_devinst *pi; /* PCI device instance */ + struct pci_devinst *pi; + + struct ptnetmap_state *ptbe; + unsigned int num_rings; + uint32_t ioregs[PTNET_IO_END >> 2]; + void *csb; }; static uint64_t @@ -65,8 +71,8 @@ } } - printf("%s: Unexpected register read [bar %u, offset %lx size %d]\n", - __func__, baridx, offset, size); + fprintf(stderr, "%s: Unexpected register read [bar %u, offset %lx " + "size %d]\n", __func__, baridx, offset, size); return 0; } @@ -80,8 +86,8 @@ if (sc == NULL) return; - printf("%s: Unexpected register write [bar %u, offset %lx size %d " - "value %lx]\n", __func__, baridx, offset, size, value); + fprintf(stderr, "%s: Unexpected register write [bar %u, offset %lx " + "size %d value %lx]\n", __func__, baridx, offset, size, value); } /* PCI device initialization. */ @@ -118,6 +124,12 @@ return ret; } + /* Initialize registers and data structures. */ + memset(sc->ioregs, 0, sizeof(sc->ioregs)); + sc->csb = NULL; + sc->num_rings = 0; + sc->ptbe = NULL; + return 0; } From owner-svn-soc-all@freebsd.org Fri Aug 5 13:57:48 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 57625BAFF32 for ; Fri, 5 Aug 2016 13:57:48 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4A8E41EE6 for ; Fri, 5 Aug 2016 13:57:48 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75DvmuG041386 for ; Fri, 5 Aug 2016 13:57:48 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75DvkuJ041288 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:57:46 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:57:46 GMT Message-Id: <201608051357.u75DvkuJ041288@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307222 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:57:48 -0000 Author: vincenzo Date: Fri Aug 5 13:57:46 2016 New Revision: 307222 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307222 Log: bhyve: use capabilities rather than features Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:56:38 2016 (r307221) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:57:46 2016 (r307222) @@ -101,14 +101,14 @@ * support. Possible features are TSO, UFO and checksum offloading * in both rx and tx direction and for both IPv4 and IPv6. */ - uint64_t (*get_features)(struct net_backend *be); + uint64_t (*get_cap)(struct net_backend *be); /* * Tell the backend to enable/disable the specified virtio-net - * features. + * features (capabilities). */ - int (*set_features)(struct net_backend *be, uint64_t features, - unsigned int vnet_hdr_len); + int (*set_cap)(struct net_backend *be, uint64_t features, + unsigned int vnet_hdr_len); struct pci_vtnet_softc *sc; int fd; @@ -138,14 +138,14 @@ } static uint64_t -netbe_null_get_features(struct net_backend *be) +netbe_null_get_cap(struct net_backend *be) { D(""); return 0; } static int -netbe_null_set_features(struct net_backend *be, uint64_t features, +netbe_null_set_cap(struct net_backend *be, uint64_t features, unsigned vnet_hdr_len) { D("setting 0x%lx", features); @@ -173,8 +173,8 @@ .cleanup = netbe_null_cleanup, .send = netbe_null_send, .recv = netbe_null_recv, - .get_features = netbe_null_get_features, - .set_features = netbe_null_set_features, + .get_cap = netbe_null_get_cap, + .set_cap = netbe_null_set_cap, }; DATA_SET(net_backend_set, null_backend); @@ -293,13 +293,13 @@ } static uint64_t -tap_get_features(struct net_backend *be) +tap_get_cap(struct net_backend *be) { return 0; // nothing extra } static int -tap_set_features(struct net_backend *be, uint64_t features, +tap_set_cap(struct net_backend *be, uint64_t features, unsigned vnet_hdr_len) { return 0; /* success */ @@ -311,8 +311,8 @@ .cleanup = tap_cleanup, .send = tap_send, .recv = tap_recv, - .get_features = tap_get_features, - .set_features = tap_set_features, + .get_cap = tap_get_cap, + .set_cap = tap_set_cap, }; DATA_SET(net_backend_set, tap_backend); @@ -419,14 +419,14 @@ } static uint64_t -netmap_get_features(struct net_backend *be) +netmap_get_cap(struct net_backend *be) { return netmap_has_vnet_hdr_len(be, VNET_HDR_LEN) ? NETMAP_FEATURES : 0; } static int -netmap_set_features(struct net_backend *be, uint64_t features, +netmap_set_cap(struct net_backend *be, uint64_t features, unsigned vnet_hdr_len) { return netmap_set_vnet_hdr_len(be, vnet_hdr_len); @@ -447,7 +447,7 @@ struct netmap_priv *priv = be->priv; /* Check that this is a netmap backend. */ - if (be->set_features != netmap_set_features) { + if (be->set_cap != netmap_set_cap) { return NULL; } @@ -847,8 +847,8 @@ .cleanup = netmap_cleanup, .send = netmap_send, .recv = netmap_recv, - .get_features = netmap_get_features, - .set_features = netmap_set_features, + .get_cap = netmap_get_cap, + .set_cap = netmap_set_cap, }; DATA_SET(net_backend_set, netmap_backend); @@ -881,15 +881,15 @@ fprintf(stderr, "missing recv for %p %s\n", be, be->name); be->recv = netbe_null_recv; } - if (be->get_features == NULL) { - fprintf(stderr, "missing get_features for %p %s\n", + if (be->get_cap == NULL) { + fprintf(stderr, "missing get_cap for %p %s\n", be, be->name); - be->get_features = netbe_null_get_features; + be->get_cap = netbe_null_get_cap; } - if (be->set_features == NULL) { - fprintf(stderr, "missing set_features for %p %s\n", + if (be->set_cap == NULL) { + fprintf(stderr, "missing set_cap for %p %s\n", be, be->name); - be->set_features = netbe_null_set_features; + be->set_cap = netbe_null_set_cap; } } @@ -964,15 +964,15 @@ } uint64_t -netbe_get_features(struct net_backend *be) +netbe_get_cap(struct net_backend *be) { if (be == NULL) return 0; - return be->get_features(be); + return be->get_cap(be); } int -netbe_set_features(struct net_backend *be, uint64_t features, +netbe_set_cap(struct net_backend *be, uint64_t features, unsigned vnet_hdr_len) { int ret; @@ -987,7 +987,7 @@ be->fe_vnet_hdr_len = vnet_hdr_len; - ret = be->set_features(be, features, vnet_hdr_len); + ret = be->set_cap(be, features, vnet_hdr_len); assert(be->be_vnet_hdr_len == 0 || be->be_vnet_hdr_len == be->fe_vnet_hdr_len); Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:56:38 2016 (r307221) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:57:46 2016 (r307222) @@ -39,8 +39,8 @@ struct net_backend *netbe_init(const char *devname, net_backend_cb_t cb, void *param); void netbe_cleanup(struct net_backend *be); -uint64_t netbe_get_features(struct net_backend *be); -int netbe_set_features(struct net_backend *be, uint64_t features, +uint64_t netbe_get_cap(struct net_backend *be); +int netbe_set_cap(struct net_backend *be, uint64_t cap, unsigned vnet_hdr_len); void netbe_send(struct net_backend *be, struct iovec *iov, int iovcnt, int len, int more); Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 13:56:38 2016 (r307221) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 13:57:46 2016 (r307222) @@ -495,7 +495,7 @@ if (!sc->vsc_be) { WPRINTF(("net backend initialization failed\n")); } else { - vc->vc_hv_caps |= netbe_get_features(sc->vsc_be); + vc->vc_hv_caps |= netbe_get_cap(sc->vsc_be); } free(devname); @@ -605,8 +605,8 @@ sc->rx_vhdrlen -= 2; } - /* Tell the backend to enable some features it has advertised. */ - netbe_set_features(sc->vsc_be, negotiated_features, sc->rx_vhdrlen); + /* Tell the backend to enable some capabilities it has advertised. */ + netbe_set_cap(sc->vsc_be, negotiated_features, sc->rx_vhdrlen); } struct pci_devemu pci_de_vnet = { From owner-svn-soc-all@freebsd.org Fri Aug 5 13:59:01 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BA8AABAFF80 for ; Fri, 5 Aug 2016 13:59:01 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id ADCEA1F24 for ; Fri, 5 Aug 2016 13:59:01 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75Dx1dO042971 for ; Fri, 5 Aug 2016 13:59:01 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75Dwx4H042915 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 13:58:59 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 13:58:59 GMT Message-Id: <201608051358.u75Dwx4H042915@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307223 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 13:59:01 -0000 Author: vincenzo Date: Fri Aug 5 13:58:59 2016 New Revision: 307223 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307223 Log: bhyve: ptnet: various changes Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:57:46 2016 (r307222) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:58:59 2016 (r307223) @@ -444,13 +444,15 @@ struct ptnetmap_state * get_ptnetmap(struct net_backend *be) { - struct netmap_priv *priv = be->priv; + struct netmap_priv *priv; /* Check that this is a netmap backend. */ - if (be->set_cap != netmap_set_cap) { + if (!be || be->set_cap != netmap_set_cap) { return NULL; } + priv = be->priv; + return &priv->ptnetmap; } @@ -1075,3 +1077,26 @@ return ret; } + +int +net_parsemac(char *mac_str, uint8_t *mac_addr) +{ + struct ether_addr *ea; + char *tmpstr; + char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; + + tmpstr = strsep(&mac_str,"="); + + if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { + ea = ether_aton(mac_str); + + if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || + memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { + fprintf(stderr, "Invalid MAC %s\n", mac_str); + return (EINVAL); + } else + memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); + } + + return (0); +} Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:57:46 2016 (r307222) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:58:59 2016 (r307223) @@ -28,6 +28,7 @@ #define __NET_BACKENDS_H__ #include +#include "mevent.h" extern int netmap_ioctl_counter; @@ -111,6 +112,11 @@ uint16_t num_rx_slots; }; +int ptnetmap_get_netmap_if(struct ptnetmap_state *ptn, + struct netmap_if_info *nif); +struct ptnetmap_state * get_ptnetmap(struct net_backend *be); int ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id); +int net_parsemac(char *mac_str, uint8_t *mac_addr); + #endif /* __NET_BACKENDS_H__ */ Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 13:57:46 2016 (r307222) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 13:58:59 2016 (r307223) @@ -42,6 +42,7 @@ #include "bhyverun.h" #include "pci_emul.h" +#include "net_backends.h" #ifndef PTNET_CSB_ALLOC #error "Hypervisor-allocated CSB not supported" @@ -51,12 +52,43 @@ struct ptnet_softc { struct pci_devinst *pi; + struct net_backend *be; struct ptnetmap_state *ptbe; + unsigned int num_rings; uint32_t ioregs[PTNET_IO_END >> 2]; void *csb; }; +static int +ptnet_get_netmap_if(struct ptnet_softc *sc) +{ + unsigned int num_rings; + struct netmap_if_info nif; + int ret; + + ret = ptnetmap_get_netmap_if(sc->ptbe, &nif); + if (ret) { + return ret; + } + + sc->ioregs[PTNET_IO_NIFP_OFS >> 2] = nif.nifp_offset; + sc->ioregs[PTNET_IO_NUM_TX_RINGS >> 2] = nif.num_tx_rings; + sc->ioregs[PTNET_IO_NUM_RX_RINGS >> 2] = nif.num_rx_rings; + sc->ioregs[PTNET_IO_NUM_TX_SLOTS >> 2] = nif.num_tx_slots; + sc->ioregs[PTNET_IO_NUM_RX_SLOTS >> 2] = nif.num_rx_slots; + + num_rings = sc->ioregs[PTNET_IO_NUM_TX_RINGS >> 2] + + sc->ioregs[PTNET_IO_NUM_RX_RINGS >> 2]; + if (sc->num_rings && num_rings && sc->num_rings != num_rings) { + fprintf(stderr, "Number of rings changed: not supported\n"); + return EINVAL; + } + sc->num_rings = num_rings; + + return 0; +} + static uint64_t ptnet_bar_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, uint64_t offset, int size) @@ -95,6 +127,8 @@ ptnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { struct ptnet_softc *sc; + uint8_t macaddr[6]; + int mac_provided = 0; int ret; sc = calloc(1, sizeof(*sc)); @@ -107,6 +141,31 @@ pi->pi_arg = sc; sc->pi = pi; + if (opts != NULL) { + char *ptopts, *devname; + + devname = ptopts = strdup(opts); + (void) strsep(&ptopts, ","); + + if (ptopts != NULL) { + ret = net_parsemac(ptopts, macaddr); + if (ret != 0) { + free(devname); + return ret; + } + mac_provided = 1; + } + + sc->be = netbe_init(devname, NULL, sc); + if (!sc->be) { + fprintf(stderr, "net backend initialization failed\n"); + } + + free(devname); + } + + sc->ptbe = get_ptnetmap(sc->be); + /* Initialize PCI configuration space. */ pci_set_cfgdata16(pi, PCIR_VENDOR, PTNETMAP_PCI_VENDOR_ID); pci_set_cfgdata16(pi, PCIR_DEVICE, PTNETMAP_PCI_NETIF_ID); @@ -127,9 +186,14 @@ /* Initialize registers and data structures. */ memset(sc->ioregs, 0, sizeof(sc->ioregs)); sc->csb = NULL; - sc->num_rings = 0; sc->ptbe = NULL; + sc->num_rings = 0; + ptnet_get_netmap_if(sc); + + /* Allocate a BAR for MSI-X vectors. */ + pci_emul_add_msixcap(pi, sc->num_rings, PTNETMAP_MSIX_PCI_BAR); + return 0; } Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 13:57:46 2016 (r307222) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 13:58:59 2016 (r307223) @@ -413,29 +413,6 @@ #endif static int -pci_vtnet_parsemac(char *mac_str, uint8_t *mac_addr) -{ - struct ether_addr *ea; - char *tmpstr; - char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; - - tmpstr = strsep(&mac_str,"="); - - if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { - ea = ether_aton(mac_str); - - if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || - memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { - fprintf(stderr, "Invalid MAC %s\n", mac_str); - return (EINVAL); - } else - memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); - } - - return (0); -} - -static int pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { MD5_CTX mdctx; @@ -483,7 +460,7 @@ (void) strsep(&vtopts, ","); if (vtopts != NULL) { - err = pci_vtnet_parsemac(vtopts, sc->vsc_config.mac); + err = net_parsemac(vtopts, sc->vsc_config.mac); if (err != 0) { free(devname); return (err); From owner-svn-soc-all@freebsd.org Fri Aug 5 14:00:29 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DD2D0BB0043 for ; Fri, 5 Aug 2016 14:00:29 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D090D1FB0 for ; Fri, 5 Aug 2016 14:00:29 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E0Tk6052559 for ; Fri, 5 Aug 2016 14:00:29 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E0RDw051989 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:00:27 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:00:27 GMT Message-Id: <201608051400.u75E0RDw051989@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307225 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:00:30 -0000 Author: vincenzo Date: Fri Aug 5 14:00:27 2016 New Revision: 307225 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307225 Log: bhyve: ptnet: export net_genmac() function Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 13:53:28 2016 (r307224) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:00:27 2016 (r307225) @@ -1078,6 +1078,13 @@ return ret; } +/* + * Some utils functions, which should go in a separate module. + */ +#include +#include "pci_emul.h" +#include "bhyverun.h" + int net_parsemac(char *mac_str, uint8_t *mac_addr) { @@ -1100,3 +1107,29 @@ return (0); } + +void +net_genmac(struct pci_devinst *pi, uint8_t *macaddr) +{ + /* + * The default MAC address is the standard NetApp OUI of 00-a0-98, + * followed by an MD5 of the PCI slot/func number and dev name + */ + MD5_CTX mdctx; + unsigned char digest[16]; + char nstr[80]; + + snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, + pi->pi_func, vmname); + + MD5Init(&mdctx); + MD5Update(&mdctx, nstr, strlen(nstr)); + MD5Final(digest, &mdctx); + + macaddr[0] = 0x00; + macaddr[1] = 0xa0; + macaddr[2] = 0x98; + macaddr[3] = digest[0]; + macaddr[4] = digest[1]; + macaddr[5] = digest[2]; +} Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 13:53:28 2016 (r307224) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:00:27 2016 (r307225) @@ -117,6 +117,9 @@ struct ptnetmap_state * get_ptnetmap(struct net_backend *be); int ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id); + +#include "pci_emul.h" int net_parsemac(char *mac_str, uint8_t *mac_addr); +void net_genmac(struct pci_devinst *pi, uint8_t *macaddr); #endif /* __NET_BACKENDS_H__ */ Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 13:53:28 2016 (r307224) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:00:27 2016 (r307225) @@ -164,6 +164,10 @@ free(devname); } + if (!mac_provided) { + net_genmac(pi, macaddr); + } + sc->ptbe = get_ptnetmap(sc->be); /* Initialize PCI configuration space. */ Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 13:53:28 2016 (r307224) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:00:27 2016 (r307225) @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -415,9 +414,6 @@ static int pci_vtnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { - MD5_CTX mdctx; - unsigned char digest[16]; - char nstr[80]; char tname[MAXCOMLEN + 1]; struct pci_vtnet_softc *sc; char *devname; @@ -478,24 +474,8 @@ free(devname); } - /* - * The default MAC address is the standard NetApp OUI of 00-a0-98, - * followed by an MD5 of the PCI slot/func number and dev name - */ if (!mac_provided) { - snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, - pi->pi_func, vmname); - - MD5Init(&mdctx); - MD5Update(&mdctx, nstr, strlen(nstr)); - MD5Final(digest, &mdctx); - - sc->vsc_config.mac[0] = 0x00; - sc->vsc_config.mac[1] = 0xa0; - sc->vsc_config.mac[2] = 0x98; - sc->vsc_config.mac[3] = digest[0]; - sc->vsc_config.mac[4] = digest[1]; - sc->vsc_config.mac[5] = digest[2]; + net_genmac(pi, sc->vsc_config.mac); } /* initialize config space */ From owner-svn-soc-all@freebsd.org Fri Aug 5 14:01:42 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D7CCDBB01F0 for ; Fri, 5 Aug 2016 14:01:42 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B10D214A5 for ; Fri, 5 Aug 2016 14:01:42 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E1gM2075904 for ; Fri, 5 Aug 2016 14:01:42 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E1gwM075641 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:01:42 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:01:42 GMT Message-Id: <201608051401.u75E1gwM075641@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307226 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:01:43 -0000 Author: vincenzo Date: Fri Aug 5 14:01:41 2016 New Revision: 307226 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307226 Log: bhyve: ptnet: initialize MAC address register Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:00:27 2016 (r307225) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:01:41 2016 (r307226) @@ -127,6 +127,7 @@ ptnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) { struct ptnet_softc *sc; + char *ptopts, *devname; uint8_t macaddr[6]; int mac_provided = 0; int ret; @@ -141,34 +142,41 @@ pi->pi_arg = sc; sc->pi = pi; - if (opts != NULL) { - char *ptopts, *devname; + /* Parse command line options. */ + if (opts == NULL) { + fprintf(stderr, "%s: No backend specified\n", __func__); + return -1; + } - devname = ptopts = strdup(opts); - (void) strsep(&ptopts, ","); + devname = ptopts = strdup(opts); + (void) strsep(&ptopts, ","); - if (ptopts != NULL) { - ret = net_parsemac(ptopts, macaddr); - if (ret != 0) { - free(devname); - return ret; - } - mac_provided = 1; + if (ptopts != NULL) { + ret = net_parsemac(ptopts, macaddr); + if (ret != 0) { + free(devname); + return ret; } - - sc->be = netbe_init(devname, NULL, sc); - if (!sc->be) { - fprintf(stderr, "net backend initialization failed\n"); - } - - free(devname); + mac_provided = 1; } if (!mac_provided) { net_genmac(pi, macaddr); } + /* Initialize backend. */ + sc->be = netbe_init(devname, NULL, sc); + if (!sc->be) { + fprintf(stderr, "net backend initialization failed\n"); + } + + free(devname); + sc->ptbe = get_ptnetmap(sc->be); + if (!sc->ptbe) { + fprintf(stderr, "%s: failed to get ptnetmap\n", __func__); + return -1; + } /* Initialize PCI configuration space. */ pci_set_cfgdata16(pi, PCIR_VENDOR, PTNETMAP_PCI_VENDOR_ID); @@ -191,6 +199,10 @@ memset(sc->ioregs, 0, sizeof(sc->ioregs)); sc->csb = NULL; sc->ptbe = NULL; + sc->ioregs[PTNET_IO_MAC_HI >> 2] = (macaddr[0] << 8) | macaddr[1]; + sc->ioregs[PTNET_IO_MAC_LO >> 2] = (macaddr[2] << 24) | + (macaddr[3] << 16) | + (macaddr[4] << 8) | macaddr[5]; sc->num_rings = 0; ptnet_get_netmap_if(sc); From owner-svn-soc-all@freebsd.org Fri Aug 5 14:02:21 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2ACFABB024D for ; Fri, 5 Aug 2016 14:02:21 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1E67A163E for ; Fri, 5 Aug 2016 14:02:21 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E2KDG090463 for ; Fri, 5 Aug 2016 14:02:20 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E2KXU089778 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:02:20 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:02:20 GMT Message-Id: <201608051402.u75E2KXU089778@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307227 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:02:21 -0000 Author: vincenzo Date: Fri Aug 5 14:02:19 2016 New Revision: 307227 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307227 Log: bhyve: ptnet: ptnet_bar_read() Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:01:41 2016 (r307226) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:02:19 2016 (r307227) @@ -98,8 +98,21 @@ if (sc == NULL) return 0; - if (baridx == PTNETMAP_IO_PCI_BAR) { + offset = offset & PTNET_IO_MASK; + + if (baridx == PTNETMAP_IO_PCI_BAR && offset < PTNET_IO_END) { switch (offset) { + case PTNET_IO_NIFP_OFS: + case PTNET_IO_NUM_TX_RINGS: + case PTNET_IO_NUM_RX_RINGS: + case PTNET_IO_NUM_TX_SLOTS: + case PTNET_IO_NUM_RX_SLOTS: + /* Fill in device registers with information about + * nifp_offset, num_*x_rings, and num_*x_slots. */ + ptnet_get_netmap_if(sc); + + default: + return sc->ioregs[offset >> 2]; } } From owner-svn-soc-all@freebsd.org Fri Aug 5 14:03:11 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id DEA3CBB02F8 for ; Fri, 5 Aug 2016 14:03:11 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B91C4174E for ; Fri, 5 Aug 2016 14:03:11 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E3BH1096364 for ; Fri, 5 Aug 2016 14:03:11 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E3A3w096280 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:03:10 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:03:10 GMT Message-Id: <201608051403.u75E3A3w096280@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307228 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:03:12 -0000 Author: vincenzo Date: Fri Aug 5 14:03:10 2016 New Revision: 307228 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307228 Log: bhyve: ptnet: implement PTNET_IO_PTFEAT register write Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:02:19 2016 (r307227) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:03:10 2016 (r307228) @@ -112,10 +112,12 @@ uint16_t num_rx_slots; }; +int ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id); int ptnetmap_get_netmap_if(struct ptnetmap_state *ptn, struct netmap_if_info *nif); struct ptnetmap_state * get_ptnetmap(struct net_backend *be); -int ptn_memdev_attach(void *mem_ptr, uint32_t mem_size, uint16_t mem_id); +uint32_t ptnetmap_ack_features(struct ptnetmap_state *ptn, + uint32_t wanted_features); #include "pci_emul.h" Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:02:19 2016 (r307227) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:03:10 2016 (r307228) @@ -98,7 +98,7 @@ if (sc == NULL) return 0; - offset = offset & PTNET_IO_MASK; + offset &= PTNET_IO_MASK; if (baridx == PTNETMAP_IO_PCI_BAR && offset < PTNET_IO_END) { switch (offset) { @@ -127,10 +127,24 @@ int baridx, uint64_t offset, int size, uint64_t value) { struct ptnet_softc *sc = pi->pi_arg; + unsigned int index; if (sc == NULL) return; + offset &= PTNET_IO_MASK; + index = offset >> 2; + + if (baridx == PTNETMAP_IO_PCI_BAR && offset < PTNET_IO_END) { + switch (offset) { + case PTNET_IO_PTFEAT: + value = ptnetmap_ack_features(sc->ptbe, value); + sc->ioregs[index] = value; + break; + } + return; + } + fprintf(stderr, "%s: Unexpected register write [bar %u, offset %lx " "size %d value %lx]\n", __func__, baridx, offset, size, value); } @@ -181,6 +195,7 @@ sc->be = netbe_init(devname, NULL, sc); if (!sc->be) { fprintf(stderr, "net backend initialization failed\n"); + return -1; } free(devname); From owner-svn-soc-all@freebsd.org Fri Aug 5 14:04:05 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 832CABB03CC for ; Fri, 5 Aug 2016 14:04:05 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 681681892 for ; Fri, 5 Aug 2016 14:04:05 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E4526097768 for ; Fri, 5 Aug 2016 14:04:05 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E43HR097709 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:04:03 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:04:03 GMT Message-Id: <201608051404.u75E43HR097709@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307229 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:04:05 -0000 Author: vincenzo Date: Fri Aug 5 14:04:03 2016 New Revision: 307229 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307229 Log: bhyve: ptnet: add support for ptctl (REGIF + UNREGIF) Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:03:10 2016 (r307228) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:04:03 2016 (r307229) @@ -55,7 +55,6 @@ #if (NETMAP_API < 11) #error "Netmap API version must be >= 11" #endif -#include /* * The API for network backends. This might need to be exposed @@ -476,7 +475,7 @@ } int -ptnetmap_get_host_memid(struct ptnetmap_state *ptn) +ptnetmap_get_hostmemid(struct ptnetmap_state *ptn) { struct netmap_priv *priv = ptn->netmap_priv; Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:03:10 2016 (r307228) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:04:03 2016 (r307229) @@ -28,6 +28,8 @@ #define __NET_BACKENDS_H__ #include +#include +#include #include "mevent.h" extern int netmap_ioctl_counter; @@ -118,6 +120,9 @@ struct ptnetmap_state * get_ptnetmap(struct net_backend *be); uint32_t ptnetmap_ack_features(struct ptnetmap_state *ptn, uint32_t wanted_features); +int ptnetmap_get_hostmemid(struct ptnetmap_state *ptn); +int ptnetmap_create(struct ptnetmap_state *ptn, struct ptnetmap_cfg *cfg); +int ptnetmap_delete(struct ptnetmap_state *ptn); #include "pci_emul.h" Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:03:10 2016 (r307228) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:04:03 2016 (r307229) @@ -37,7 +37,11 @@ #include #include +#include +#include +#include #include +#include /* VM_LAPIC_MSI */ #include #include "bhyverun.h" @@ -89,6 +93,108 @@ return 0; } +static int +ptnet_regif(struct ptnet_softc *sc) +{ + struct pci_devinst *pi = sc->pi; + struct vmctx *vmctx = pi->pi_vmctx; + struct ptnetmap_cfg *cfg; + unsigned int kick_addr; + int ret; + int i; + + if (sc->csb == NULL) { + fprintf(stderr, "%s: Unexpected NULL CSB", __func__); + return -1; + } + + cfg = calloc(1, sizeof(*cfg) + sc->num_rings * sizeof(cfg->entries[0])); + + cfg->features = PTNETMAP_CFG_FEAT_CSB | PTNETMAP_CFG_FEAT_EVENTFD; + cfg->num_rings = sc->num_rings; + cfg->ptrings = sc->csb; + + kick_addr = pi->pi_bar[PTNETMAP_IO_PCI_BAR].addr + PTNET_IO_KICK_BASE; + + for (i = 0; i < sc->num_rings; i++, kick_addr += 4) { + struct msix_table_entry *mte; + + cfg->entries[i].irqfd = vm_get_fd(vmctx); + cfg->entries[i].ioctl.com = VM_LAPIC_MSI; + mte = &pi->pi_msix.table[i]; + cfg->entries[i].ioctl.data.msix.addr = mte->addr; + cfg->entries[i].ioctl.data.msix.msg = mte->msg_data; + + fprintf(stderr, "%s: vector %u, addr %lu, data %u, " + "kick_addr %u\n", + __func__, i, mte->addr, mte->msg_data, kick_addr); + + ret = vm_io_reg_handler(vmctx, kick_addr /* ioaddr */, + 0 /* in */, 0 /* mask_data */, + 0 /* data */, VM_IO_REGH_KWEVENTS, + (void *)sc + i /* cookie */); + if (ret) { + fprintf(stderr, "%s: vm_io_reg_handler %d\n", + __func__, ret); + } + cfg->entries[i].ioeventfd = (uint64_t) (sc + i); + } + + ret = ptnetmap_create(sc->ptbe, cfg); + free(cfg); + + return ret; +} + +static int +ptnet_unregif(struct ptnet_softc *sc) +{ + struct pci_devinst *pi = sc->pi; + struct vmctx *vmctx = pi->pi_vmctx; + unsigned int kick_addr; + int i; + + kick_addr = pi->pi_bar[PTNETMAP_IO_PCI_BAR].addr + PTNET_IO_KICK_BASE; + + for (i = 0; i < sc->num_rings; i++, kick_addr += 4) { + vm_io_reg_handler(vmctx, kick_addr, 0, 0, 0, + VM_IO_REGH_DELETE, 0); + } + + return ptnetmap_delete(sc->ptbe); +} + +static void +ptnet_ptctl(struct ptnet_softc *sc, uint64_t cmd) +{ + int ret = EINVAL; + + switch (cmd) { + case NET_PARAVIRT_PTCTL_CONFIG: + fprintf(stderr, "Ignoring deprecated CONFIG PTCTL\n"); + break; + + case NET_PARAVIRT_PTCTL_REGIF: + /* Emulate a REGIF for the guest. */ + ret = ptnet_regif(sc); + break; + + case NET_PARAVIRT_PTCTL_UNREGIF: + /* Emulate an UNREGIF for the guest. */ + ret = ptnet_unregif(sc); + break; + + case NET_PARAVIRT_PTCTL_HOSTMEMID: + ret = ptnetmap_get_hostmemid(sc->ptbe); + break; + + default: + break; + } + + sc->ioregs[PTNET_IO_PTSTS >> 2] = ret; +} + static uint64_t ptnet_bar_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, uint64_t offset, int size) @@ -141,6 +247,11 @@ value = ptnetmap_ack_features(sc->ptbe, value); sc->ioregs[index] = value; break; + + case PTNET_IO_PTCTL: + ptnet_ptctl(sc, value); + break; + } return; } From owner-svn-soc-all@freebsd.org Fri Aug 5 14:04:40 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id AAD22BB0423 for ; Fri, 5 Aug 2016 14:04:40 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9E74918D2 for ; Fri, 5 Aug 2016 14:04:40 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E4e82098813 for ; Fri, 5 Aug 2016 14:04:40 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E4ehs098792 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:04:40 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:04:40 GMT Message-Id: <201608051404.u75E4ehs098792@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307230 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:04:40 -0000 Author: vincenzo Date: Fri Aug 5 14:04:39 2016 New Revision: 307230 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307230 Log: bhyve: ptnet: add CSB allocation protocol support Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:04:03 2016 (r307229) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:04:39 2016 (r307230) @@ -229,6 +229,19 @@ } static void +ptnet_csb_mapping(struct ptnet_softc *sc) +{ + uint64_t base = ((uint64_t)sc->ioregs[PTNET_IO_CSBBAH >> 2] << 32) | + sc->ioregs[PTNET_IO_CSBBAL >> 2]; + uint64_t len = 4096; + + sc->csb = NULL; + if (base) { + sc->csb = paddr_guest2host(sc->pi->pi_vmctx, base, len); + } +} + +static void ptnet_bar_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, int baridx, uint64_t offset, int size, uint64_t value) { @@ -252,6 +265,18 @@ ptnet_ptctl(sc, value); break; + case PTNET_IO_CTRL: + /* Nothing to do for now (done at regif time). */ + break; + + case PTNET_IO_CSBBAH: + sc->ioregs[index] = value; + break; + + case PTNET_IO_CSBBAL: + sc->ioregs[index] = value; + ptnet_csb_mapping(sc); + break; } return; } From owner-svn-soc-all@freebsd.org Fri Aug 5 14:05:25 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 640D3BB048F for ; Fri, 5 Aug 2016 14:05:25 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 577CC1981 for ; Fri, 5 Aug 2016 14:05:25 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E5Pf9099959 for ; Fri, 5 Aug 2016 14:05:25 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E5OrH099956 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:05:24 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:05:24 GMT Message-Id: <201608051405.u75E5OrH099956@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307231 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:05:25 -0000 Author: vincenzo Date: Fri Aug 5 14:05:23 2016 New Revision: 307231 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307231 Log: bhyve: ptnet: support VNET_HDR register Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:04:39 2016 (r307230) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:05:23 2016 (r307231) @@ -426,7 +426,7 @@ static int netmap_set_cap(struct net_backend *be, uint64_t features, - unsigned vnet_hdr_len) + unsigned vnet_hdr_len) { return netmap_set_vnet_hdr_len(be, vnet_hdr_len); } @@ -974,7 +974,7 @@ int netbe_set_cap(struct net_backend *be, uint64_t features, - unsigned vnet_hdr_len) + unsigned vnet_hdr_len) { int ret; Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:04:39 2016 (r307230) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:05:23 2016 (r307231) @@ -277,6 +277,11 @@ sc->ioregs[index] = value; ptnet_csb_mapping(sc); break; + + case PTNET_IO_VNET_HDR_LEN: + netbe_set_cap(sc->be, netbe_get_cap(sc->be), value); + sc->ioregs[index] = value; + break; } return; } From owner-svn-soc-all@freebsd.org Fri Aug 5 14:06:11 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 60E8ABB04E7 for ; Fri, 5 Aug 2016 14:06:11 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3AE7419C7 for ; Fri, 5 Aug 2016 14:06:11 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E6BH0001009 for ; Fri, 5 Aug 2016 14:06:11 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E6AaN000991 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:06:10 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:06:10 GMT Message-Id: <201608051406.u75E6AaN000991@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307232 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:06:11 -0000 Author: vincenzo Date: Fri Aug 5 14:06:09 2016 New Revision: 307232 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307232 Log: bhyve: net_backends: fix get_ptnetmap implementation Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:05:23 2016 (r307231) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:06:09 2016 (r307232) @@ -445,8 +445,9 @@ { struct netmap_priv *priv; - /* Check that this is a netmap backend. */ - if (!be || be->set_cap != netmap_set_cap) { + /* Check that this is a ptnetmap backend. */ + if (!be || be->set_cap != netmap_set_cap || + !(priv->nmd->req.nr_flags & NR_PTNETMAP_HOST)) { return NULL; } @@ -613,11 +614,11 @@ goto err; } + priv->ptnetmap.netmap_priv = priv; + priv->ptnetmap.features = NET_PTN_FEATURES_BASE; + priv->ptnetmap.acked_features = 0; + priv->ptnetmap.running = 0; if (ptnetmap) { - priv->ptnetmap.netmap_priv = priv; - priv->ptnetmap.features = NET_PTN_FEATURES_BASE; - priv->ptnetmap.acked_features = 0; - priv->ptnetmap.running = 0; if (netmap_has_vnet_hdr_len(be, VNET_HDR_LEN)) { priv->ptnetmap.features |= NET_PTN_FEATURES_VNET_HDR; } Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:05:23 2016 (r307231) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:06:09 2016 (r307232) @@ -367,7 +367,6 @@ /* Initialize registers and data structures. */ memset(sc->ioregs, 0, sizeof(sc->ioregs)); sc->csb = NULL; - sc->ptbe = NULL; sc->ioregs[PTNET_IO_MAC_HI >> 2] = (macaddr[0] << 8) | macaddr[1]; sc->ioregs[PTNET_IO_MAC_LO >> 2] = (macaddr[2] << 24) | (macaddr[3] << 16) | From owner-svn-soc-all@freebsd.org Fri Aug 5 14:07:03 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3C80ABB0510 for ; Fri, 5 Aug 2016 14:07:03 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3039E1A0C for ; Fri, 5 Aug 2016 14:07:03 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E73LD002129 for ; Fri, 5 Aug 2016 14:07:03 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E72oU002127 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:07:02 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:07:02 GMT Message-Id: <201608051407.u75E72oU002127@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307233 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:07:03 -0000 Author: vincenzo Date: Fri Aug 5 14:07:02 2016 New Revision: 307233 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307233 Log: bhyve: netmap_init: init be->priv earlier Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:06:09 2016 (r307232) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:07:02 2016 (r307233) @@ -614,6 +614,8 @@ goto err; } + be->priv = priv; + priv->ptnetmap.netmap_priv = priv; priv->ptnetmap.features = NET_PTN_FEATURES_BASE; priv->ptnetmap.acked_features = 0; @@ -627,8 +629,6 @@ priv->nmd->req.nr_arg2); } - be->priv = priv; - return 0; err: From owner-svn-soc-all@freebsd.org Fri Aug 5 14:07:41 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0491FBB059E for ; Fri, 5 Aug 2016 14:07:41 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DDA581A63 for ; Fri, 5 Aug 2016 14:07:40 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E7eYl002918 for ; Fri, 5 Aug 2016 14:07:40 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E7ea7002916 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:07:40 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:07:40 GMT Message-Id: <201608051407.u75E7ea7002916@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307234 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:07:41 -0000 Author: vincenzo Date: Fri Aug 5 14:07:39 2016 New Revision: 307234 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307234 Log: bhyve: ptnet: redirect PCI read/write to the MSI-X emulation code Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:07:02 2016 (r307233) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:07:39 2016 (r307234) @@ -195,39 +195,6 @@ sc->ioregs[PTNET_IO_PTSTS >> 2] = ret; } -static uint64_t -ptnet_bar_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) -{ - struct ptnet_softc *sc = pi->pi_arg; - - if (sc == NULL) - return 0; - - offset &= PTNET_IO_MASK; - - if (baridx == PTNETMAP_IO_PCI_BAR && offset < PTNET_IO_END) { - switch (offset) { - case PTNET_IO_NIFP_OFS: - case PTNET_IO_NUM_TX_RINGS: - case PTNET_IO_NUM_RX_RINGS: - case PTNET_IO_NUM_TX_SLOTS: - case PTNET_IO_NUM_RX_SLOTS: - /* Fill in device registers with information about - * nifp_offset, num_*x_rings, and num_*x_slots. */ - ptnet_get_netmap_if(sc); - - default: - return sc->ioregs[offset >> 2]; - } - } - - fprintf(stderr, "%s: Unexpected register read [bar %u, offset %lx " - "size %d]\n", __func__, baridx, offset, size); - - return 0; -} - static void ptnet_csb_mapping(struct ptnet_softc *sc) { @@ -248,6 +215,13 @@ struct ptnet_softc *sc = pi->pi_arg; unsigned int index; + /* Redirect to MSI-X emulation code. */ + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + pci_emul_msix_twrite(pi, offset, size, value); + return; + } + if (sc == NULL) return; @@ -290,6 +264,44 @@ "size %d value %lx]\n", __func__, baridx, offset, size, value); } +static uint64_t +ptnet_bar_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, + int baridx, uint64_t offset, int size) +{ + struct ptnet_softc *sc = pi->pi_arg; + + if (baridx == pci_msix_table_bar(pi) || + baridx == pci_msix_pba_bar(pi)) { + return pci_emul_msix_tread(pi, offset, size); + } + + if (sc == NULL) + return 0; + + offset &= PTNET_IO_MASK; + + if (baridx == PTNETMAP_IO_PCI_BAR && offset < PTNET_IO_END) { + switch (offset) { + case PTNET_IO_NIFP_OFS: + case PTNET_IO_NUM_TX_RINGS: + case PTNET_IO_NUM_RX_RINGS: + case PTNET_IO_NUM_TX_SLOTS: + case PTNET_IO_NUM_RX_SLOTS: + /* Fill in device registers with information about + * nifp_offset, num_*x_rings, and num_*x_slots. */ + ptnet_get_netmap_if(sc); + + default: + return sc->ioregs[offset >> 2]; + } + } + + fprintf(stderr, "%s: Unexpected register read [bar %u, offset %lx " + "size %d]\n", __func__, baridx, offset, size); + + return 0; +} + /* PCI device initialization. */ static int ptnet_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) From owner-svn-soc-all@freebsd.org Fri Aug 5 14:08:36 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id BB79CBB05EB for ; Fri, 5 Aug 2016 14:08:36 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AEFBF1AB7 for ; Fri, 5 Aug 2016 14:08:36 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E8ang004080 for ; Fri, 5 Aug 2016 14:08:36 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E8aQ4004064 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:08:36 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:08:36 GMT Message-Id: <201608051408.u75E8aQ4004064@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307235 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:08:36 -0000 Author: vincenzo Date: Fri Aug 5 14:08:35 2016 New Revision: 307235 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307235 Log: bhyve: ptnet: don't support CTRL register Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:07:39 2016 (r307234) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:08:35 2016 (r307235) @@ -239,10 +239,6 @@ ptnet_ptctl(sc, value); break; - case PTNET_IO_CTRL: - /* Nothing to do for now (done at regif time). */ - break; - case PTNET_IO_CSBBAH: sc->ioregs[index] = value; break; From owner-svn-soc-all@freebsd.org Fri Aug 5 14:09:14 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 16AD5BB063B for ; Fri, 5 Aug 2016 14:09:14 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EFDFF1B31 for ; Fri, 5 Aug 2016 14:09:13 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75E9Dca004834 for ; Fri, 5 Aug 2016 14:09:13 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75E9Dpb004831 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:09:13 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:09:13 GMT Message-Id: <201608051409.u75E9Dpb004831@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307236 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:09:14 -0000 Author: vincenzo Date: Fri Aug 5 14:09:12 2016 New Revision: 307236 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307236 Log: bhyve: net-backends: expand netmap_common_init() Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:08:35 2016 (r307235) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:09:12 2016 (r307236) @@ -552,28 +552,34 @@ return 0; } -/* Used by netmap at initialization time. */ static int -netmap_common_init(struct net_backend *be, struct netmap_priv *priv, - uint32_t nr_flags, const char *devname, - net_backend_cb_t cb, void *param) +netmap_init(struct net_backend *be, const char *devname, + net_backend_cb_t cb, void *param) { const char *ndname = "/dev/netmap"; + struct netmap_priv *priv = NULL; struct nmreq req; - char tname[40]; + int ptnetmap = 0; + + priv = calloc(1, sizeof(struct netmap_priv)); + if (priv == NULL) { + WPRINTF(("Unable alloc netmap private data\n")); + return -1; + } strncpy(priv->ifname, devname, sizeof(priv->ifname)); priv->ifname[sizeof(priv->ifname) - 1] = '\0'; memset(&req, 0, sizeof(req)); - req.nr_flags = nr_flags; + req.nr_flags = ptnetmap ? NR_PTNETMAP_HOST : 0; priv->nmd = nm_open(priv->ifname, &req, NETMAP_NO_TX_POLL, NULL); if (priv->nmd == NULL) { WPRINTF(("Unable to nm_open(): device '%s', " "interface '%s', errno (%s)\n", ndname, devname, strerror(errno))); - goto err_open; + free(priv); + return -1; } priv->tx = NETMAP_TXRING(priv->nmd->nifp, 0); @@ -584,36 +590,6 @@ priv->rx_continue = 0; be->fd = priv->nmd->fd; - - /* Create a thread for netmap poll. */ - pthread_create(&priv->evloop_tid, NULL, netmap_evloop_thread, (void *)be); - snprintf(tname, sizeof(tname), "netmap-evloop-%p", priv); - pthread_set_name_np(priv->evloop_tid, tname); - - return 0; - -err_open: - return -1; -} - -static int -netmap_init(struct net_backend *be, const char *devname, - net_backend_cb_t cb, void *param) -{ - struct netmap_priv *priv = NULL; - int ptnetmap = 0; - - priv = calloc(1, sizeof(struct netmap_priv)); - if (priv == NULL) { - WPRINTF(("Unable alloc netmap private data\n")); - return -1; - } - - if (netmap_common_init(be, priv, ptnetmap ? NR_PTNETMAP_HOST : 0, - devname, cb, param)) { - goto err; - } - be->priv = priv; priv->ptnetmap.netmap_priv = priv; @@ -627,14 +603,16 @@ /* XXX Call ptn_memdev_attach() here or in get_ptnetmap ? */ ptn_memdev_attach(priv->nmd->mem, priv->nmd->memsize, priv->nmd->req.nr_arg2); + } else { + char tname[40]; + + /* Create a thread for netmap poll. */ + pthread_create(&priv->evloop_tid, NULL, netmap_evloop_thread, (void *)be); + snprintf(tname, sizeof(tname), "netmap-evloop-%p", priv); + pthread_set_name_np(priv->evloop_tid, tname); } return 0; - -err: - free(priv); - - return -1; } static void From owner-svn-soc-all@freebsd.org Fri Aug 5 14:11:25 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 13FB8BB076A for ; Fri, 5 Aug 2016 14:11:25 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 076FD1D09 for ; Fri, 5 Aug 2016 14:11:25 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EBOFX009857 for ; Fri, 5 Aug 2016 14:11:24 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EBOlX009833 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:11:24 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:11:24 GMT Message-Id: <201608051411.u75EBOlX009833@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307237 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:11:25 -0000 Author: vincenzo Date: Fri Aug 5 14:11:23 2016 New Revision: 307237 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307237 Log: bhyve: netmap_init: distinguish ptnetmap checking for NULL callback Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:09:12 2016 (r307236) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:11:23 2016 (r307237) @@ -210,6 +210,11 @@ int opt = 1; struct tap_priv *priv; + if (cb == NULL) { + WPRINTF(("TAP backend requires non-NULL callback\n")); + return -1; + } + priv = calloc(1, sizeof(struct tap_priv)); if (priv == NULL) { WPRINTF(("tap_priv alloc failed\n")); @@ -559,7 +564,7 @@ const char *ndname = "/dev/netmap"; struct netmap_priv *priv = NULL; struct nmreq req; - int ptnetmap = 0; + int ptnetmap = (cb == NULL); priv = calloc(1, sizeof(struct netmap_priv)); if (priv == NULL) { Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:09:12 2016 (r307236) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:11:23 2016 (r307237) @@ -340,7 +340,8 @@ net_genmac(pi, macaddr); } - /* Initialize backend. */ + /* Initialize backend. A NULL callback is used here to tell + * the ask the netmap backend to use ptnetmap. */ sc->be = netbe_init(devname, NULL, sc); if (!sc->be) { fprintf(stderr, "net backend initialization failed\n"); From owner-svn-soc-all@freebsd.org Fri Aug 5 14:13:42 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C9E2ABB090D for ; Fri, 5 Aug 2016 14:13:42 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id BD1B111B3 for ; Fri, 5 Aug 2016 14:13:42 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EDg8V018003 for ; Fri, 5 Aug 2016 14:13:42 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EDdqo017915 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:13:39 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:13:39 GMT Message-Id: <201608051413.u75EDdqo017915@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307238 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:13:42 -0000 Author: vincenzo Date: Fri Aug 5 14:13:39 2016 New Revision: 307238 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307238 Log: bhyve: move net-utils functionalities in a separate module Added: soc2016/vincenzo/head/usr.sbin/bhyve/net_utils.c soc2016/vincenzo/head/usr.sbin/bhyve/net_utils.h Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 14:11:23 2016 (r307237) +++ soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 14:13:39 2016 (r307238) @@ -26,6 +26,7 @@ mevent.c \ mptbl.c \ net_backends.c \ + net_utils.c \ pci_ahci.c \ pci_emul.c \ pci_hostbridge.c \ Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:11:23 2016 (r307237) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:13:39 2016 (r307238) @@ -29,7 +29,6 @@ #include #include #include /* u_short etc */ -#include /* ETHER_ADDR_LEN */ #include #include @@ -1060,59 +1059,3 @@ return ret; } - -/* - * Some utils functions, which should go in a separate module. - */ -#include -#include "pci_emul.h" -#include "bhyverun.h" - -int -net_parsemac(char *mac_str, uint8_t *mac_addr) -{ - struct ether_addr *ea; - char *tmpstr; - char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; - - tmpstr = strsep(&mac_str,"="); - - if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { - ea = ether_aton(mac_str); - - if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || - memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { - fprintf(stderr, "Invalid MAC %s\n", mac_str); - return (EINVAL); - } else - memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); - } - - return (0); -} - -void -net_genmac(struct pci_devinst *pi, uint8_t *macaddr) -{ - /* - * The default MAC address is the standard NetApp OUI of 00-a0-98, - * followed by an MD5 of the PCI slot/func number and dev name - */ - MD5_CTX mdctx; - unsigned char digest[16]; - char nstr[80]; - - snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, - pi->pi_func, vmname); - - MD5Init(&mdctx); - MD5Update(&mdctx, nstr, strlen(nstr)); - MD5Final(digest, &mdctx); - - macaddr[0] = 0x00; - macaddr[1] = 0xa0; - macaddr[2] = 0x98; - macaddr[3] = digest[0]; - macaddr[4] = digest[1]; - macaddr[5] = digest[2]; -} Added: soc2016/vincenzo/head/usr.sbin/bhyve/net_utils.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_utils.c Fri Aug 5 14:13:39 2016 (r307238) @@ -0,0 +1,85 @@ +/*- + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "net_utils.h" +#include "bhyverun.h" +#include +#include +#include +#include +#include + +/* + * Some utils functions, used by net front-ends. + */ + +int +net_parsemac(char *mac_str, uint8_t *mac_addr) +{ + struct ether_addr *ea; + char *tmpstr; + char zero_addr[ETHER_ADDR_LEN] = { 0, 0, 0, 0, 0, 0 }; + + tmpstr = strsep(&mac_str,"="); + + if ((mac_str != NULL) && (!strcmp(tmpstr,"mac"))) { + ea = ether_aton(mac_str); + + if (ea == NULL || ETHER_IS_MULTICAST(ea->octet) || + memcmp(ea->octet, zero_addr, ETHER_ADDR_LEN) == 0) { + fprintf(stderr, "Invalid MAC %s\n", mac_str); + return (EINVAL); + } else + memcpy(mac_addr, ea->octet, ETHER_ADDR_LEN); + } + + return (0); +} + +void +net_genmac(struct pci_devinst *pi, uint8_t *macaddr) +{ + /* + * The default MAC address is the standard NetApp OUI of 00-a0-98, + * followed by an MD5 of the PCI slot/func number and dev name + */ + MD5_CTX mdctx; + unsigned char digest[16]; + char nstr[80]; + + snprintf(nstr, sizeof(nstr), "%d-%d-%s", pi->pi_slot, + pi->pi_func, vmname); + + MD5Init(&mdctx); + MD5Update(&mdctx, nstr, strlen(nstr)); + MD5Final(digest, &mdctx); + + macaddr[0] = 0x00; + macaddr[1] = 0xa0; + macaddr[2] = 0x98; + macaddr[3] = digest[0]; + macaddr[4] = digest[1]; + macaddr[5] = digest[2]; +} Added: soc2016/vincenzo/head/usr.sbin/bhyve/net_utils.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_utils.h Fri Aug 5 14:13:39 2016 (r307238) @@ -0,0 +1,33 @@ +/*- + * Copyright (c) 2011 NetApp, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "pci_emul.h" + +#ifndef _NET_UTILS_H_ +void net_genmac(struct pci_devinst *pi, uint8_t *macaddr); +int net_parsemac(char *mac_str, uint8_t *mac_addr); +#endif /* _NET_UTILS_H_ */ Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:11:23 2016 (r307237) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:13:39 2016 (r307238) @@ -46,6 +46,7 @@ #include "bhyverun.h" #include "pci_emul.h" +#include "net_utils.h" #include "net_backends.h" #ifndef PTNET_CSB_ALLOC @@ -132,12 +133,12 @@ ret = vm_io_reg_handler(vmctx, kick_addr /* ioaddr */, 0 /* in */, 0 /* mask_data */, 0 /* data */, VM_IO_REGH_KWEVENTS, - (void *)sc + i /* cookie */); + (void *)sc + 4*i /* cookie */); if (ret) { fprintf(stderr, "%s: vm_io_reg_handler %d\n", __func__, ret); } - cfg->entries[i].ioeventfd = (uint64_t) (sc + i); + cfg->entries[i].ioeventfd = (uint64_t) (sc + 4*i); } ret = ptnetmap_create(sc->ptbe, cfg); Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:11:23 2016 (r307237) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:13:39 2016 (r307238) @@ -57,6 +57,7 @@ #include "pci_emul.h" #include "mevent.h" #include "virtio.h" +#include "net_utils.h" #include "net_backends.h" #define VTNET_RINGSZ 1024 From owner-svn-soc-all@freebsd.org Fri Aug 5 14:14:41 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D8741BB09CE for ; Fri, 5 Aug 2016 14:14:41 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CBEB41232 for ; Fri, 5 Aug 2016 14:14:41 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EEfdE019260 for ; Fri, 5 Aug 2016 14:14:41 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EEf3j019223 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:14:41 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:14:41 GMT Message-Id: <201608051414.u75EEf3j019223@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307239 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:14:41 -0000 Author: vincenzo Date: Fri Aug 5 14:14:40 2016 New Revision: 307239 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307239 Log: bhyve: ptnet_regif: fix cookie computation Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:13:39 2016 (r307238) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:14:40 2016 (r307239) @@ -119,6 +119,7 @@ for (i = 0; i < sc->num_rings; i++, kick_addr += 4) { struct msix_table_entry *mte; + void *cookie = ((void*)sc) + 4*i; cfg->entries[i].irqfd = vm_get_fd(vmctx); cfg->entries[i].ioctl.com = VM_LAPIC_MSI; @@ -133,12 +134,12 @@ ret = vm_io_reg_handler(vmctx, kick_addr /* ioaddr */, 0 /* in */, 0 /* mask_data */, 0 /* data */, VM_IO_REGH_KWEVENTS, - (void *)sc + 4*i /* cookie */); + cookie /* cookie */); if (ret) { fprintf(stderr, "%s: vm_io_reg_handler %d\n", __func__, ret); } - cfg->entries[i].ioeventfd = (uint64_t) (sc + 4*i); + cfg->entries[i].ioeventfd = (uint64_t) cookie; } ret = ptnetmap_create(sc->ptbe, cfg); From owner-svn-soc-all@freebsd.org Fri Aug 5 14:16:12 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0E19DBB0AA5 for ; Fri, 5 Aug 2016 14:16:12 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 016C81431 for ; Fri, 5 Aug 2016 14:16:12 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EGBPw021429 for ; Fri, 5 Aug 2016 14:16:11 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EGBwt021427 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:16:11 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:16:11 GMT Message-Id: <201608051416.u75EGBwt021427@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307240 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:16:12 -0000 Author: vincenzo Date: Fri Aug 5 14:16:10 2016 New Revision: 307240 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307240 Log: bhyve: netmap_send: rewrite it from scratch Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:14:40 2016 (r307239) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:10 2016 (r307240) @@ -659,81 +659,81 @@ static int netmap_send(struct net_backend *be, struct iovec *iov, - int iovcnt, int size, int more) + int iovcnt, int size, int more) { struct netmap_priv *priv = be->priv; struct netmap_ring *ring; - uint32_t last; - uint32_t idx; - uint8_t *dst; + int nm_buf_size; + int nm_buf_len; + uint32_t head; + void *nm_buf; int j; - uint32_t i; - if (iovcnt <= 0) - goto txsync; + if (iovcnt <= 0 || size <= 0) { + D("Wrong iov: iovcnt %d size %d", iovcnt, size); + return 0; + } ring = priv->tx; - last = i = ring->cur; - - if (nm_ring_space(ring) < iovcnt) { - static int c; - c++; - RD(5, "no space, txsync %d", c); - /* Not enough netmap slots. */ + head = ring->head; + if (head == ring->tail) { + RD(1, "No space, drop %d bytes", size); goto txsync; } + nm_buf = NETMAP_BUF(ring, ring->slot[head].buf_idx); + nm_buf_size = ring->nr_buf_size; + nm_buf_len = 0; for (j = 0; j < iovcnt; j++) { int iov_frag_size = iov[j].iov_len; - int offset = 0; - int nm_frag_size; + void *iov_frag_buf = iov[j].iov_base; /* Split each iovec fragment over more netmap slots, if - necessary (without performing data copy). */ - while (iov_frag_size) { - nm_frag_size = iov_frag_size; - if (nm_frag_size > ring->nr_buf_size) { - nm_frag_size = ring->nr_buf_size; + necessary. */ + for (;;) { + int copylen; + + copylen = iov_frag_size < nm_buf_size ? iov_frag_size : nm_buf_size; + pkt_copy(iov_frag_buf, nm_buf, copylen); + + iov_frag_buf += copylen; + iov_frag_size -= copylen; + nm_buf += copylen; + nm_buf_size -= copylen; + nm_buf_len += copylen; + + if (iov_frag_size == 0) { + break; } - if (nm_ring_empty(ring)) { - /* We run out of netmap slots while splitting the - iovec fragments. */ + ring->slot[head].len = nm_buf_len; + ring->slot[head].flags = NS_MOREFRAG; + head = nm_ring_next(ring, head); + if (head == ring->tail) { + /* We ran out of netmap slots while + * splitting the iovec fragments. */ + RD(1, "No space, drop %d bytes", size); goto txsync; } - - idx = ring->slot[i].buf_idx; - dst = (uint8_t *)NETMAP_BUF(ring, idx); - - ring->slot[i].len = nm_frag_size; -// #define USE_INDIRECT_BUFFERS -#ifdef USE_INDIRECT_BUFFERS - ring->slot[i].flags = NS_MOREFRAG | NS_INDIRECT; - ring->slot[i].ptr = (uintptr_t)(iov[j].iov_base + offset); -#else /* !USE_INDIRECT_BUFFERS */ - ring->slot[i].flags = NS_MOREFRAG; - pkt_copy(iov[j].iov_base + offset, dst, nm_frag_size); -#endif /* !USING_INDIRECT_BUFFERS */ - - last = i; - i = nm_ring_next(ring, i); - - offset += nm_frag_size; - iov_frag_size -= nm_frag_size; + nm_buf = NETMAP_BUF(ring, ring->slot[head].buf_idx); + nm_buf_size = ring->nr_buf_size; + nm_buf_len = 0; } } - /* The last slot must not have NS_MOREFRAG set. */ - ring->slot[last].flags &= ~NS_MOREFRAG; - /* Now update ring->cur and ring->avail. */ - ring->cur = ring->head = i; + /* Complete the last slot, which must not have NS_MOREFRAG set. */ + ring->slot[head].len = nm_buf_len; + ring->slot[head].flags = 0; + head = nm_ring_next(ring, head); -txsync: - if (!more) {// || nm_ring_space(ring) < 64) { - // IFRATE(vq->vq_vs->rate.cur.var2[vq->vq_num]++); - // netmap_ioctl_counter++; - ioctl(be->fd, NIOCTXSYNC, NULL); + /* Now update ring->head and ring->cur. */ + ring->head = ring->cur = head; + + if (more) {// && nm_ring_space(ring) > 64 + return 0; } +txsync: + ioctl(be->fd, NIOCTXSYNC, NULL); return 0; } From owner-svn-soc-all@freebsd.org Fri Aug 5 14:17:00 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3F4DBBB0AF4 for ; Fri, 5 Aug 2016 14:17:00 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 32A5A14C3 for ; Fri, 5 Aug 2016 14:17:00 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EH0m1022467 for ; Fri, 5 Aug 2016 14:17:00 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EGweL022460 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:16:58 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:16:58 GMT Message-Id: <201608051416.u75EGweL022460@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307241 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:17:00 -0000 Author: vincenzo Date: Fri Aug 5 14:16:58 2016 New Revision: 307241 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307241 Log: bhyve: netmap_recv: write it from scratch Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:10 2016 (r307240) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:58 2016 (r307241) @@ -91,8 +91,7 @@ * times to receive a single packet, depending of how big is * buffers you provide. */ - int (*recv)(struct net_backend *be, struct iovec *iov, - int iovcnt, int *more); + int (*recv)(struct net_backend *be, struct iovec *iov, int iovcnt); /* * Ask the backend for the virtio-net features it is able to @@ -158,8 +157,7 @@ } static int -netbe_null_recv(struct net_backend *be, struct iovec *iov, - int iovcnt, int *more) +netbe_null_recv(struct net_backend *be, struct iovec *iov, int iovcnt) { fprintf(stderr, "netbe_null_recv called ?\n"); return -1; /* never called, i believe */ @@ -278,13 +276,12 @@ } static int -tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more) +tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt) { int ret; /* Should never be called without a valid tap fd */ assert(be->fd != -1); - *more = 0; ret = readv(be->fd, iov, iovcnt); @@ -739,90 +736,68 @@ } static int -netmap_recv(struct net_backend *be, struct iovec *iov, - int iovcnt, int *more) +netmap_recv(struct net_backend *be, struct iovec *iov, int iovcnt) { struct netmap_priv *priv = be->priv; + struct netmap_slot *slot = NULL; struct netmap_ring *ring; - int tot = 0; - int copylen; - int iov_avail; - uint8_t *iov_buf; + void *iov_frag_buf; + int iov_frag_size; + int totlen = 0; + uint32_t head; assert(iovcnt); ring = priv->rx; + head = ring->head; + iov_frag_buf = iov->iov_base; + iov_frag_size = iov->iov_len; - /* Init iovec pointers. */ - iov_buf = iov->iov_base; - iov_avail = iov->iov_len; - - if (!priv->rx_continue) { - /* Init netmap pointers. */ - priv->rx_idx = ring->cur; - priv->rx_avail_slots = nm_ring_space(ring); - priv->rx_buf = NETMAP_BUF(ring, - ring->slot[priv->rx_idx].buf_idx); - priv->rx_avail = ring->slot[priv->rx_idx].len; - priv->rx_morefrag = (ring->slot[priv->rx_idx].flags - & NS_MOREFRAG); + do { + int nm_buf_len; + void *nm_buf; - if (!priv->rx_avail_slots) { - goto out; + if (head == ring->tail) { + return 0; } - priv->rx_continue = 1; - } - for (;;) { - copylen = priv->rx_avail; - if (copylen > iov_avail) { - copylen = iov_avail; - } + slot = ring->slot + head; + nm_buf = NETMAP_BUF(ring, slot->buf_idx); + nm_buf_len = slot->len; + + for (;;) { + int copylen = nm_buf_len < iov_frag_size ? nm_buf_len : iov_frag_size; + + pkt_copy(nm_buf, iov_frag_buf, copylen); + nm_buf += copylen; + nm_buf_len -= copylen; + iov_frag_buf += copylen; + iov_frag_size -= copylen; + totlen += copylen; - /* Copy and update pointers. */ - bcopy(priv->rx_buf, iov_buf, copylen); - iov_buf += copylen; - iov_avail -= copylen; - priv->rx_buf += copylen; - priv->rx_avail -= copylen; - tot += copylen; - - if (!priv->rx_avail) { - priv->rx_avail_slots--; - if (!priv->rx_morefrag || !priv->rx_avail_slots) { - priv->rx_continue = 0; + if (nm_buf_len == 0) { break; } - /* Go to the next netmap slot. */ - priv->rx_idx = nm_ring_next(ring, priv->rx_idx); - priv->rx_buf = NETMAP_BUF(ring, - ring->slot[priv->rx_idx].buf_idx); - priv->rx_avail = ring->slot[priv->rx_idx].len; - priv->rx_morefrag = - (ring->slot[priv->rx_idx].flags - & NS_MOREFRAG); - } - if (!iov_avail) { + iov++; iovcnt--; - if (!iovcnt) { - break; + if (iovcnt == 0) { + /* No space to receive. */ + D("Short iov, drop %d bytes", totlen); + return -ENOSPC; } - /* Go to the next iovec descriptor. */ - iov++; - iov_buf = iov->iov_base; - iov_avail = iov->iov_len; + iov_frag_buf = iov->iov_base; + iov_frag_size = iov->iov_len; } - } - if (!priv->rx_continue) { - /* End of reception: Update the ring now. */ - ring->cur = ring->head = nm_ring_next(ring, priv->rx_idx); - } -out: - *more = priv->rx_continue; + head = nm_ring_next(ring, head); + + } while (slot->flags & NS_MOREFRAG); + + /* Release slots to netmap. */ + ring->head = ring->cur = head; - return tot; + return totlen; } static struct net_backend netmap_backend = { @@ -1020,7 +995,7 @@ } int -netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more) +netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt) { int hlen = 0; int ret; @@ -1052,7 +1027,7 @@ } } - ret = be->recv(be, iov, iovcnt, more); + ret = be->recv(be, iov, iovcnt); if (ret > 0) { ret += hlen; } Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:16:10 2016 (r307240) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:16:58 2016 (r307241) @@ -47,8 +47,7 @@ unsigned vnet_hdr_len); void netbe_send(struct net_backend *be, struct iovec *iov, int iovcnt, int len, int more); -int netbe_recv(struct net_backend *be, struct iovec *iov, - int iovcnt, int *more); +int netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt); /* Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:16:10 2016 (r307240) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:16:58 2016 (r307241) @@ -209,11 +209,10 @@ * We only make it large enough for TSO-sized segment. */ static uint8_t dummybuf[65536+64]; - int more; iov[0].iov_base = dummybuf; iov[0].iov_len = sizeof(dummybuf); - netbe_recv(sc->vsc_be, iov, 1, &more); + netbe_recv(sc->vsc_be, iov, 1); } static void @@ -223,7 +222,6 @@ struct vqueue_info *vq; int len, n; uint16_t idx; - int more; /* * This will be called when the rx ring hasn't yet @@ -258,7 +256,7 @@ n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL); assert(n >= 1 && n <= VTNET_MAXSEGS); - len = netbe_recv(sc->vsc_be, iov, n, &more); + len = netbe_recv(sc->vsc_be, iov, n); if (len == 0) { /* From owner-svn-soc-all@freebsd.org Fri Aug 5 14:17:53 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E927CBB0B5B for ; Fri, 5 Aug 2016 14:17:53 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DCA36161F for ; Fri, 5 Aug 2016 14:17:53 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EHr7h023559 for ; Fri, 5 Aug 2016 14:17:53 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EHqwZ023504 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:17:52 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:17:52 GMT Message-Id: <201608051417.u75EHqwZ023504@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307242 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:17:54 -0000 Author: vincenzo Date: Fri Aug 5 14:17:52 2016 New Revision: 307242 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307242 Log: bhyve: pci_virtio_net: don't advertise MRG_RX_BUF capability Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:16:58 2016 (r307241) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:17:52 2016 (r307242) @@ -341,14 +341,6 @@ net_backend_cb_t cb; void *cb_param; - /* Support for splitted receives. */ - int rx_continue; - int rx_idx; - uint8_t *rx_buf; - int rx_avail; - int rx_morefrag; - int rx_avail_slots; - struct ptnetmap_state ptnetmap; }; @@ -588,7 +580,6 @@ priv->cb = cb; priv->cb_param = param; - priv->rx_continue = 0; be->fd = priv->nmd->fd; be->priv = priv; Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:16:58 2016 (r307241) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c Fri Aug 5 14:17:52 2016 (r307242) @@ -64,8 +64,9 @@ #define VTNET_MAXSEGS 256 +/* Our capabilities: we don't support VIRTIO_NET_F_MRG_RXBUF at the moment. */ #define VTNET_S_HOSTCAPS \ - ( VIRTIO_NET_F_MAC | VIRTIO_NET_F_MRG_RXBUF | VIRTIO_NET_F_STATUS | \ + ( VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | \ VIRTIO_F_NOTIFY_ON_EMPTY | VIRTIO_RING_F_INDIRECT_DESC) /* From owner-svn-soc-all@freebsd.org Fri Aug 5 14:18:45 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 82744BB0BAE for ; Fri, 5 Aug 2016 14:18:45 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 760A91678 for ; Fri, 5 Aug 2016 14:18:45 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EIjQ2024531 for ; Fri, 5 Aug 2016 14:18:45 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EIir5024529 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:18:44 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:18:44 GMT Message-Id: <201608051418.u75EIir5024529@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307243 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:18:45 -0000 Author: vincenzo Date: Fri Aug 5 14:18:44 2016 New Revision: 307243 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307243 Log: bhyve: ptnet: print cookie Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:17:52 2016 (r307242) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:18:44 2016 (r307243) @@ -128,8 +128,9 @@ cfg->entries[i].ioctl.data.msix.msg = mte->msg_data; fprintf(stderr, "%s: vector %u, addr %lu, data %u, " - "kick_addr %u\n", - __func__, i, mte->addr, mte->msg_data, kick_addr); + "kick_addr %u, cookie: %p\n", + __func__, i, mte->addr, mte->msg_data, kick_addr, + cookie); ret = vm_io_reg_handler(vmctx, kick_addr /* ioaddr */, 0 /* in */, 0 /* mask_data */, From owner-svn-soc-all@freebsd.org Fri Aug 5 14:19:30 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 15384BB0BF1 for ; Fri, 5 Aug 2016 14:19:30 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 056EF16CC for ; Fri, 5 Aug 2016 14:19:30 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EJTkM025407 for ; Fri, 5 Aug 2016 14:19:29 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EJT9g025404 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:19:29 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:19:29 GMT Message-Id: <201608051419.u75EJT9g025404@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307244 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:19:30 -0000 Author: vincenzo Date: Fri Aug 5 14:19:28 2016 New Revision: 307244 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307244 Log: bhyve: ptnet: use a cookie dependent on MAC address Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:18:44 2016 (r307243) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:19:28 2016 (r307244) @@ -119,7 +119,7 @@ for (i = 0; i < sc->num_rings; i++, kick_addr += 4) { struct msix_table_entry *mte; - void *cookie = ((void*)sc) + 4*i; + uint64_t cookie = sc->ioregs[PTNET_IO_MAC_LO >> 2] + 4*i; cfg->entries[i].irqfd = vm_get_fd(vmctx); cfg->entries[i].ioctl.com = VM_LAPIC_MSI; @@ -130,12 +130,12 @@ fprintf(stderr, "%s: vector %u, addr %lu, data %u, " "kick_addr %u, cookie: %p\n", __func__, i, mte->addr, mte->msg_data, kick_addr, - cookie); + (void*)cookie); ret = vm_io_reg_handler(vmctx, kick_addr /* ioaddr */, 0 /* in */, 0 /* mask_data */, 0 /* data */, VM_IO_REGH_KWEVENTS, - cookie /* cookie */); + (void*)cookie /* cookie */); if (ret) { fprintf(stderr, "%s: vm_io_reg_handler %d\n", __func__, ret); From owner-svn-soc-all@freebsd.org Fri Aug 5 14:20:35 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1FC0DBB0C1C for ; Fri, 5 Aug 2016 14:20:35 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 104171714 for ; Fri, 5 Aug 2016 14:20:35 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75EKYPe027270 for ; Fri, 5 Aug 2016 14:20:34 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75EKXSU027230 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:20:33 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:20:33 GMT Message-Id: <201608051420.u75EKXSU027230@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307245 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:20:35 -0000 Author: vincenzo Date: Fri Aug 5 14:20:32 2016 New Revision: 307245 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307245 Log: bhyve: include netmap_virt.h from the netmap public headers Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:19:28 2016 (r307244) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c Fri Aug 5 14:20:32 2016 (r307245) @@ -487,7 +487,7 @@ struct nmreq req; int err; - if (!(ptn->acked_features & NET_PTN_FEATURES_BASE)) { + if (!(ptn->acked_features & PTNETMAP_F_BASE)) { fprintf(stderr, "%s: ptnetmap features not acked\n", __func__); return EINVAL; @@ -585,12 +585,12 @@ be->priv = priv; priv->ptnetmap.netmap_priv = priv; - priv->ptnetmap.features = NET_PTN_FEATURES_BASE; + priv->ptnetmap.features = PTNETMAP_F_BASE; priv->ptnetmap.acked_features = 0; priv->ptnetmap.running = 0; if (ptnetmap) { if (netmap_has_vnet_hdr_len(be, VNET_HDR_LEN)) { - priv->ptnetmap.features |= NET_PTN_FEATURES_VNET_HDR; + priv->ptnetmap.features |= PTNETMAP_F_VNET_HDR; } /* XXX Call ptn_memdev_attach() here or in get_ptnetmap ? */ ptn_memdev_attach(priv->nmd->mem, priv->nmd->memsize, Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:19:28 2016 (r307244) +++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h Fri Aug 5 14:20:32 2016 (r307245) @@ -29,7 +29,7 @@ #include #include -#include +#include #include "mevent.h" extern int netmap_ioctl_counter; Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c Fri Aug 5 14:19:28 2016 (r307244) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_memdev.c Fri Aug 5 14:20:32 2016 (r307245) @@ -34,7 +34,7 @@ #include /* IFNAMSIZ */ #include -#include +#include #include #include @@ -311,7 +311,7 @@ } struct pci_devemu pci_de_ptnetmap = { - .pe_emu = PTN_MEMDEV_NAME, + .pe_emu = PTNETMAP_MEMDEV_NAME, .pe_init = ptn_memdev_init, .pe_barwrite = ptn_pci_write, .pe_barread = ptn_pci_read Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:19:28 2016 (r307244) +++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_ptnetmap_netif.c Fri Aug 5 14:20:32 2016 (r307245) @@ -35,7 +35,7 @@ #include /* IFNAMSIZ */ #include -#include +#include #include #include @@ -173,21 +173,21 @@ int ret = EINVAL; switch (cmd) { - case NET_PARAVIRT_PTCTL_CONFIG: + case PTNETMAP_PTCTL_CONFIG: fprintf(stderr, "Ignoring deprecated CONFIG PTCTL\n"); break; - case NET_PARAVIRT_PTCTL_REGIF: + case PTNETMAP_PTCTL_REGIF: /* Emulate a REGIF for the guest. */ ret = ptnet_regif(sc); break; - case NET_PARAVIRT_PTCTL_UNREGIF: + case PTNETMAP_PTCTL_UNREGIF: /* Emulate an UNREGIF for the guest. */ ret = ptnet_unregif(sc); break; - case NET_PARAVIRT_PTCTL_HOSTMEMID: + case PTNETMAP_PTCTL_HOSTMEMID: ret = ptnetmap_get_hostmemid(sc->ptbe); break; From owner-svn-soc-all@freebsd.org Fri Aug 5 14:21:25 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E77B1BB0C3F for ; Fri, 5 Aug 2016 14:21:25 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DAF1117C8 for ; Fri, 5 Aug 2016 14:21:25 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75ELPBI028916 for ; Fri, 5 Aug 2016 14:21:25 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75ELPdG028914 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 14:21:25 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 14:21:25 GMT Message-Id: <201608051421.u75ELPdG028914@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307246 - soc2016/vincenzo/head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 14:21:26 -0000 Author: vincenzo Date: Fri Aug 5 14:21:24 2016 New Revision: 307246 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307246 Log: bhyve: Makefile: remove temporary artifact from Makefile Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Modified: soc2016/vincenzo/head/usr.sbin/bhyve/Makefile ============================================================================== --- soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 14:20:32 2016 (r307245) +++ soc2016/vincenzo/head/usr.sbin/bhyve/Makefile Fri Aug 5 14:21:24 2016 (r307246) @@ -54,8 +54,6 @@ LIBADD= vmmapi md pthread -CFLAGS=-I/home/vmaffione/git/netmap/sys - WARNS?= 2 .include From owner-svn-soc-all@freebsd.org Fri Aug 5 16:11:16 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E6B46BB0F3A for ; Fri, 5 Aug 2016 16:11:15 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D96961682 for ; Fri, 5 Aug 2016 16:11:15 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75GBFoM021817 for ; Fri, 5 Aug 2016 16:11:15 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75GBBvf021718 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 16:11:11 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 16:11:11 GMT Message-Id: <201608051611.u75GBBvf021718@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307251 - in soc2016/vincenzo/head/sys: dev/netmap net MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 16:11:16 -0000 Author: vincenzo Date: Fri Aug 5 16:11:11 2016 New Revision: 307251 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307251 Log: align netmap to github and port ptnet driver to head Added: soc2016/vincenzo/head/sys/net/netmap_virt.h Modified: soc2016/vincenzo/head/sys/dev/netmap/if_em_netmap.h soc2016/vincenzo/head/sys/dev/netmap/if_lem_netmap.h soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c soc2016/vincenzo/head/sys/dev/netmap/if_vtnet_netmap.h soc2016/vincenzo/head/sys/dev/netmap/ixgbe_netmap.h soc2016/vincenzo/head/sys/dev/netmap/netmap.c soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c soc2016/vincenzo/head/sys/dev/netmap/netmap_generic.c soc2016/vincenzo/head/sys/dev/netmap/netmap_kern.h soc2016/vincenzo/head/sys/dev/netmap/netmap_mem2.c soc2016/vincenzo/head/sys/dev/netmap/netmap_monitor.c soc2016/vincenzo/head/sys/dev/netmap/netmap_offloadings.c soc2016/vincenzo/head/sys/dev/netmap/netmap_pipe.c soc2016/vincenzo/head/sys/dev/netmap/netmap_vale.c soc2016/vincenzo/head/sys/dev/netmap/ptnetmap.c soc2016/vincenzo/head/sys/net/netmap.h soc2016/vincenzo/head/sys/net/netmap_user.h Modified: soc2016/vincenzo/head/sys/dev/netmap/if_em_netmap.h ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_em_netmap.h Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/if_em_netmap.h Fri Aug 5 16:11:11 2016 (r307251) @@ -148,7 +148,7 @@ /* device-specific */ struct e1000_tx_desc *curr = &txr->tx_base[nic_i]; - struct em_buffer *txbuf = &txr->tx_buffers[nic_i]; + struct em_txbuffer *txbuf = &txr->tx_buffers[nic_i]; int flags = (slot->flags & NS_REPORT || nic_i == 0 || nic_i == report_frequency) ? E1000_TXD_CMD_RS : 0; @@ -239,12 +239,12 @@ nm_i = netmap_idx_n2k(kring, nic_i); for (n = 0; ; n++) { // XXX no need to count - struct e1000_rx_desc *curr = &rxr->rx_base[nic_i]; - uint32_t staterr = le32toh(curr->status); + union e1000_rx_desc_extended *curr = &rxr->rx_base[nic_i]; + uint32_t staterr = le32toh(curr->wb.upper.status_error); if ((staterr & E1000_RXD_STAT_DD) == 0) break; - ring->slot[nm_i].len = le16toh(curr->length); + ring->slot[nm_i].len = le16toh(curr->wb.upper.length); ring->slot[nm_i].flags = slot_flags; bus_dmamap_sync(rxr->rxtag, rxr->rx_buffers[nic_i].map, BUS_DMASYNC_POSTREAD); @@ -271,19 +271,19 @@ uint64_t paddr; void *addr = PNMB(na, slot, &paddr); - struct e1000_rx_desc *curr = &rxr->rx_base[nic_i]; - struct em_buffer *rxbuf = &rxr->rx_buffers[nic_i]; + union e1000_rx_desc_extended *curr = &rxr->rx_base[nic_i]; + struct em_rxbuffer *rxbuf = &rxr->rx_buffers[nic_i]; if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ goto ring_reset; if (slot->flags & NS_BUF_CHANGED) { /* buffer has changed, reload map */ - curr->buffer_addr = htole64(paddr); + curr->read.buffer_addr = htole64(paddr); netmap_reload_map(na, rxr->rxtag, rxbuf->map, addr); slot->flags &= ~NS_BUF_CHANGED; } - curr->status = 0; + curr->wb.upper.status_error = 0; bus_dmamap_sync(rxr->rxtag, rxbuf->map, BUS_DMASYNC_PREREAD); nm_i = nm_next(nm_i, lim); Modified: soc2016/vincenzo/head/sys/dev/netmap/if_lem_netmap.h ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_lem_netmap.h Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/if_lem_netmap.h Fri Aug 5 16:11:11 2016 (r307251) @@ -41,7 +41,7 @@ #ifdef WITH_PTNETMAP_GUEST #include #endif -#include +#include extern int netmap_adaptive_io; @@ -509,7 +509,7 @@ if (csb == NULL) return EINVAL; - ret = lem_ptnetmap_ptctl(ifp, NET_PARAVIRT_PTCTL_CONFIG); + ret = lem_ptnetmap_ptctl(ifp, PTNETMAP_PTCTL_CONFIG); if (ret) return ret; @@ -569,7 +569,7 @@ int ret; if (onoff) { - ret = lem_ptnetmap_ptctl(ifp, NET_PARAVIRT_PTCTL_REGIF); + ret = lem_ptnetmap_ptctl(ifp, PTNETMAP_PTCTL_REGIF); if (ret) return ret; @@ -601,7 +601,7 @@ } else { na->na_flags &= ~NAF_NETMAP_ON; adapter->ptnetmap_enabled = 0; - ret = lem_ptnetmap_ptctl(ifp, NET_PARAVIRT_PTCTL_UNREGIF); + ret = lem_ptnetmap_ptctl(ifp, PTNETMAP_PTCTL_UNREGIF); } return lem_netmap_reg(na, onoff); @@ -634,11 +634,11 @@ { uint32_t features; /* tell the device the features we support */ - E1000_WRITE_REG(&adapter->hw, E1000_PTFEAT, NET_PTN_FEATURES_BASE); + E1000_WRITE_REG(&adapter->hw, E1000_PTFEAT, PTNETMAP_F_BASE); /* get back the acknowledged features */ features = E1000_READ_REG(&adapter->hw, E1000_PTFEAT); device_printf(adapter->dev, "ptnetmap support: %s\n", - (features & NET_PTN_FEATURES_BASE) ? "base" : + (features & PTNETMAP_F_BASE) ? "base" : "none"); return features; } @@ -678,7 +678,7 @@ #if defined (NIC_PTNETMAP) && defined (WITH_PTNETMAP_GUEST) /* XXX: check if the device support ptnetmap (now we use PARA_SUBDEV) */ if ((adapter->hw.subsystem_device_id == E1000_PARA_SUBDEV) && - (lem_ptnetmap_features(adapter) & NET_PTN_FEATURES_BASE)) { + (lem_ptnetmap_features(adapter) & PTNETMAP_F_BASE)) { int err; na.nm_config = lem_ptnetmap_config; @@ -690,7 +690,7 @@ /* Ask the device to fill in some configuration fields. Here we * just need nifp_offset. */ - err = lem_ptnetmap_ptctl(na.ifp, NET_PARAVIRT_PTCTL_CONFIG); + err = lem_ptnetmap_ptctl(na.ifp, PTNETMAP_PTCTL_CONFIG); if (err) { D("Failed to get nifp_offset from passthrough device"); return; Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Aug 5 16:11:11 2016 (r307251) @@ -29,6 +29,7 @@ #include //__FBSDID("$FreeBSD: releng/10.2/sys/dev/netmap/netmap_ptnet.c xxx $"); +#include #include #include #include @@ -51,6 +52,7 @@ #include #include +#include #include #include #include @@ -81,7 +83,7 @@ #include #include #include -#include +#include #include #include @@ -141,7 +143,7 @@ struct ptnet_softc { device_t dev; - struct ifnet *ifp; + if_t ifp; struct ifmedia media; struct mtx lock; char lock_name[16]; @@ -182,24 +184,25 @@ static int ptnet_shutdown(device_t); static void ptnet_init(void *opaque); -static int ptnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); +static int ptnet_ioctl(if_t ifp, u_long cmd, caddr_t data); +static uint64_t ptnet_get_counter(if_t, ift_counter); static int ptnet_init_locked(struct ptnet_softc *sc); static int ptnet_stop(struct ptnet_softc *sc); -static int ptnet_transmit(struct ifnet *ifp, struct mbuf *m); +static int ptnet_transmit(if_t ifp, struct mbuf *m); static int ptnet_drain_transmit_queue(struct ptnet_queue *pq, unsigned int budget, bool may_resched); -static void ptnet_qflush(struct ifnet *ifp); +static void ptnet_qflush(if_t ifp); static void ptnet_tx_task(void *context, int pending); -static int ptnet_media_change(struct ifnet *ifp); -static void ptnet_media_status(struct ifnet *ifp, struct ifmediareq *ifmr); +static int ptnet_media_change(if_t ifp); +static void ptnet_media_status(if_t ifp, struct ifmediareq *ifmr); static void ptnet_tick(void *opaque); static int ptnet_irqs_init(struct ptnet_softc *sc); static void ptnet_irqs_fini(struct ptnet_softc *sc); -static uint32_t ptnet_nm_ptctl(struct ifnet *ifp, uint32_t cmd); +static uint32_t ptnet_nm_ptctl(if_t ifp, uint32_t cmd); static int ptnet_nm_config(struct netmap_adapter *na, unsigned *txr, unsigned *txd, unsigned *rxr, unsigned *rxd); static void ptnet_update_vnet_hdr(struct ptnet_softc *sc); @@ -279,12 +282,12 @@ static int ptnet_attach(device_t dev) { - uint32_t ptfeatures = NET_PTN_FEATURES_BASE; + uint32_t ptfeatures = PTNETMAP_F_BASE; unsigned int num_rx_rings, num_tx_rings; struct netmap_adapter na_arg; unsigned int nifp_offset; struct ptnet_softc *sc; - struct ifnet *ifp; + if_t ifp; uint32_t macreg; int err, rid; int i; @@ -306,11 +309,11 @@ /* Check if we are supported by the hypervisor. If not, * bail out immediately. */ if (ptnet_vnet_hdr) { - ptfeatures |= NET_PTN_FEATURES_VNET_HDR; + ptfeatures |= PTNETMAP_F_VNET_HDR; } bus_write_4(sc->iomem, PTNET_IO_PTFEAT, ptfeatures); /* wanted */ ptfeatures = bus_read_4(sc->iomem, PTNET_IO_PTFEAT); /* acked */ - if (!(ptfeatures & NET_PTN_FEATURES_BASE)) { + if (!(ptfeatures & PTNETMAP_F_BASE)) { device_printf(dev, "Hypervisor does not support netmap " "passthorugh\n"); err = ENXIO; @@ -390,11 +393,12 @@ } if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - if_initbaudrate(ifp, IF_Gbps(10)); + ifp->if_baudrate = IF_Gbps(10); ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX; ifp->if_init = ptnet_init; ifp->if_ioctl = ptnet_ioctl; + ifp->if_get_counter = ptnet_get_counter; ifp->if_transmit = ptnet_transmit; ifp->if_qflush = ptnet_qflush; @@ -414,10 +418,10 @@ ether_ifattach(ifp, sc->hwaddr); - ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); + ifp->if_hdrlen = sizeof(struct ether_vlan_header); ifp->if_capabilities |= IFCAP_JUMBO_MTU | IFCAP_VLAN_MTU; - if (sc->ptfeatures & NET_PTN_FEATURES_VNET_HDR) { + if (sc->ptfeatures & PTNETMAP_F_VNET_HDR) { /* Similarly to what the vtnet driver does, we can emulate * VLAN offloadings by inserting and removing the 802.1Q * header during transmit and receive. We are then able @@ -720,9 +724,9 @@ } static int -ptnet_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +ptnet_ioctl(if_t ifp, u_long cmd, caddr_t data) { - struct ptnet_softc *sc = ifp->if_softc; + struct ptnet_softc *sc = if_getsoftc(ifp); device_t dev = sc->dev; struct ifreq *ifr = (struct ifreq *)data; int mask, err = 0; @@ -815,7 +819,7 @@ static int ptnet_init_locked(struct ptnet_softc *sc) { - struct ifnet *ifp = sc->ifp; + if_t ifp = sc->ifp; struct netmap_adapter *na_dr = &sc->ptna->dr.up; struct netmap_adapter *na_nm = &sc->ptna->hwup.up; unsigned int nm_buf_size; @@ -906,7 +910,7 @@ static int ptnet_stop(struct ptnet_softc *sc) { - struct ifnet *ifp = sc->ifp; + if_t ifp = sc->ifp; struct netmap_adapter *na_dr = &sc->ptna->dr.up; struct netmap_adapter *na_nm = &sc->ptna->hwup.up; int i; @@ -939,9 +943,9 @@ } static void -ptnet_qflush(struct ifnet *ifp) +ptnet_qflush(if_t ifp) { - struct ptnet_softc *sc = ifp->if_softc; + struct ptnet_softc *sc = if_getsoftc(ifp); int i; /* Flush all the bufrings and do the interface flush. */ @@ -962,9 +966,9 @@ } static int -ptnet_media_change(struct ifnet *ifp) +ptnet_media_change(if_t ifp) { - struct ptnet_softc *sc = ifp->if_softc; + struct ptnet_softc *sc = if_getsoftc(ifp); struct ifmedia *ifm = &sc->media; if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER) { @@ -974,12 +978,10 @@ return 0; } -/* Called under core lock. */ -static void -ptnet_tick(void *opaque) +static uint64_t +ptnet_get_counter(if_t ifp, ift_counter cnt) { - struct ptnet_softc *sc = opaque; - struct ifnet *ifp = sc->ifp; + struct ptnet_softc *sc = if_getsoftc(ifp); struct ptnet_queue_stats stats[2]; int i; @@ -996,16 +998,29 @@ stats[idx].mcasts += pq->stats.mcasts; } - /* Update interface statistics. */ - ifp->if_opackets = stats[0].packets; - ifp->if_obytes = stats[0].bytes; - ifp->if_omcasts = stats[0].mcasts; - ifp->if_oerrors = stats[0].errors; - ifp->if_ipackets = stats[1].packets; - ifp->if_ibytes = stats[1].bytes; - ifp->if_imcasts = stats[1].mcasts; - ifp->if_ierrors = stats[1].errors; - ifp->if_iqdrops = stats[1].iqdrops; + switch (cnt) { + case IFCOUNTER_IPACKETS: + return (stats[1].packets); + case IFCOUNTER_IQDROPS: + return (stats[1].iqdrops); + case IFCOUNTER_IERRORS: + return (stats[1].errors); + case IFCOUNTER_OPACKETS: + return (stats[0].packets); + case IFCOUNTER_OBYTES: + return (stats[0].bytes); + case IFCOUNTER_OMCASTS: + return (stats[0].mcasts); + default: + return (if_get_counter_default(ifp, cnt)); + } +} + +/* Called under core lock. */ +static void +ptnet_tick(void *opaque) +{ + struct ptnet_softc *sc = opaque; #ifdef PTNETMAP_STATS for (i = 0; i < sc->num_rings; i++) { @@ -1036,7 +1051,7 @@ } static void -ptnet_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) +ptnet_media_status(if_t ifp, struct ifmediareq *ifmr) { /* We are always active, as the backend netmap port is * always open in netmap mode. */ @@ -1045,9 +1060,9 @@ } static uint32_t -ptnet_nm_ptctl(struct ifnet *ifp, uint32_t cmd) +ptnet_nm_ptctl(if_t ifp, uint32_t cmd) { - struct ptnet_softc *sc = ifp->if_softc; + struct ptnet_softc *sc = if_getsoftc(ifp); int ret; bus_write_4(sc->iomem, PTNET_IO_PTCTL, cmd); @@ -1118,8 +1133,8 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff) { /* device-specific */ - struct ifnet *ifp = na->ifp; - struct ptnet_softc *sc = ifp->if_softc; + if_t ifp = na->ifp; + struct ptnet_softc *sc = if_getsoftc(ifp); int native = (na == &sc->ptna->hwup.up); struct ptnet_queue *pq; enum txrx t; @@ -1160,7 +1175,7 @@ /* Make sure the host adapter passed through is ready * for txsync/rxsync. */ - ret = ptnet_nm_ptctl(ifp, NET_PARAVIRT_PTCTL_REGIF); + ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_REGIF); if (ret) { return ret; } @@ -1210,7 +1225,7 @@ } if (sc->ptna->backend_regifs == 0) { - ret = ptnet_nm_ptctl(ifp, NET_PARAVIRT_PTCTL_UNREGIF); + ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_UNREGIF); } } @@ -1352,7 +1367,7 @@ } static int -ptnet_tx_offload_tso(struct ifnet *ifp, struct mbuf *m, int eth_type, +ptnet_tx_offload_tso(if_t ifp, struct mbuf *m, int eth_type, int offset, bool allow_ecn, struct virtio_net_hdr *hdr) { static struct timeval lastecn; @@ -1391,7 +1406,7 @@ } static struct mbuf * -ptnet_tx_offload(struct ifnet *ifp, struct mbuf *m, bool allow_ecn, +ptnet_tx_offload(if_t ifp, struct mbuf *m, bool allow_ecn, struct virtio_net_hdr *hdr) { int flags, etype, csum_start, proto, error; @@ -1662,7 +1677,7 @@ struct ptnet_softc *sc = pq->sc; bool have_vnet_hdr = sc->vnet_hdr_len; struct netmap_adapter *na = &sc->ptna->dr.up; - struct ifnet *ifp = sc->ifp; + if_t ifp = sc->ifp; unsigned int batch_count = 0; struct ptnet_ring *ptring; struct netmap_kring *kring; @@ -1846,9 +1861,9 @@ } static int -ptnet_transmit(struct ifnet *ifp, struct mbuf *m) +ptnet_transmit(if_t ifp, struct mbuf *m) { - struct ptnet_softc *sc = ifp->if_softc; + struct ptnet_softc *sc = if_getsoftc(ifp); struct ptnet_queue *pq; unsigned int queue_idx; int err; @@ -1961,7 +1976,7 @@ unsigned int const lim = kring->nkr_num_slots - 1; unsigned int head = ring->head; unsigned int batch_count = 0; - struct ifnet *ifp = sc->ifp; + if_t ifp = sc->ifp; unsigned int count = 0; PTNET_Q_LOCK(pq); @@ -2190,9 +2205,9 @@ /* We don't need to handle differently POLL_AND_CHECK_STATUS and * POLL_ONLY, since we don't have an Interrupt Status Register. */ static int -ptnet_poll(struct ifnet *ifp, enum poll_cmd cmd, int budget) +ptnet_poll(if_t ifp, enum poll_cmd cmd, int budget) { - struct ptnet_softc *sc = ifp->if_softc; + struct ptnet_softc *sc = if_getsoftc(ifp); unsigned int queue_budget; unsigned int count = 0; bool borrow = false; Modified: soc2016/vincenzo/head/sys/dev/netmap/if_vtnet_netmap.h ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_vtnet_netmap.h Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/if_vtnet_netmap.h Fri Aug 5 16:11:11 2016 (r307251) @@ -33,7 +33,7 @@ #include /* vtophys ? */ #include #ifdef WITH_PTNETMAP_GUEST -#include +#include #include static int vtnet_ptnetmap_txsync(struct netmap_kring *kring, int flags); #define VTNET_PTNETMAP_ON(_na) \ @@ -477,7 +477,7 @@ vm_paddr_t csb_phyaddr; - csb = contigmalloc(NET_PARAVIRT_CSB_SIZE, M_DEVBUF, + csb = contigmalloc(NETMAP_VIRT_CSB_SIZE, M_DEVBUF, M_NOWAIT | M_ZERO, (size_t)0, -1UL, PAGE_SIZE, 0); if (!csb) { D("Communication Status Block allocation failed!"); @@ -513,7 +513,7 @@ vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_CSBBAH, 0x0ULL); vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_CSBBAL, 0x0ULL); - contigfree(ptna->csb, NET_PARAVIRT_CSB_SIZE, M_DEVBUF); + contigfree(ptna->csb, NETMAP_VIRT_CSB_SIZE, M_DEVBUF); ptna->csb = NULL; } } @@ -538,7 +538,7 @@ if (csb == NULL) return EINVAL; - ret = vtnet_ptnetmap_ptctl(na->ifp, NET_PARAVIRT_PTCTL_CONFIG); + ret = vtnet_ptnetmap_ptctl(na->ifp, PTNETMAP_PTCTL_CONFIG); if (ret) return ret; @@ -642,7 +642,7 @@ ret = vtnet_txq_encap(txq, &m0); } } - ret = vtnet_ptnetmap_ptctl(na->ifp, NET_PARAVIRT_PTCTL_REGIF); + ret = vtnet_ptnetmap_ptctl(na->ifp, PTNETMAP_PTCTL_REGIF); if (ret) { //na->na_flags &= ~NAF_NETMAP_ON; nm_clear_native_flags(na); @@ -674,7 +674,7 @@ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); //na->na_flags &= ~NAF_NETMAP_ON; nm_clear_native_flags(na); - ret = vtnet_ptnetmap_ptctl(na->ifp, NET_PARAVIRT_PTCTL_UNREGIF); + ret = vtnet_ptnetmap_ptctl(na->ifp, PTNETMAP_PTCTL_UNREGIF); vtnet_init_locked(sc); /* also enable intr */ } out: @@ -719,11 +719,11 @@ uint32_t features; /* tell the device the features we support */ vtnet_ptnetmap_iowrite4(dev, PTNETMAP_VIRTIO_IO_PTFEAT, - NET_PTN_FEATURES_BASE); + PTNETMAP_F_BASE); /* get back the acknowledged features */ features = vtnet_ptnetmap_ioread4(dev, PTNETMAP_VIRTIO_IO_PTFEAT); D("ptnetmap support: %s\n", - (features & NET_PTN_FEATURES_BASE) ? "base" : + (features & PTNETMAP_F_BASE) ? "base" : "none"); return features; } @@ -759,7 +759,7 @@ #ifdef WITH_PTNETMAP_GUEST /* check if virtio-net (guest and host) supports ptnetmap */ if (virtio_with_feature(sc->vtnet_dev, VIRTIO_NET_F_PTNETMAP) && - (vtnet_ptnetmap_features(sc) & NET_PTN_FEATURES_BASE)) { + (vtnet_ptnetmap_features(sc) & PTNETMAP_F_BASE)) { struct paravirt_csb *csb; int err; @@ -778,7 +778,7 @@ /* Ask the device to fill in some configuration fields. Here we * just need nifp_offset. */ - err = vtnet_ptnetmap_ptctl(na.ifp, NET_PARAVIRT_PTCTL_CONFIG); + err = vtnet_ptnetmap_ptctl(na.ifp, PTNETMAP_PTCTL_CONFIG); if (err) { D("Failed to get nifp_offset from passthrough device"); return; Modified: soc2016/vincenzo/head/sys/dev/netmap/ixgbe_netmap.h ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/ixgbe_netmap.h Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/ixgbe_netmap.h Fri Aug 5 16:11:11 2016 (r307251) @@ -48,6 +48,7 @@ */ #include +void ixgbe_netmap_attach(struct adapter *adapter); /* * device-specific sysctl variables: @@ -134,20 +135,19 @@ struct adapter *adapter = ifp->if_softc; IXGBE_CORE_LOCK(adapter); - ixgbe_disable_intr(adapter); // XXX maybe ixgbe_stop ? + adapter->stop_locked(adapter); - /* Tell the stack that the interface is no longer active */ - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - set_crcstrip(&adapter->hw, onoff); + if (!IXGBE_IS_VF(adapter)) + set_crcstrip(&adapter->hw, onoff); /* enable or disable flags and callbacks in na and ifp */ if (onoff) { nm_set_native_flags(na); } else { nm_clear_native_flags(na); } - ixgbe_init_locked(adapter); /* also enables intr */ - set_crcstrip(&adapter->hw, onoff); // XXX why twice ? + adapter->init_locked(adapter); /* also enables intr */ + if (!IXGBE_IS_VF(adapter)) + set_crcstrip(&adapter->hw, onoff); // XXX why twice ? IXGBE_CORE_UNLOCK(adapter); return (ifp->if_drv_flags & IFF_DRV_RUNNING ? 0 : 1); } @@ -280,7 +280,7 @@ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* (re)start the tx unit up to slot nic_i (excluded) */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(txr->me), nic_i); + IXGBE_WRITE_REG(&adapter->hw, txr->tail, nic_i); } /* @@ -324,7 +324,8 @@ * REPORT_STATUS in a few slots so TDH is the only * good way. */ - nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_TDH(kring->ring_id)); + nic_i = IXGBE_READ_REG(&adapter->hw, IXGBE_IS_VF(adapter) ? + IXGBE_VFTDH(kring->ring_id) : IXGBE_TDH(kring->ring_id)); if (nic_i >= kring->nkr_num_slots) { /* XXX can it happen ? */ D("TDH wrap %d", nic_i); nic_i -= kring->nkr_num_slots; @@ -393,7 +394,7 @@ * rxr->next_to_check is set to 0 on a ring reinit */ if (netmap_no_pendintr || force_update) { - int crclen = ix_crcstrip ? 0 : 4; + int crclen = (ix_crcstrip || IXGBE_IS_VF(adapter)) ? 0 : 4; uint16_t slot_flags = kring->nkr_slot_flags; nic_i = rxr->next_to_check; // or also k2n(kring->nr_hwtail) @@ -467,7 +468,7 @@ * so move nic_i back by one unit */ nic_i = nm_prev(nic_i, lim); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(rxr->me), nic_i); + IXGBE_WRITE_REG(&adapter->hw, rxr->tail, nic_i); } return 0; @@ -484,7 +485,7 @@ * netmap mode will be disabled and the driver will only * operate in standard mode. */ -static void +void ixgbe_netmap_attach(struct adapter *adapter) { struct netmap_adapter na; Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap.c Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap.c Fri Aug 5 16:11:11 2016 (r307251) @@ -185,7 +185,7 @@ * This is a persistent or ephemeral VALE port. Ephemeral ports * are created on the fly if they don't already exist, and are * always attached to a bridge. - * Persistent VALE ports must must be created seperately, and i + * Persistent VALE ports must must be created separately, and i * then attached like normal NICs. The NIOCREGIF we are examining * will find them only if they had previosly been created and * attached (see VALE_CTL below). @@ -599,8 +599,8 @@ /* * Convenience function used in drivers. Waits for current txsync()s/rxsync()s * to finish and prevents any new one from starting. Call this before turning - * netmap mode off, or before removing the harware rings (e.g., on module - * onload). + * netmap mode off, or before removing the hardware rings (e.g., on module + * onload). */ void netmap_disable_all_rings(struct ifnet *ifp) @@ -634,6 +634,18 @@ } } +void +netmap_undo_zombie(struct ifnet *ifp) +{ + if (NM_NA_VALID(ifp)) { + struct netmap_adapter *na = NA(ifp); + if (na->na_flags & NAF_ZOMBIE) { + netmap_set_all_rings(na, NM_KR_LOCKED); + na->na_flags &= ~NAF_ZOMBIE; + netmap_set_all_rings(na, 0); + } + } +} /* * generic bound_checking function @@ -829,7 +841,7 @@ * IMPORTANT: Always keep one slot empty. */ kring->rtail = kring->nr_hwtail = (t == NR_TX ? ndesc - 1 : 0); - snprintf(kring->name, sizeof(kring->name) - 1, "%s %s%d", na->name, + snprintf(kring->name, sizeof(kring->name) - 1, "%s %s%d", na->name, nm_txrx2str(t), i); ND("ktx %s h %d c %d t %d", kring->name, kring->rhead, kring->rcur, kring->rtail); @@ -918,6 +930,9 @@ na->nm_register(na, 0); } + /* delete rings and buffers that are no longer needed */ + netmap_mem_rings_delete(na); + if (na->active_fds <= 0) { /* last instance */ /* * (TO CHECK) We enter here @@ -936,8 +951,10 @@ if (netmap_verbose) D("deleting last instance for %s", na->name); - /* delete rings and buffers */ - netmap_mem_rings_delete(na); + if (nm_netmap_on(na)) { + D("BUG: netmap on while going to delete the krings"); + } + na->nm_krings_delete(na); } @@ -1392,7 +1409,7 @@ NMG_LOCK_ASSERT(); - /* we cascade through all possibile types of netmap adapter. + /* We cascade through all possible types of netmap adapter. * All netmap_get_*_na() functions return an error and an na, * with the following combinations: * @@ -1692,6 +1709,13 @@ } D("deprecated API, old ringid 0x%x -> ringid %x reg %d", ringid, i, reg); } + + if ((flags & NR_PTNETMAP_HOST) && (reg != NR_REG_ALL_NIC || + flags & (NR_RX_RINGS_ONLY|NR_TX_RINGS_ONLY))) { + D("Error: only NR_REG_ALL_NIC supported with netmap passthrough"); + return EINVAL; + } + for_rx_tx(t) { if (flags & excluded_direction[t]) { priv->np_qfirst[t] = priv->np_qlast[t] = 0; @@ -1939,7 +1963,7 @@ * * * netmap_pipe_reg (pipes) * inform the other pipe end that it is no - * longer responsibile for the lifetime of this + * longer responsible for the lifetime of this * pipe end * * * netmap_monitor_reg (monitors) @@ -1975,7 +1999,7 @@ if (na->active_fds == 0) { /* * If this is the first registration of the adapter, - * also create the netmap rings and their in-kernel view, + * create the in-kernel view of the netmap rings, * the netmap krings. */ @@ -1987,25 +2011,26 @@ if (error) goto err_drop_mem; - /* create all missing netmap rings */ - error = netmap_mem_rings_create(na); - if (error) - goto err_del_krings; } - /* now the kring must exist and we can check whether some + /* now the krings must exist and we can check whether some * previous bind has exclusive ownership on them, and set * nr_pending_mode */ error = netmap_krings_get(priv); if (error) - goto err_del_rings; + goto err_del_krings; + + /* create all needed missing netmap rings */ + error = netmap_mem_rings_create(na); + if (error) + goto err_rel_excl; /* in all cases, create a new netmap if */ nifp = netmap_mem_if_new(na); if (nifp == NULL) { error = ENOMEM; - goto err_rel_excl; + goto err_del_rings; } if (na->active_fds == 0) { @@ -2013,7 +2038,7 @@ error = netmap_mem_get_lut(na->nm_mem, &na->na_lut); if (error) goto err_del_if; - D("lut %p bufs %u size %u", na->na_lut.lut, na->na_lut.objtotal, + ND("lut %p bufs %u size %u", na->na_lut.lut, na->na_lut.objtotal, na->na_lut.objsize); } @@ -2021,7 +2046,7 @@ /* Some kring is switching mode, tell the adapter to * react on this. */ error = na->nm_register(na, 1); - if (error) + if (error) goto err_put_lut; } @@ -2046,8 +2071,7 @@ err_rel_excl: netmap_krings_put(priv); err_del_rings: - if (na->active_fds == 0) - netmap_mem_rings_delete(na); + netmap_mem_rings_delete(na); err_del_krings: if (na->active_fds == 0) na->nm_krings_delete(na); @@ -2245,10 +2269,12 @@ } if (nmr->nr_arg3) { - D("requested %d extra buffers", nmr->nr_arg3); + if (netmap_verbose) + D("requested %d extra buffers", nmr->nr_arg3); nmr->nr_arg3 = netmap_extra_alloc(na, &nifp->ni_bufs_head, nmr->nr_arg3); - D("got %d extra buffers", nmr->nr_arg3); + if (netmap_verbose) + D("got %d extra buffers", nmr->nr_arg3); } nmr->nr_offset = netmap_mem_if_offset(na->nm_mem, nifp); @@ -3009,6 +3035,11 @@ goto done; } + if (nm_os_mbuf_has_offld(m)) { + D("%s drop mbuf requiring offloadings", na->name); + goto done; + } + /* protect against rxsync_from_host(), netmap_sw_to_nic() * and maybe other instances of netmap_transmit (the latter * not possible on Linux). Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_freebsd.c Fri Aug 5 16:11:11 2016 (r307251) @@ -67,8 +67,8 @@ #include #include +#include #include -#include /* ======================== FREEBSD-SPECIFIC ROUTINES ================== */ @@ -116,16 +116,27 @@ } static void +netmap_ifnet_arrival_handler(void *arg __unused, struct ifnet *ifp) +{ + netmap_undo_zombie(ifp); +} + +static void netmap_ifnet_departure_handler(void *arg __unused, struct ifnet *ifp) { netmap_make_zombie(ifp); } +static eventhandler_tag nm_ifnet_ah_tag; static eventhandler_tag nm_ifnet_dh_tag; int nm_os_ifnet_init(void) { + nm_ifnet_ah_tag = + EVENTHANDLER_REGISTER(ifnet_arrival_event, + netmap_ifnet_arrival_handler, + NULL, EVENTHANDLER_PRI_ANY); nm_ifnet_dh_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, netmap_ifnet_departure_handler, @@ -136,6 +147,8 @@ void nm_os_ifnet_fini(void) { + EVENTHANDLER_DEREGISTER(ifnet_arrival_event, + nm_ifnet_ah_tag); EVENTHANDLER_DEREGISTER(ifnet_departure_event, nm_ifnet_dh_tag); } @@ -227,6 +240,14 @@ return NULL; } +int +nm_os_mbuf_has_offld(struct mbuf *m) +{ + return m->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP | CSUM_SCTP | + CSUM_TCP_IPV6 | CSUM_UDP_IPV6 | + CSUM_SCTP_IPV6 | CSUM_TSO); +} + static void freebsd_generic_rx_handler(struct ifnet *ifp, struct mbuf *m) { @@ -590,7 +611,7 @@ }; static driver_t ptn_memdev_driver = { - PTN_MEMDEV_NAME, + PTNETMAP_MEMDEV_NAME, ptn_memdev_methods, sizeof(struct ptnetmap_memdev), }; @@ -676,7 +697,7 @@ return (ENXIO); snprintf(desc, sizeof(desc), "%s PCI adapter", - PTN_MEMDEV_NAME); + PTNETMAP_MEMDEV_NAME); device_set_desc_copy(dev, desc); return (BUS_PROBE_DEFAULT); Modified: soc2016/vincenzo/head/sys/dev/netmap/netmap_generic.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/netmap_generic.c Fri Aug 5 15:48:56 2016 (r307250) +++ soc2016/vincenzo/head/sys/dev/netmap/netmap_generic.c Fri Aug 5 16:11:11 2016 (r307251) @@ -92,7 +92,7 @@ * * We allocate EXT_PACKET mbuf+clusters, but need to set M_NOFREE * so that the destructor, if invoked, will not free the packet. - * In principle we should set the destructor only on demand, + * In principle we should set the destructor only on demand, * but since there might be a race we better do it on allocation. * As a consequence, we also need to set the destructor or we * would leak buffers. @@ -131,8 +131,12 @@ struct mbuf *m; (void)ifp; - m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR | M_NOFREE); + m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (m) { + /* m_getcl() (mb_ctor_mbuf) has an assert that checks that + * M_NOFREE flag is not specified as third argument, + * so we have to set M_NOFREE after m_getcl(). */ + m->m_flags |= M_NOFREE; m->m_ext.ext_arg1 = m->m_ext.ext_buf; // XXX save m->m_ext.ext_free = (void *)netmap_default_mbuf_destructor; m->m_ext.ext_type = EXT_EXTREF; @@ -159,6 +163,13 @@ #include /* struct ethtool_ops, get_ringparam */ #include +static inline struct mbuf * +nm_os_get_mbuf(struct ifnet *ifp, int len) +{ + return alloc_skb(ifp->needed_headroom + len + + ifp->needed_tailroom, GFP_ATOMIC); +} + #endif /* linux */ @@ -168,13 +179,18 @@ #include -#define for_each_tx_kring(_i, _k, _na) \ - for (_k=&(_na)->tx_rings[0], _i = 0; \ - _i < (_na)->num_tx_rings; (_k)++, (_i)++) - -#define for_each_rx_kring(_i, _k, _na) \ - for (_k=&(_na)->rx_rings[0], _i = 0; \ - _i < (_na)->num_rx_rings; (_k)++, (_i)++) +#define for_each_kring_n(_i, _k, _karr, _n) \ + for (_k=_karr, _i = 0; _i < _n; (_k)++, (_i)++) + +#define for_each_tx_kring(_i, _k, _na) \ + for_each_kring_n(_i, _k, (_na)->tx_rings, (_na)->num_tx_rings) +#define for_each_tx_kring_h(_i, _k, _na) \ + for_each_kring_n(_i, _k, (_na)->tx_rings, (_na)->num_tx_rings + 1) + +#define for_each_rx_kring(_i, _k, _na) \ + for_each_kring_n(_i, _k, (_na)->rx_rings, (_na)->num_rx_rings) +#define for_each_rx_kring_h(_i, _k, _na) \ + for_each_kring_n(_i, _k, (_na)->rx_rings, (_na)->num_rx_rings + 1) /* ======================== PERFORMANCE STATISTICS =========================== */ @@ -286,18 +302,25 @@ rtnl_unlock(); } - for_each_rx_kring(r, kring, na) { - if (!nm_kring_pending_off(kring)) { - continue; + for_each_rx_kring_h(r, kring, na) { + if (nm_kring_pending_off(kring)) { + D("RX ring %d of generic adapter %p goes off", r, na); + kring->nr_mode = NKR_NETMAP_OFF; + } + } + for_each_tx_kring_h(r, kring, na) { *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** From owner-svn-soc-all@freebsd.org Fri Aug 5 16:46:09 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 454A0BB069B for ; Fri, 5 Aug 2016 16:46:09 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1FB361A97 for ; Fri, 5 Aug 2016 16:46:09 +0000 (UTC) (envelope-from vincenzo@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u75Gk8nN090138 for ; Fri, 5 Aug 2016 16:46:08 GMT (envelope-from vincenzo@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u75Gk8jB090133 for svn-soc-all@FreeBSD.org; Fri, 5 Aug 2016 16:46:08 GMT (envelope-from vincenzo@FreeBSD.org) Date: Fri, 5 Aug 2016 16:46:08 GMT Message-Id: <201608051646.u75Gk8jB090133@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to vincenzo@FreeBSD.org using -f From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307252 - in soc2016/vincenzo/head/sys: conf dev/netmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Aug 2016 16:46:09 -0000 Author: vincenzo Date: Fri Aug 5 16:46:07 2016 New Revision: 307252 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307252 Log: netmap: update files and fix if_ptnet KASSERT calls Modified: soc2016/vincenzo/head/sys/conf/files soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Modified: soc2016/vincenzo/head/sys/conf/files ============================================================================== --- soc2016/vincenzo/head/sys/conf/files Fri Aug 5 16:11:11 2016 (r307251) +++ soc2016/vincenzo/head/sys/conf/files Fri Aug 5 16:46:07 2016 (r307252) @@ -2117,6 +2117,7 @@ dev/ncr/ncr.c optional ncr pci dev/ncv/ncr53c500.c optional ncv dev/ncv/ncr53c500_pccard.c optional ncv pccard +dev/netmap/if_ptnet.c optional netmap dev/netmap/netmap.c optional netmap dev/netmap/netmap_freebsd.c optional netmap dev/netmap/netmap_generic.c optional netmap @@ -2126,6 +2127,7 @@ dev/netmap/netmap_offloadings.c optional netmap dev/netmap/netmap_pipe.c optional netmap dev/netmap/netmap_vale.c optional netmap +dev/netmap/ptnetmap.c optional netmap # compile-with "${NORMAL_C} -Wconversion -Wextra" dev/nfsmb/nfsmb.c optional nfsmb pci dev/nge/if_nge.c optional nge Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c ============================================================================== --- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Aug 5 16:11:11 2016 (r307251) +++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Aug 5 16:46:07 2016 (r307252) @@ -883,7 +883,7 @@ nm_buf_size = NETMAP_BUF_SIZE(na_dr); - KASSERT(nm_buf_size > 0, "Invalid netmap buffer size"); + KASSERT(nm_buf_size > 0, ("Invalid netmap buffer size")); sc->min_tx_space = PTNET_MAX_PKT_SIZE / nm_buf_size + 2; device_printf(sc->dev, "%s: min_tx_space = %u\n", __func__, sc->min_tx_space); @@ -1811,8 +1811,8 @@ slot->flags = NS_MOREFRAG; head = nm_next(head, lim); - KASSERT(head != rina->tail, - "Unexpectedly run out of TX space"); + KASSERT(head != ring->tail, + ("Unexpectedly run out of TX space")); slot = ring->slot + head; nmbuf = NMB(na, slot); nmbuf_bytes = 0; @@ -2213,7 +2213,7 @@ bool borrow = false; int i; - KASSERT(sc->num_rings > 0, "Found no queues in while polling ptnet"); + KASSERT(sc->num_rings > 0, ("Found no queues in while polling ptnet")); queue_budget = MAX(budget / sc->num_rings, 1); RD(1, "Per-queue budget is %d", queue_budget); From owner-svn-soc-all@freebsd.org Sat Aug 6 12:14:28 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D27FEBAE723 for ; Sat, 6 Aug 2016 12:14:28 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id C5F451A48 for ; Sat, 6 Aug 2016 12:14:28 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u76CES95010031 for ; Sat, 6 Aug 2016 12:14:28 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u76CESXb009347 for svn-soc-all@FreeBSD.org; Sat, 6 Aug 2016 12:14:28 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 6 Aug 2016 12:14:28 GMT Message-Id: <201608061214.u76CESXb009347@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307273 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2016 12:14:28 -0000 Author: iateaca Date: Sat Aug 6 12:14:27 2016 New Revision: 307273 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307273 Log: make it compile with HDA_DEBUG=0 M pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Aug 6 11:02:07 2016 (r307272) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Aug 6 12:14:27 2016 (r307273) @@ -141,7 +141,7 @@ static int hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value); -static void +static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p); static int hda_corb_start(struct hda_softc *sc); @@ -705,11 +705,12 @@ return 0; } -static void +static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p) { +#if DEBUG_HDA == 1 char *name = p->name; - +#endif DPRINTF("%s size: %d\n", name, p->size); DPRINTF("%s dma_vaddr: %p\n", name, p->dma_vaddr); DPRINTF("%s wp: 0x%x\n", name, p->wp); From owner-svn-soc-all@freebsd.org Sat Aug 6 13:01:52 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 24F64BAF969 for ; Sat, 6 Aug 2016 13:01:52 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 17D82157A for ; Sat, 6 Aug 2016 13:01:52 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u76D1p8G091114 for ; Sat, 6 Aug 2016 13:01:51 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u76D1p5c090917 for svn-soc-all@FreeBSD.org; Sat, 6 Aug 2016 13:01:51 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 6 Aug 2016 13:01:51 GMT Message-Id: <201608061301.u76D1p5c090917@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307276 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2016 13:01:52 -0000 Author: iateaca Date: Sat Aug 6 13:01:50 2016 New Revision: 307276 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307276 Log: redesign the hda_codec_parameters using macros for each node in order to allow multiple configurations (1 output channel, 1 input channel or both of them) M hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Aug 6 12:51:07 2016 (r307275) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Aug 6 13:01:50 2016 (r307276) @@ -185,70 +185,85 @@ * HDA Codec global data */ +#define HDA_CODEC_ROOT_DESC \ + [HDA_CODEC_ROOT_NID] = { \ + [HDA_PARAM_VENDOR_ID] = INTEL_VENDORID, \ + [HDA_PARAM_REVISION_ID] = 0xffff, \ + [HDA_PARAM_SUB_NODE_COUNT] = 0x00010001, /* 1 Subnode, StartNid = 1 */ \ + }, \ + +#define HDA_CODEC_FG_COMMON_DESC \ + [HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO, \ + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, /* B8 - B32, 8.0 - 192.0kHz */ \ + [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ + [HDA_PARAM_GPIO_COUNT] = 0x00, \ + +#define HDA_CODEC_FG_DUPLEX_DESC \ + [HDA_CODEC_FG_NID] = { \ + [HDA_PARAM_SUB_NODE_COUNT] = 0x00020004, /* 4 Subnodes, StartNid = 2 */ \ + HDA_CODEC_FG_COMMON_DESC \ + }, \ + +#define HDA_CODEC_OUTPUT_DESC \ + [HDA_CODEC_AUDIO_OUTPUT_NID] = { \ + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_OUTPUT | \ + HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | \ + HDA_CODEC_AUDIO_WCAP_AMP_OVR | \ + HDA_CODEC_AUDIO_WCAP_OUT_AMP | \ + HDA_CODEC_AUDIO_WCAP_STEREO, \ + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, /* B16, 16.0 - 192.0kHz */ \ + [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ + [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, \ + [HDA_PARAM_OUTPUT_AMP_CAP] = HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | \ + HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | \ + HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | \ + HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, \ + }, \ + [HDA_CODEC_PIN_OUTPUT_NID] = { \ + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_PIN | \ + HDA_CODEC_AUDIO_WCAP_CONN_LIST | \ + HDA_CODEC_AUDIO_WCAP_STEREO, \ + [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_OUTPUT | \ + HDA_CODEC_PIN_CAP_PRESENCE_DETECT, \ + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ + [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, \ + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ + }, \ + +#define HDA_CODEC_INPUT_DESC \ + [HDA_CODEC_AUDIO_INPUT_NID] = { \ + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_INPUT | \ + HDA_CODEC_AUDIO_WCAP_CONN_LIST | \ + HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | \ + HDA_CODEC_AUDIO_WCAP_AMP_OVR | \ + HDA_CODEC_AUDIO_WCAP_IN_AMP | \ + HDA_CODEC_AUDIO_WCAP_STEREO, \ + [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, /* B16, 16.0 - 192.0kHz */ \ + [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ + [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, \ + [HDA_PARAM_INPUT_AMP_CAP] = HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | \ + HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | \ + HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | \ + HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, \ + }, \ + [HDA_CODEC_PIN_INPUT_NID] = { \ + [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_PIN | \ + HDA_CODEC_AUDIO_WCAP_STEREO, \ + [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_INPUT | \ + HDA_CODEC_PIN_CAP_PRESENCE_DETECT, \ + [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ + [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ + }, \ + static const uint32_t hda_codec_parameters[][HDA_CODEC_PARAMS_COUNT] = { - [HDA_CODEC_ROOT_NID] = { - [HDA_PARAM_VENDOR_ID] = INTEL_VENDORID, - [HDA_PARAM_REVISION_ID] = 0xffff, - [HDA_PARAM_SUB_NODE_COUNT] = 0x00010001, /* 1 Subnode, StartNid = 1 */ - }, - [HDA_CODEC_FG_NID] = { - [HDA_PARAM_SUB_NODE_COUNT] = 0x00020004, /* 4 Subnodes, StartNid = 2 */ - [HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO, - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, /* B8 - B32, 8.0 - 192.0kHz */ - [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ - [HDA_PARAM_GPIO_COUNT] = 0x00, - }, - [HDA_CODEC_AUDIO_OUTPUT_NID] = { - [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_OUTPUT | - HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | - HDA_CODEC_AUDIO_WCAP_AMP_OVR | - HDA_CODEC_AUDIO_WCAP_OUT_AMP | - HDA_CODEC_AUDIO_WCAP_STEREO, - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, /* B16, 16.0 - 192.0kHz */ - [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, - [HDA_PARAM_OUTPUT_AMP_CAP] = HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | - HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | - HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | - HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, - }, - [HDA_CODEC_PIN_OUTPUT_NID] = { - [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_PIN | - HDA_CODEC_AUDIO_WCAP_CONN_LIST | - HDA_CODEC_AUDIO_WCAP_STEREO, - [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_OUTPUT | - HDA_CODEC_PIN_CAP_PRESENCE_DETECT, - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ - }, - [HDA_CODEC_AUDIO_INPUT_NID] = { - [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_INPUT | - HDA_CODEC_AUDIO_WCAP_CONN_LIST | - HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | - HDA_CODEC_AUDIO_WCAP_AMP_OVR | - HDA_CODEC_AUDIO_WCAP_IN_AMP | - HDA_CODEC_AUDIO_WCAP_STEREO, - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, /* B16, 16.0 - 192.0kHz */ - [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM, - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, - [HDA_PARAM_INPUT_AMP_CAP] = HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | - HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | - HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | - HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, - }, - [HDA_CODEC_PIN_INPUT_NID] = { - [HDA_PARAM_AUDIO_WIDGET_CAP] = HDA_CODEC_AUDIO_WCAP_PIN | - HDA_CODEC_AUDIO_WCAP_STEREO, - [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_INPUT | - HDA_CODEC_PIN_CAP_PRESENCE_DETECT, - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ - }, + HDA_CODEC_ROOT_DESC + HDA_CODEC_FG_DUPLEX_DESC + HDA_CODEC_OUTPUT_DESC + HDA_CODEC_INPUT_DESC }; #define HDA_CODEC_NODES_COUNT (ARRAY_SIZE(hda_codec_parameters)) From owner-svn-soc-all@freebsd.org Sat Aug 6 13:36:25 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 0E8AFBB0430 for ; Sat, 6 Aug 2016 13:36:25 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E80DE183E for ; Sat, 6 Aug 2016 13:36:24 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u76DaONq069932 for ; Sat, 6 Aug 2016 13:36:24 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u76DaOrr069930 for svn-soc-all@FreeBSD.org; Sat, 6 Aug 2016 13:36:24 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 6 Aug 2016 13:36:24 GMT Message-Id: <201608061336.u76DaOrr069930@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307277 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2016 13:36:25 -0000 Author: iateaca Date: Sat Aug 6 13:36:23 2016 New Revision: 307277 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307277 Log: add output, input and duplex configuration M hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Aug 6 13:01:50 2016 (r307276) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Aug 6 13:36:23 2016 (r307277) @@ -200,6 +200,24 @@ [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ [HDA_PARAM_GPIO_COUNT] = 0x00, \ +#define HDA_CODEC_FG_NONE_DESC \ + [HDA_CODEC_FG_NID] = { \ + [HDA_PARAM_SUB_NODE_COUNT] = 0x00000000, /* 0 Subnodes, StartNid = 0 */ \ + HDA_CODEC_FG_COMMON_DESC \ + }, \ + +#define HDA_CODEC_FG_OUTPUT_DESC \ + [HDA_CODEC_FG_NID] = { \ + [HDA_PARAM_SUB_NODE_COUNT] = 0x00020002, /* 2 Subnodes, StartNid = 2 */ \ + HDA_CODEC_FG_COMMON_DESC \ + }, \ + +#define HDA_CODEC_FG_INPUT_DESC \ + [HDA_CODEC_FG_NID] = { \ + [HDA_PARAM_SUB_NODE_COUNT] = 0x00040002, /* 2 Subnodes, StartNid = 4 */ \ + HDA_CODEC_FG_COMMON_DESC \ + }, \ + #define HDA_CODEC_FG_DUPLEX_DESC \ [HDA_CODEC_FG_NID] = { \ [HDA_PARAM_SUB_NODE_COUNT] = 0x00020004, /* 4 Subnodes, StartNid = 2 */ \ @@ -259,14 +277,31 @@ [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ }, \ -static const uint32_t hda_codec_parameters[][HDA_CODEC_PARAMS_COUNT] = { +static const uint32_t hda_codec_none_parameters[][HDA_CODEC_PARAMS_COUNT] = { + HDA_CODEC_ROOT_DESC + HDA_CODEC_FG_NONE_DESC +}; + +static const uint32_t hda_codec_output_parameters[][HDA_CODEC_PARAMS_COUNT] = { + HDA_CODEC_ROOT_DESC + HDA_CODEC_FG_OUTPUT_DESC + HDA_CODEC_OUTPUT_DESC +}; + +static const uint32_t hda_codec_input_parameters[][HDA_CODEC_PARAMS_COUNT] = { + HDA_CODEC_ROOT_DESC + HDA_CODEC_FG_INPUT_DESC + HDA_CODEC_INPUT_DESC +}; + +static const uint32_t hda_codec_duplex_parameters[][HDA_CODEC_PARAMS_COUNT] = { HDA_CODEC_ROOT_DESC HDA_CODEC_FG_DUPLEX_DESC HDA_CODEC_OUTPUT_DESC HDA_CODEC_INPUT_DESC }; -#define HDA_CODEC_NODES_COUNT (ARRAY_SIZE(hda_codec_parameters)) +#define HDA_CODEC_NODES_COUNT (ARRAY_SIZE(hda_codec_duplex_parameters)) static const uint8_t hda_codec_conn_list[HDA_CODEC_NODES_COUNT][HDA_CODEC_CONN_LIST_COUNT] = { [HDA_CODEC_PIN_OUTPUT_NID] = {HDA_CODEC_AUDIO_OUTPUT_NID}, @@ -313,7 +348,7 @@ sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID; sc->no_nodes = HDA_CODEC_NODES_COUNT; - sc->get_parameters = hda_codec_parameters; + sc->get_parameters = hda_codec_duplex_parameters; sc->conn_list = hda_codec_conn_list; sc->conf_default = hda_codec_conf_default; sc->pin_ctrl_default = hda_codec_pin_ctrl_default; From owner-svn-soc-all@freebsd.org Sat Aug 6 15:38:27 2016 Return-Path: Delivered-To: svn-soc-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2B845BAFED4 for ; Sat, 6 Aug 2016 15:38:27 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 10D9A1DAB for ; Sat, 6 Aug 2016 15:38:27 +0000 (UTC) (envelope-from iateaca@FreeBSD.org) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.15.2/8.15.2) with ESMTP id u76FcQkm074771 for ; Sat, 6 Aug 2016 15:38:26 GMT (envelope-from iateaca@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.15.2/8.15.2/Submit) id u76FcPok074709 for svn-soc-all@FreeBSD.org; Sat, 6 Aug 2016 15:38:25 GMT (envelope-from iateaca@FreeBSD.org) Date: Sat, 6 Aug 2016 15:38:25 GMT Message-Id: <201608061538.u76FcPok074709@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to iateaca@FreeBSD.org using -f From: iateaca@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r307280 - soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2016 15:38:27 -0000 Author: iateaca Date: Sat Aug 6 15:38:25 2016 New Revision: 307280 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307280 Log: redesign the init interface if the hda codec: add 2 more parameters (play and rec) in order to transmit the codec the name of the audio devices M hda_codec.c M pci_hda.c M pci_hda.h Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Aug 6 13:32:40 2016 (r307279) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/hda_codec.c Sat Aug 6 15:38:25 2016 (r307280) @@ -155,7 +155,7 @@ * HDA Codec module function declarations */ static int -hda_codec_init(struct hda_codec_inst *hci, const char *opts); +hda_codec_init(struct hda_codec_inst *hci, const char *play, const char *rec, const char *opts); static int hda_codec_reset(struct hda_codec_inst *hci); static int @@ -200,12 +200,6 @@ [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ [HDA_PARAM_GPIO_COUNT] = 0x00, \ -#define HDA_CODEC_FG_NONE_DESC \ - [HDA_CODEC_FG_NID] = { \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00000000, /* 0 Subnodes, StartNid = 0 */ \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - #define HDA_CODEC_FG_OUTPUT_DESC \ [HDA_CODEC_FG_NID] = { \ [HDA_PARAM_SUB_NODE_COUNT] = 0x00020002, /* 2 Subnodes, StartNid = 2 */ \ @@ -277,11 +271,6 @@ [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ }, \ -static const uint32_t hda_codec_none_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_NONE_DESC -}; - static const uint32_t hda_codec_output_parameters[][HDA_CODEC_PARAMS_COUNT] = { HDA_CODEC_ROOT_DESC HDA_CODEC_FG_OUTPUT_DESC @@ -334,21 +323,31 @@ */ static int -hda_codec_init(struct hda_codec_inst *hci, const char *opts) +hda_codec_init(struct hda_codec_inst *hci, const char *play, const char *rec, const char *opts) { struct hda_codec_softc *sc = NULL; struct hda_codec_stream *st = NULL; int err; + if (!(play || rec)) + return -1; + DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts); sc = calloc(1, sizeof(*sc)); if (!sc) return -1; + if (play && rec) + sc->get_parameters = hda_codec_duplex_parameters; + else { + if (play) + sc->get_parameters = hda_codec_output_parameters; + else + sc->get_parameters = hda_codec_input_parameters; + } sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID; sc->no_nodes = HDA_CODEC_NODES_COUNT; - sc->get_parameters = hda_codec_duplex_parameters; sc->conn_list = hda_codec_conn_list; sc->conf_default = hda_codec_conf_default; sc->pin_ctrl_default = hda_codec_pin_ctrl_default; @@ -358,31 +357,35 @@ /* * Initialize the Audio Output stream */ - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - - err = hda_audio_ctxt_init(&st->actx, "hda-audio-output", hda_codec_audio_output_do_transfer, hda_codec_audio_output_do_setup, sc); - assert(!err); + if (play) { + st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - /* TODO Get the name of the sound device from the config string */ - st->aud = audio_init("/dev/dsp0", 1); - if (!st->aud) { - DPRINTF("Fail to init the output audio player\n"); - return -1; + err = hda_audio_ctxt_init(&st->actx, "hda-audio-output", + hda_codec_audio_output_do_transfer, hda_codec_audio_output_do_setup, sc); + assert(!err); + + st->aud = audio_init(play, 1); + if (!st->aud) { + DPRINTF("Fail to init the output audio player\n"); + return -1; + } } /* * Initialize the Audio Input stream */ - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - - err = hda_audio_ctxt_init(&st->actx, "hda-audio-input", hda_codec_audio_input_do_transfer, hda_codec_audio_input_do_setup, sc); - assert(!err); + if (rec) { + st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - /* TODO Get the name of the sound device from the config string */ - st->aud = audio_init("/dev/dsp1", 0); - if (!st->aud) { - DPRINTF("Fail to init the input audio player\n"); - return -1; + err = hda_audio_ctxt_init(&st->actx, "hda-audio-input", + hda_codec_audio_input_do_transfer, hda_codec_audio_input_do_setup, sc); + assert(!err); + + st->aud = audio_init(rec, 0); + if (!st->aud) { + DPRINTF("Fail to init the input audio player\n"); + return -1; + } } sc->hci = hci; Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Aug 6 13:32:40 2016 (r307279) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.c Sat Aug 6 15:38:25 2016 (r307280) @@ -432,7 +432,7 @@ return -1; } - return codec->init(hci, NULL); + return codec->init(hci, "/dev/dsp0", "/dev/dsp1", NULL); } static struct hda_codec_class * Modified: soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h ============================================================================== --- soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Sat Aug 6 13:32:40 2016 (r307279) +++ soc2016/iateaca/bhyve-hda-head/usr.sbin/bhyve/pci_hda.h Sat Aug 6 15:38:25 2016 (r307280) @@ -42,7 +42,7 @@ struct hda_codec_class { char *name; - int (*init)(struct hda_codec_inst *hci, const char *opts); + int (*init)(struct hda_codec_inst *hci, const char *play, const char *rec, const char *opts); int (*reset)(struct hda_codec_inst *hci); int (*command)(struct hda_codec_inst *hci, uint32_t cmd_data); int (*notify)(struct hda_codec_inst *hci, uint8_t run, uint8_t stream, uint8_t dir);