Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Oct 2016 07:50:09 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r307025 - in stable/10/sys/dev/hyperv: include vmbus
Message-ID:  <201610110750.u9B7o90c015436@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Tue Oct 11 07:50:09 2016
New Revision: 307025
URL: https://svnweb.freebsd.org/changeset/base/307025

Log:
  MFC 302723,302726,302731
  
  302723
      hyperv: All Hypercall parameters have same alignment requirement.
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7086
  
  302726
      hyperv: Signal event input parameter is shared w/ MNF
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7087
  
  302731
      hyperv/vmbus: Reorganize MNF event sending.
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7088

Modified:
  stable/10/sys/dev/hyperv/include/hyperv.h
  stable/10/sys/dev/hyperv/vmbus/hv_channel.c
  stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  stable/10/sys/dev/hyperv/vmbus/hyperv.c
  stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h
  stable/10/sys/dev/hyperv/vmbus/hyperv_var.h
  stable/10/sys/dev/hyperv/vmbus/vmbus.c
  stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h
  stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- stable/10/sys/dev/hyperv/include/hyperv.h	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/include/hyperv.h	Tue Oct 11 07:50:09 2016	(r307025)
@@ -523,12 +523,13 @@ typedef struct hv_vmbus_channel {
 	hv_vmbus_channel_state		state;
 	uint32_t			ch_flags;	/* VMBUS_CHAN_FLAG_ */
 	uint32_t			ch_id;		/* channel id */
+
 	/*
 	 * These are based on the offer_msg.monitor_id.
 	 * Save it here for easy access.
 	 */
-	uint8_t				monitor_group;
-	uint8_t				monitor_bit;
+	int				ch_montrig_idx;	/* MNF trig index */
+	uint32_t			ch_montrig_mask;/* MNF trig mask */
 
 	uint32_t			ring_buffer_gpadl_handle;
 	/*
@@ -551,8 +552,8 @@ typedef struct hv_vmbus_channel {
 	hv_vmbus_pfn_channel_callback	on_channel_callback;
 	void*				channel_callback_context;
 
-	struct hypercall_sigevt_in	*ch_sigevt;
-	struct hyperv_dma		ch_sigevt_dma;
+	struct hyperv_mon_param		*ch_monprm;
+	struct hyperv_dma		ch_monprm_dma;
 
 	/*
 	 * From Win8, this field specifies the target virtual process

Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel.c	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel.c	Tue Oct 11 07:50:09 2016	(r307025)
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/hyperv/vmbus/vmbus_reg.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
 
-static void 	vmbus_channel_set_event(hv_vmbus_channel* channel);
+static void 	vmbus_chan_send_event(hv_vmbus_channel* channel);
 static void	vmbus_chan_update_evtflagcnt(struct vmbus_softc *,
 		    const struct hv_vmbus_channel *);
 static void	vmbus_chan_task(void *, int);
@@ -60,7 +60,7 @@ static void	vmbus_chan_task_nobatch(void
  *  @brief Trigger an event notification on the specified channel
  */
 static void
-vmbus_channel_set_event(hv_vmbus_channel *channel)
+vmbus_chan_send_event(hv_vmbus_channel *channel)
 {
 	struct vmbus_softc *sc = channel->vmbus_sc;
 	uint32_t chanid = channel->ch_id;
@@ -69,16 +69,12 @@ vmbus_channel_set_event(hv_vmbus_channel
 	    1UL << (chanid & VMBUS_EVTFLAG_MASK));
 
 	if (channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) {
-		hv_vmbus_monitor_page *monitor_page;
-
-		monitor_page = sc->vmbus_mnf2;
-		synch_set_bit(channel->monitor_bit,
-			(uint32_t *)&monitor_page->
-				trigger_group[channel->monitor_group].u.pending);
+		atomic_set_int(
+		&sc->vmbus_mnf2->mnf_trigs[channel->ch_montrig_idx].mt_pending,
+		channel->ch_montrig_mask);
 	} else {
-		hypercall_signal_event(channel->ch_sigevt_dma.hv_paddr);
+		hypercall_signal_event(channel->ch_monprm_dma.hv_paddr);
 	}
-
 }
 
 static int
@@ -622,9 +618,8 @@ hv_vmbus_channel_send_packet(
 	    &need_sig);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && need_sig) {
-		vmbus_channel_set_event(channel);
-	}
+	if (ret == 0 && need_sig)
+		vmbus_chan_send_event(channel);
 
 	return (ret);
 }
