Author: sephe
Date: Fri Oct 14 04:53:52 2016
New Revision: 307259
URL: https://svnweb.freebsd.org/changeset/base/307259

Log:
  MFC 306482,306483
  
  306482
      hyperv/hn: If synthetic parts are detached, don't touch them.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8065
  
  306483
      hyperv/hn: Fix detach and attach error handling.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D8066

Modified:
  stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
  stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h        Fri Oct 14 04:13:59 
2016        (r307258)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h        Fri Oct 14 04:53:52 
2016        (r307259)
@@ -253,6 +253,7 @@ struct hn_softc {
 #define HN_FLAG_CHIM_CONNECTED         0x0002
 #define HN_FLAG_HAS_RSSKEY             0x0004
 #define HN_FLAG_HAS_RSSIND             0x0008
+#define HN_FLAG_SYNTH_ATTACHED         0x0010
 
 #define HN_CAP_VLAN                    0x0001
 #define HN_CAP_MTU                     0x0002

Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Fri Oct 14 
04:13:59 2016        (r307258)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c     Fri Oct 14 
04:53:52 2016        (r307259)
@@ -354,6 +354,7 @@ static void hn_resume(struct hn_softc *)
 static void hn_rx_drain(struct vmbus_channel *);
 static void hn_tx_resume(struct hn_softc *, int);
 static void hn_tx_ring_qflush(struct hn_tx_ring *);
+static int netvsc_detach(device_t dev);
 
 static void hn_nvs_handle_notify(struct hn_softc *sc,
                const struct vmbus_chanpkt_hdr *pkt);
@@ -407,6 +408,9 @@ hn_rss_reconfig(struct hn_softc *sc)
 
        HN_LOCK_ASSERT(sc);
 
+       if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0)
+               return (ENXIO);
+
        /*
         * Disable RSS first.
         *
@@ -752,27 +756,28 @@ netvsc_attach(device_t dev)
 
        return (0);
 failed:
-       /* TODO: reuse netvsc_detach() */
-       hn_destroy_tx_data(sc);
-       if (ifp != NULL)
-               if_free(ifp);
+       if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED)
+               hn_synth_detach(sc);
+       netvsc_detach(dev);
        return (error);
 }
 
-/*
- * TODO: Use this for error handling on attach path.
- */
 static int
 netvsc_detach(device_t dev)
 {
        struct hn_softc *sc = device_get_softc(dev);
+       struct ifnet *ifp = sc->hn_ifp;
 
-       /* TODO: ether_ifdetach */
-
-       HN_LOCK(sc);
-       /* TODO: hn_stop */
-       hn_synth_detach(sc);
-       HN_UNLOCK(sc);
+       if (device_is_attached(dev)) {
+               HN_LOCK(sc);
+               if (sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) {
+                       if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+                               hn_stop(sc);
+                       hn_synth_detach(sc);
+               }
+               HN_UNLOCK(sc);
+               ether_ifdetach(ifp);
+       }
 
        ifmedia_removeall(&sc->hn_media);
        hn_destroy_rx_data(sc);
@@ -781,10 +786,12 @@ netvsc_detach(device_t dev)
        if (sc->hn_tx_taskq != hn_tx_taskq)
                taskqueue_free(sc->hn_tx_taskq);
 
-       vmbus_xact_ctx_destroy(sc->hn_xact);
-       HN_LOCK_DESTROY(sc);
+       if (sc->hn_xact != NULL)
+               vmbus_xact_ctx_destroy(sc->hn_xact);
+
+       if_free(ifp);
 
-       /* TODO: if_free */
+       HN_LOCK_DESTROY(sc);
        return (0);
 }
 
@@ -1638,6 +1645,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
 
                HN_LOCK(sc);
 
+               if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) {
+                       HN_UNLOCK(sc);
+                       break;
+               }
+
                if ((sc->hn_caps & HN_CAP_MTU) == 0) {
                        /* Can't change MTU */
                        HN_UNLOCK(sc);
@@ -1691,6 +1703,11 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, 
        case SIOCSIFFLAGS:
                HN_LOCK(sc);
 
+               if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) {
+                       HN_UNLOCK(sc);
+                       break;
+               }
+
                if (ifp->if_flags & IFF_UP) {
                        /*
                         * If only the state of the PROMISC flag changed,
@@ -1802,6 +1819,9 @@ hn_stop(struct hn_softc *sc)
 
        HN_LOCK_ASSERT(sc);
 
+       KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED,
+           ("synthetic parts were not attached"));
+
        /* Clear RUNNING bit _before_ hn_suspend() */
        atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_RUNNING);
        hn_suspend(sc);
@@ -1878,6 +1898,9 @@ hn_init_locked(struct hn_softc *sc)
 
        HN_LOCK_ASSERT(sc);
 
+       if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0)
+               return;
+
        if (ifp->if_drv_flags & IFF_DRV_RUNNING)
                return;
 
@@ -3397,6 +3420,9 @@ hn_synth_attach(struct hn_softc *sc, int
        int error, nsubch, nchan, i;
        uint32_t old_caps;
 
+       KASSERT((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0,
+           ("synthetic parts were attached"));
+
        /* Save capabilities for later verification. */
        old_caps = sc->hn_caps;
        sc->hn_caps = 0;
@@ -3509,6 +3535,8 @@ back:
        error = hn_attach_subchans(sc);
        if (error)
                return (error);
+
+       sc->hn_flags |= HN_FLAG_SYNTH_ATTACHED;
        return (0);
 }
 
@@ -3522,6 +3550,9 @@ hn_synth_detach(struct hn_softc *sc)
 {
        HN_LOCK_ASSERT(sc);
 
+       KASSERT(sc->hn_flags & HN_FLAG_SYNTH_ATTACHED,
+           ("synthetic parts were not attached"));
+
        /* Detach the RNDIS first. */
        hn_rndis_detach(sc);
 
@@ -3530,6 +3561,8 @@ hn_synth_detach(struct hn_softc *sc)
 
        /* Detach all of the channels. */
        hn_detach_allchans(sc);
+
+       sc->hn_flags &= ~HN_FLAG_SYNTH_ATTACHED;
 }
 
 static void
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to