diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c
index a56d3eab35dd..391f1f2e1af2 100644
--- a/drivers/net/xen-netback/xenbus.c
+++ b/drivers/net/xen-netback/xenbus.c
@@ -22,9 +22,25 @@
 #include <linux/vmalloc.h>
 #include <linux/rtnetlink.h>
 
+#define REQUIRE_PATH_LEN (256)
+
+struct backend_features {
+	unsigned int max_queues;
+	unsigned int split_evtchn:1;
+	unsigned int ctrl_ring:1;
+	unsigned int can_sg:1;
+	unsigned int gso_v4:1;
+	unsigned int gso_v6:1;
+	unsigned int mcast_ctrl:1;
+	unsigned int dyn_mcast_ctrl:1;
+	unsigned int ip_no_csum:1;
+	unsigned int ipv6_csum:1;
+};
+
 struct backend_info {
 	struct xenbus_device *dev;
 	struct xenvif *vif;
+	struct backend_features features;
 
 	/* This is the state that will be reflected in xenstore when any
 	 * active hotplug script completes.
@@ -48,6 +64,17 @@ static void xen_unregister_watchers(struct xenvif *vif);
 static void set_backend_state(struct backend_info *be,
 			      enum xenbus_state state);
 
+static int xenbus_read_feature(const char *dir, const char *node,
+			       unsigned int default_val)
+{
+	char reqnode[REQUIRE_PATH_LEN];
+	unsigned int val;
+
+	snprintf(reqnode, REQUIRE_PATH_LEN, "%s/require", dir);
+	val = xenbus_read_unsigned(reqnode, node, default_val);
+	return val;
+}
+
 #ifdef CONFIG_DEBUG_FS
 struct dentry *xen_netback_dbg_root = NULL;
 
@@ -280,6 +307,32 @@ static int netback_remove(struct xenbus_device *dev)
 	return 0;
 }
 
+static void netback_probe_features(struct xenbus_device *dev,
+				   struct backend_info *be)
+{
+	struct backend_features *ft = &be->features;
+
+	ft->can_sg = xenbus_read_feature(dev->nodename, "feature-sg", 1);
+	ft->gso_v4 = xenbus_read_feature(dev->nodename, "feature-gso-v4", 1);
+	ft->gso_v6 = xenbus_read_feature(dev->nodename, "feature-gso-v6", 1);
+	ft->gso_v6 = xenbus_read_feature(dev->nodename, "feature-gso-v6", 1);
+	ft->ipv6_csum = xenbus_read_feature(dev->nodename,
+					    "feature-ipv6-csum-offload", 1);
+	ft->ip_no_csum = xenbus_read_feature(dev->nodename,
+					    "feature-no-csum-offload", 0);
+	ft->mcast_ctrl = xenbus_read_feature(dev->nodename,
+					     "feature-multicast-control", 1);
+	ft->dyn_mcast_ctrl = xenbus_read_feature(dev->nodename,
+					"feature-dynamic-multicast-control", 1);
+	ft->split_evtchn = xenbus_read_feature(dev->nodename,
+					       "feature-split-event-channels",
+					       separate_tx_rx_irq);
+	ft->max_queues = xenbus_read_feature(dev->nodename,
+					     "multi-queue-max-queues",
+					     xenvif_max_queues);
+	ft->ctrl_ring = xenbus_read_feature(dev->nodename, "feature-ctrl-ring",
+					    1);
+}
 
 /**
  * Entry point to this code when a new device is created.  Allocate the basic
@@ -291,8 +344,8 @@ static int netback_probe(struct xenbus_device *dev,
 	const char *message;
 	struct xenbus_transaction xbt;
 	int err;
-	int sg;
 	const char *script;
+	struct backend_features *ft;
 	struct backend_info *be = kzalloc(sizeof(struct backend_info),
 					  GFP_KERNEL);
 	if (!be) {
@@ -309,7 +362,8 @@ static int netback_probe(struct xenbus_device *dev,
 	if (err)
 		goto fail;
 
-	sg = 1;
+	netback_probe_features(dev, be);
+	ft = &be->features;
 
 	do {
 		err = xenbus_transaction_start(&xbt);
@@ -318,21 +372,22 @@ static int netback_probe(struct xenbus_device *dev,
 			goto fail;
 		}
 
-		err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d", sg);
+		err = xenbus_printf(xbt, dev->nodename, "feature-sg", "%d",
+				    ft->can_sg);
 		if (err) {
 			message = "writing feature-sg";
 			goto abort_transaction;
 		}
 
 		err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv4",
-				    "%d", sg);
+				    "%d", ft->gso_v4);
 		if (err) {
 			message = "writing feature-gso-tcpv4";
 			goto abort_transaction;
 		}
 
 		err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv6",
-				    "%d", sg);
+				    "%d", ft->gso_v6);
 		if (err) {
 			message = "writing feature-gso-tcpv6";
 			goto abort_transaction;
@@ -341,12 +396,21 @@ static int netback_probe(struct xenbus_device *dev,
 		/* We support partial checksum setup for IPv6 packets */
 		err = xenbus_printf(xbt, dev->nodename,
 				    "feature-ipv6-csum-offload",
-				    "%d", 1);
+				    "%d", ft->ipv6_csum);
 		if (err) {
 			message = "writing feature-ipv6-csum-offload";
 			goto abort_transaction;
 		}
 
+		/* We support partial checksum setup for IPv4 packets */
+		err = xenbus_printf(xbt, dev->nodename,
+				    "feature-no-csum-offload",
+				    "%d", ft->ip_no_csum);
+		if (err) {
+			message = "writing feature-no-csum-offload";
+			goto abort_transaction;
+		}
+
 		/* We support rx-copy path. */
 		err = xenbus_printf(xbt, dev->nodename,
 				    "feature-rx-copy", "%d", 1);