@@ -690,9 +685,8 @@ hv_vmbus_channel_send_packet_pagebuffer(
 	    &need_sig);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && need_sig) {
-		vmbus_channel_set_event(channel);
-	}
+	if (ret == 0 && need_sig)
+		vmbus_chan_send_event(channel);
 
 	return (ret);
 }
@@ -766,9 +760,8 @@ hv_vmbus_channel_send_packet_multipagebu
 	    &need_sig);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && need_sig) {
-	    vmbus_channel_set_event(channel);
-	}
+	if (ret == 0 && need_sig)
+		vmbus_chan_send_event(channel);
 
 	return (ret);
 }

Modified: stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/hv_channel_mgmt.c	Tue Oct 11 07:50:09 2016	(r307025)
@@ -299,23 +299,29 @@ vmbus_channel_on_offer_internal(struct v
 	if (offer->monitor_allocated)
 		new_channel->ch_flags |= VMBUS_CHAN_FLAG_HASMNF;
 
-	new_channel->ch_sigevt = hyperv_dmamem_alloc(
+	new_channel->ch_monprm = hyperv_dmamem_alloc(
 	    bus_get_dma_tag(sc->vmbus_dev),
-	    HYPERCALL_SIGEVTIN_ALIGN, 0, sizeof(struct hypercall_sigevt_in),
-	    &new_channel->ch_sigevt_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
-	if (new_channel->ch_sigevt == NULL) {
-		device_printf(sc->vmbus_dev, "sigevt alloc failed\n");
+	    HYPERCALL_PARAM_ALIGN, 0, sizeof(struct hyperv_mon_param),
+	    &new_channel->ch_monprm_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
+	if (new_channel->ch_monprm == NULL) {
+		device_printf(sc->vmbus_dev, "monprm alloc failed\n");
 		/* XXX */
 		mtx_destroy(&new_channel->sc_lock);
 		free(new_channel, M_DEVBUF);
 		return;
 	}
-	new_channel->ch_sigevt->hc_connid = VMBUS_CONNID_EVENT;
+	new_channel->ch_monprm->mp_connid = VMBUS_CONNID_EVENT;
 	if (sc->vmbus_version != VMBUS_VERSION_WS2008)
-		new_channel->ch_sigevt->hc_connid = offer->connection_id;
+		new_channel->ch_monprm->mp_connid = offer->connection_id;
 
-	new_channel->monitor_group = (uint8_t) offer->monitor_id / 32;
-	new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32;
+	if (new_channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) {
+		new_channel->ch_montrig_idx =
+		    offer->monitor_id / VMBUS_MONTRIG_LEN;
+		if (new_channel->ch_montrig_idx >= VMBUS_MONTRIGS_MAX)
+			panic("invalid monitor id %u", offer->monitor_id);
+		new_channel->ch_montrig_mask =
+		    1 << (offer->monitor_id % VMBUS_MONTRIG_LEN);
+	}
 
 	/* Select default cpu for this channel. */
 	vmbus_channel_select_defcpu(new_channel);

Modified: stable/10/sys/dev/hyperv/vmbus/hyperv.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv.c	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv.c	Tue Oct 11 07:50:09 2016	(r307025)
@@ -109,10 +109,10 @@ hypercall_post_message(bus_addr_t msg_pa
 }
 
 uint64_t
-hypercall_signal_event(bus_addr_t sigevt_paddr)
+hypercall_signal_event(bus_addr_t monprm_paddr)
 {
 	return hypercall_md(hypercall_context.hc_addr,
-	    HYPERCALL_SIGNAL_EVENT, sigevt_paddr, 0);
+	    HYPERCALL_SIGNAL_EVENT, monprm_paddr, 0);
 }
 
 int

Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv_reg.h	Tue Oct 11 07:50:09 2016	(r307025)
@@ -133,6 +133,15 @@
 #define CPUID_LEAF_HV_HWFEATURES	0x40000006
 
 /*
+ * Hyper-V Monitor Notification Facility
+ */
+struct hyperv_mon_param {
+	uint32_t	mp_connid;
+	uint16_t	mp_evtflag_ofs;
+	uint16_t	mp_rsvd;
+} __packed;
+
+/*
  * Hyper-V message types
  */
 #define HYPERV_MSGTYPE_NONE		0
@@ -153,13 +162,22 @@
 /*
  * Hypercall input parameters
  */
+#define HYPERCALL_PARAM_ALIGN		8
+#if 0
+/*
+ * XXX
+ * <<Hypervisor Top Level Functional Specification 4.0b>> requires
+ * input parameters size to be multiple of 8, however, many post
+ * message input parameters do _not_ meet this requirement.
+ */
+#define HYPERCALL_PARAM_SIZE_ALIGN	8
+#endif
 
 /*
  * HYPERCALL_POST_MESSAGE
  */
 #define HYPERCALL_POSTMSGIN_DSIZE_MAX	240
 #define HYPERCALL_POSTMSGIN_SIZE	256
-#define HYPERCALL_POSTMSGIN_ALIGN	8
 
 struct hypercall_postmsg_in {
 	uint32_t	hc_connid;
@@ -172,13 +190,8 @@ CTASSERT(sizeof(struct hypercall_postmsg
 
 /*
  * HYPERCALL_SIGNAL_EVENT
+ *
+ * struct hyperv_mon_param.
  */
-#define HYPERCALL_SIGEVTIN_ALIGN	8
-
-struct hypercall_sigevt_in {
-	uint32_t	hc_connid;
-	uint16_t	hc_evtflag_ofs;
-	uint16_t	hc_rsvd;
-} __packed;
 
 #endif	/* !_HYPERV_REG_H_ */

Modified: stable/10/sys/dev/hyperv/vmbus/hyperv_var.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/hyperv_var.h	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/hyperv_var.h	Tue Oct 11 07:50:09 2016	(r307025)
@@ -41,6 +41,6 @@ extern u_int	hyperv_features;
 extern u_int	hyperv_recommends;
 
 uint64_t	hypercall_post_message(bus_addr_t msg_paddr);
-uint64_t	hypercall_signal_event(bus_addr_t sigevt_paddr);
+uint64_t	hypercall_signal_event(bus_addr_t monprm_paddr);
 
 #endif	/* !_HYPERV_VAR_H_ */

Modified: stable/10/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus.c	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus.c	Tue Oct 11 07:50:09 2016	(r307025)
@@ -130,7 +130,7 @@ vmbus_msghc_alloc(bus_dma_tag_t parent_d
 	mh = malloc(sizeof(*mh), M_DEVBUF, M_WAITOK | M_ZERO);
 
 	mh->mh_inprm = hyperv_dmamem_alloc(parent_dtag,
-	    HYPERCALL_POSTMSGIN_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE,
+	    HYPERCALL_PARAM_ALIGN, 0, HYPERCALL_POSTMSGIN_SIZE,
 	    &mh->mh_inprm_dma, BUS_DMA_WAITOK);
 	if (mh->mh_inprm == NULL) {
 		free(mh, M_DEVBUF);
@@ -835,7 +835,8 @@ vmbus_dma_alloc(struct vmbus_softc *sc)
 		return ENOMEM;
 
 	sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
-	    PAGE_SIZE, &sc->vmbus_mnf2_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
+	    sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
+	    BUS_DMA_WAITOK | BUS_DMA_ZERO);
 	if (sc->vmbus_mnf2 == NULL)
 		return ENOMEM;
 

Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_reg.h	Tue Oct 11 07:50:09 2016	(r307025)
@@ -72,6 +72,34 @@ struct vmbus_evtflags {
 CTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE);
 
 /*
+ * Hyper-V Monitor Notification Facility
+ */
+
+struct vmbus_mon_trig {
+	uint32_t	mt_pending;
+	uint32_t	mt_armed;
+} __packed;
+
+#define VMBUS_MONTRIGS_MAX	4
+#define VMBUS_MONTRIG_LEN	32
+
+struct vmbus_mnf {
+	uint32_t	mnf_state;
+	uint32_t	mnf_rsvd1;
+
+	struct vmbus_mon_trig mnf_trigs[VMBUS_MONTRIGS_MAX];
+	uint8_t		mnf_rsvd2[536];
+
+	uint16_t	mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
+	uint8_t		mnf_rsvd3[256];
+
+	struct hyperv_mon_param
+			mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
+	uint8_t		mnf_rsvd4[1984];
+} __packed;
+CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE);
+
+/*
  * Channel
  */
 

Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_var.h	Tue Oct 11 07:44:26 2016	(r307024)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_var.h	Tue Oct 11 07:50:09 2016	(r307025)
@@ -70,7 +70,7 @@ struct vmbus_softc {
 	void			(*vmbus_event_proc)(struct vmbus_softc *, int);
 	u_long			*vmbus_tx_evtflags;
 						/* event flags to host */
-	void			*vmbus_mnf2;	/* monitored by host */
+	struct vmbus_mnf	*vmbus_mnf2;	/* monitored by host */
 
 	u_long			*vmbus_rx_evtflags;
 						/* compat evtflgs from host */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610110750.u9B7o90c015436>