@@ -368,7 +432,8 @@ static int netback_probe(struct xenbus_device *dev,
 
 		/* We support dynamic multicast-control. */
 		err = xenbus_printf(xbt, dev->nodename,
-				    "feature-multicast-control", "%d", 1);
+				    "feature-multicast-control", "%d",
+				    ft->mcast_ctrl);
 		if (err) {
 			message = "writing feature-multicast-control";
 			goto abort_transaction;
@@ -376,7 +441,7 @@ static int netback_probe(struct xenbus_device *dev,
 
 		err = xenbus_printf(xbt, dev->nodename,
 				    "feature-dynamic-multicast-control",
-				    "%d", 1);
+				    "%d", ft->dyn_mcast_ctrl);
 		if (err) {
 			message = "writing feature-dynamic-multicast-control";
 			goto abort_transaction;
@@ -396,19 +461,19 @@ static int netback_probe(struct xenbus_device *dev,
 	 */
 	err = xenbus_printf(XBT_NIL, dev->nodename,
 			    "feature-split-event-channels",
-			    "%u", separate_tx_rx_irq);
+			    "%u", ft->split_evtchn);
 	if (err)
 		pr_debug("Error writing feature-split-event-channels\n");
 
 	/* Multi-queue support: This is an optional feature. */
 	err = xenbus_printf(XBT_NIL, dev->nodename,
-			    "multi-queue-max-queues", "%u", xenvif_max_queues);
+			    "multi-queue-max-queues", "%u", ft->max_queues);
 	if (err)
 		pr_debug("Error writing multi-queue-max-queues\n");
 
 	err = xenbus_printf(XBT_NIL, dev->nodename,
 			    "feature-ctrl-ring",
-			    "%u", true);
+			    "%u", ft->ctrl_ring);
 	if (err)
 		pr_debug("Error writing feature-ctrl-ring\n");
 
@@ -904,6 +969,9 @@ static int connect_ctrl_ring(struct backend_info *be)
 	unsigned int evtchn;
 	int err;
 
+	if (!be->features.ctrl_ring)
+		goto done;
+
 	err = xenbus_scanf(XBT_NIL, dev->otherend,
 			   "ctrl-ring-ref", "%u", &val);
 	if (err < 0)
@@ -951,11 +1019,11 @@ static void connect(struct backend_info *be)
 	 */
 	requested_num_queues = xenbus_read_unsigned(dev->otherend,
 					"multi-queue-num-queues", 1);
-	if (requested_num_queues > xenvif_max_queues) {
+	if (requested_num_queues > be->features.max_queues) {
 		/* buggy or malicious guest */
 		xenbus_dev_fatal(dev, -EINVAL,
 				 "guest requested %u queues, exceeding the maximum of %u.",
-				 requested_num_queues, xenvif_max_queues);
+				 requested_num_queues, be->features.max_queues);
 		return;
 	}
 
@@ -1110,10 +1178,13 @@ static int connect_data_rings(struct backend_info *be,
 		goto err;
 	}
 
+	err = -EOPNOTSUPP;
 	/* Try split event channels first, then single event channel. */
-	err = xenbus_gather(XBT_NIL, xspath,
-			    "event-channel-tx", "%u", &tx_evtchn,
-			    "event-channel-rx", "%u", &rx_evtchn, NULL);
+	if (be->features.split_evtchn)
+		err = xenbus_gather(XBT_NIL, xspath,
+				    "event-channel-tx", "%u", &tx_evtchn,
+				    "event-channel-rx", "%u", &rx_evtchn, NULL);
+
 	if (err < 0) {
 		err = xenbus_scanf(XBT_NIL, xspath,
 				   "event-channel", "%u", &tx_evtchn);
@@ -1173,21 +1244,26 @@ static int read_xenbus_vif_flags(struct backend_info *be)
 		be->vif->stall_timeout = 0;
 	}
 
-	vif->can_sg = !!xenbus_read_unsigned(dev->otherend, "feature-sg", 0);
+	vif->can_sg = be->features.can_sg &&
+			!!xenbus_read_unsigned(dev->otherend, "feature-sg", 0);
 
 	vif->gso_mask = 0;
 
-	if (xenbus_read_unsigned(dev->otherend, "feature-gso-tcpv4", 0))
+	if (be->features.gso_v4 &&
+	    xenbus_read_unsigned(dev->otherend, "feature-gso-tcpv4", 0))
 		vif->gso_mask |= GSO_BIT(TCPV4);
 
-	if (xenbus_read_unsigned(dev->otherend, "feature-gso-tcpv6", 0))
+	if (be->features.gso_v6 &&
+	    xenbus_read_unsigned(dev->otherend, "feature-gso-tcpv6", 0))
 		vif->gso_mask |= GSO_BIT(TCPV6);
 
-	vif->ip_csum = !xenbus_read_unsigned(dev->otherend,
-					     "feature-no-csum-offload", 0);
+	vif->ip_csum = !be->features.ip_no_csum &&
+			!xenbus_read_unsigned(dev->otherend,
+					      "feature-no-csum-offload", 0);
 
-	vif->ipv6_csum = !!xenbus_read_unsigned(dev->otherend,
-						"feature-ipv6-csum-offload", 0);
+	vif->ipv6_csum = be->features.ipv6_csum &&
+			!!xenbus_read_unsigned(dev->otherend,
+					       "feature-ipv6-csum-offload", 0);
 
 	return 0;
 }
