[pve-devel] [PATCH kernel 04/17] drop already applied patches

Fabian Grünbichler f.gruenbichler at proxmox.com
Mon Mar 6 10:31:25 CET 2017


these were all cherry-picks on top of the previous 4.4
kernel which are no longer needed.

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
 Makefile                                           |  11 -
 ...rectly-reset-dest_map-vector-when-restori.patch |  68 --
 ...ndard-ACS-vs-device-specific-ACS-enabling.patch | 110 ---
 ...Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch | 123 ----
 ...reeing-skb-too-early-for-IPV6_RECVPKTINFO.patch |  58 --
 ...ck-the-IB-LL-address-into-the-hard-header.patch | 365 ----------
 ..._mark_head_lost-to-check-skb-len-before-f.patch |  77 ---
 mei_bus-whitelist-watchdog-client.patch            |  74 --
 mei_drop-watchdog-code.patch                       | 754 ---------------------
 watchdog_implement-mei-iamt-driver.patch           | 514 --------------
 10 files changed, 2154 deletions(-)
 delete mode 100644 0001-kvm-x86-correctly-reset-dest_map-vector-when-restori.patch
 delete mode 100644 981-1-PCI-Reverse-standard-ACS-vs-device-specific-ACS-enabling.patch
 delete mode 100644 981-2-PCI-Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch
 delete mode 100644 CVE-2017-6074-dccp-fix-freeing-skb-too-early-for-IPV6_RECVPKTINFO.patch
 delete mode 100644 IB-ipoib-move-back-the-IB-LL-address-into-the-hard-header.patch
 delete mode 100644 bug-950-tcp-fix-tcp_mark_head_lost-to-check-skb-len-before-f.patch
 delete mode 100644 mei_bus-whitelist-watchdog-client.patch
 delete mode 100644 mei_drop-watchdog-code.patch
 delete mode 100644 watchdog_implement-mei-iamt-driver.patch

diff --git a/Makefile b/Makefile
index 0712745..2b6c819 100644
--- a/Makefile
+++ b/Makefile
@@ -254,20 +254,9 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNELSRCTAR}
 	#cd ${KERNEL_SRC}; patch -p1 <../add-empty-ndo_poll_controller-to-veth.patch
 	cd ${KERNEL_SRC}; patch -p1 <../override_for_missing_acs_capabilities.patch
 	#cd ${KERNEL_SRC}; patch -p1 <../vhost-net-extend-device-allocation-to-vmalloc.patch
-	cd ${KERNEL_SRC}; patch -p1 <../bug-950-tcp-fix-tcp_mark_head_lost-to-check-skb-len-before-f.patch
-	cd ${KERNEL_SRC}; patch -p1 < ../981-1-PCI-Reverse-standard-ACS-vs-device-specific-ACS-enabling.patch
-	cd ${KERNEL_SRC}; patch -p1 < ../981-2-PCI-Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch
 	cd ${KERNEL_SRC}; patch -p1 < ../kvm-dynamic-halt-polling-disable-default.patch
-	# avoid iAMT watchdog problems (not a real watchdog, because does not reset the host)
-	cd ${KERNEL_SRC}; patch -p1 < ../watchdog_implement-mei-iamt-driver.patch
-	cd ${KERNEL_SRC}; patch -p1 < ../mei_drop-watchdog-code.patch
-	cd ${KERNEL_SRC}; patch -p1 < ../mei_bus-whitelist-watchdog-client.patch
-	# IPoIB performance regression fix
-	cd ${KERNEL_SRC}; patch -p1 < ../IB-ipoib-move-back-the-IB-LL-address-into-the-hard-header.patch
 	cd ${KERNEL_SRC}; patch -p1 < ../cgroup-cpuset-add-cpuset.remap_cpus.patch
-	cd ${KERNEL_SRC}; patch -p1 < ../0001-kvm-x86-correctly-reset-dest_map-vector-when-restori.patch
 	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-2596-kvm-page-reference-leakage-in-handle_vmon.patch
-	cd ${KERNEL_SRC}; patch -p1 < ../CVE-2017-6074-dccp-fix-freeing-skb-too-early-for-IPV6_RECVPKTINFO.patch
 	cd ${KERNEL_SRC}; patch -p1 < ../Revert-intel_idle-Add-CPU-model-54-Atom-N2000-series.patch
 	sed -i ${KERNEL_SRC}/Makefile -e 's/^EXTRAVERSION.*$$/EXTRAVERSION=${EXTRAVERSION}/'
 	touch $@
diff --git a/0001-kvm-x86-correctly-reset-dest_map-vector-when-restori.patch b/0001-kvm-x86-correctly-reset-dest_map-vector-when-restori.patch
deleted file mode 100644
index da9f4f8..0000000
--- a/0001-kvm-x86-correctly-reset-dest_map-vector-when-restori.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-From b0eaf4506f5f95d15d6731d72c0ddf4a2179eefa Mon Sep 17 00:00:00 2001
-From: Paolo Bonzini <pbonzini at redhat.com>
-Date: Wed, 14 Sep 2016 23:39:12 +0200
-Subject: [PATCH] kvm: x86: correctly reset dest_map->vector when restoring
- LAPIC state
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-When userspace sends KVM_SET_LAPIC, KVM schedules a check between
-the vCPU's IRR and ISR and the IOAPIC redirection table, in order
-to re-establish the IOAPIC's dest_map (the list of CPUs servicing
-the real-time clock interrupt with the corresponding vectors).
-
-However, __rtc_irq_eoi_tracking_restore_one was forgetting to
-set dest_map->vectors.  Because of this, the IOAPIC did not process
-the real-time clock interrupt EOI, ioapic->rtc_status.pending_eoi
-got stuck at a non-zero value, and further RTC interrupts were
-reported to userspace as coalesced.
-
-Fixes: 9e4aabe2bb3454c83dac8139cf9974503ee044db
-Fixes: 4d99ba898dd0c521ca6cdfdde55c9b58aea3cb3d
-Cc: stable at vger.kernel.org
-Cc: Joerg Roedel <jroedel at suse.de>
-Cc: David Gilbert <dgilbert at redhat.com>
-Reviewed-by: Radim Krčmář <rkrcmar at redhat.com>
-Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
-Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
----
- arch/x86/kvm/ioapic.c | 8 +++++---
- 1 file changed, 5 insertions(+), 3 deletions(-)
-
-diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
-index 5f42d03..c7220ba 100644
---- a/arch/x86/kvm/ioapic.c
-+++ b/arch/x86/kvm/ioapic.c
-@@ -109,6 +109,7 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
- {
- 	bool new_val, old_val;
- 	struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
-+	struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
- 	union kvm_ioapic_redirect_entry *e;
- 
- 	e = &ioapic->redirtbl[RTC_GSI];
-@@ -117,16 +118,17 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
- 		return;
- 
- 	new_val = kvm_apic_pending_eoi(vcpu, e->fields.vector);
--	old_val = test_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map);
-+	old_val = test_bit(vcpu->vcpu_id, dest_map->map);
- 
- 	if (new_val == old_val)
- 		return;
- 
- 	if (new_val) {
--		__set_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map);
-+		__set_bit(vcpu->vcpu_id, dest_map->map);
-+		dest_map->vectors[vcpu->vcpu_id] = e->fields.vector;
- 		ioapic->rtc_status.pending_eoi++;
- 	} else {
--		__clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map.map);
-+		__clear_bit(vcpu->vcpu_id, dest_map->map);
- 		ioapic->rtc_status.pending_eoi--;
- 		rtc_status_pending_eoi_check_valid(ioapic);
- 	}
--- 
-2.1.4
-
diff --git a/981-1-PCI-Reverse-standard-ACS-vs-device-specific-ACS-enabling.patch b/981-1-PCI-Reverse-standard-ACS-vs-device-specific-ACS-enabling.patch
deleted file mode 100644
index 8543bc3..0000000
--- a/981-1-PCI-Reverse-standard-ACS-vs-device-specific-ACS-enabling.patch
+++ /dev/null
@@ -1,110 +0,0 @@
-From: Alex Williamson <alex.williamson at redhat.com>
-Subject: [PATCH 1/2] PCI: Reverse standard ACS vs device specific ACS enabling
-
-The original thought was that if a device implemented ACS, then surely
-we want to use that... well, it turns out that devices can make an ACS
-capability so broken that we still need to fall back to quirks.
-Reverse the order of ACS enabling to give quirks first shot at it.
-
-Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
----
- drivers/pci/pci.c    |   10 ++++------
- drivers/pci/quirks.c |    6 ++++--
- include/linux/pci.h  |    7 +++++--
- 3 files changed, 13 insertions(+), 10 deletions(-)
-
-diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
-index 25e0327..c98c4e2 100644
---- a/drivers/pci/pci.c
-+++ b/drivers/pci/pci.c
-@@ -2548,7 +2548,7 @@ void pci_request_acs(void)
-  * pci_std_enable_acs - enable ACS on devices using standard ACS capabilites
-  * @dev: the PCI device
-  */
--static int pci_std_enable_acs(struct pci_dev *dev)
-+static void pci_std_enable_acs(struct pci_dev *dev)
- {
- 	int pos;
- 	u16 cap;
-@@ -2556,7 +2556,7 @@ static int pci_std_enable_acs(struct pci_dev *dev)
- 
- 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
- 	if (!pos)
--		return -ENODEV;
-+		return;
- 
- 	pci_read_config_word(dev, pos + PCI_ACS_CAP, &cap);
- 	pci_read_config_word(dev, pos + PCI_ACS_CTRL, &ctrl);
-@@ -2574,8 +2574,6 @@ static int pci_std_enable_acs(struct pci_dev *dev)
- 	ctrl |= (cap & PCI_ACS_UF);
- 
- 	pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
--
--	return 0;
- }
- 
- /**
-@@ -2585,10 +2585,10 @@ void pci_enable_acs(struct pci_dev *dev)
- 	if (!pci_acs_enable)
- 		return;
- 
--	if (!pci_std_enable_acs(dev))
-+	if (!pci_dev_specific_enable_acs(dev))
- 		return;
- 
--	pci_dev_specific_enable_acs(dev);
-+	pci_std_enable_acs(dev);
- }
- 
- static bool pci_acs_flags_enabled(struct pci_dev *pdev, u16 acs_flags)
-diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
-index 8e67802..701fad6 100644
---- a/drivers/pci/quirks.c
-+++ b/drivers/pci/quirks.c
-@@ -4224,7 +4224,7 @@ static const struct pci_dev_enable_acs {
- 	{ 0 }
- };
- 
--void pci_dev_specific_enable_acs(struct pci_dev *dev)
-+int pci_dev_specific_enable_acs(struct pci_dev *dev)
- {
- 	const struct pci_dev_enable_acs *i;
- 	int ret;
-@@ -4236,9 +4236,11 @@ void pci_dev_specific_enable_acs(struct pci_dev *dev)
- 		     i->device == (u16)PCI_ANY_ID)) {
- 			ret = i->enable_acs(dev);
- 			if (ret >= 0)
--				return;
-+				return ret;
- 		}
- 	}
-+
-+	return -ENOTTY;
- }
- 
- /*
-diff --git a/include/linux/pci.h b/include/linux/pci.h
-index 004b813..aaec79a 100644
---- a/include/linux/pci.h
-+++ b/include/linux/pci.h
-@@ -1657,7 +1657,7 @@ enum pci_fixup_pass {
- #ifdef CONFIG_PCI_QUIRKS
- void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
- int pci_dev_specific_acs_enabled(struct pci_dev *dev, u16 acs_flags);
--void pci_dev_specific_enable_acs(struct pci_dev *dev);
-+int pci_dev_specific_enable_acs(struct pci_dev *dev);
- #else
- static inline void pci_fixup_device(enum pci_fixup_pass pass,
- 				    struct pci_dev *dev) { }
-@@ -1666,7 +1666,10 @@ static inline int pci_dev_specific_acs_enabled(struct pci_dev *dev,
- {
- 	return -ENOTTY;
- }
--static inline void pci_dev_specific_enable_acs(struct pci_dev *dev) { }
-+static inline int pci_dev_specific_enable_acs(struct pci_dev *dev)
-+{
-+	return -ENOTTY;
-+}
- #endif
- 
- void __iomem *pcim_iomap(struct pci_dev *pdev, int bar, unsigned long maxlen);
diff --git a/981-2-PCI-Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch b/981-2-PCI-Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch
deleted file mode 100644
index 9c3dd24..0000000
--- a/981-2-PCI-Quirk-PCH-root-port-ACS-for-Sunrise-Point.patch
+++ /dev/null
@@ -1,123 +0,0 @@
-From: Alex Williamson <alex.williamson at redhat.com>
-Subject: [PATCH 2/2] PCI: Quirk PCH root port ACS for Sunrise Point
-
-As noted in the comments, these root ports attempted to implement ACS
-but used dwords for the capability and control registers, putting the
-control register at the wrong offset.  We use quirks to enable and
-test ACS for these devices, which match the standard functions modulo
-the broken control register offset.
-
-Signed-off-by: Alex Williamson <alex.williamson at redhat.com>
----
- drivers/pci/quirks.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 78 insertions(+)
-
-diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
-index 701fad6..d6606e4 100644
---- a/drivers/pci/quirks.c
-+++ b/drivers/pci/quirks.c
-@@ -3992,6 +3992,55 @@ static int pci_quirk_intel_pch_acs(struct pci_dev *dev, u16 acs_flags)
- 	return acs_flags & ~flags ? 0 : 1;
- }
- 
-+/*
-+ * Sunrise Point PCH root ports implement ACS, but unfortunately as shown in
-+ * the datasheet (Intel 100 Series Chipset Family PCH Datasheet, Vol. 2,
-+ * 12.1.46, 12.1.47)[1] this chipset uses dwords for the ACS capability and
-+ * control registers whereas the PCIe spec packs them into words (Rev 3.0,
-+ * 7.16 ACS Extended Capability).  The bit definitions are correct, but the
-+ * control register is at offset 8 instead of 6 and we should probably use
-+ * dword accesses to them.  This applies to the following PCI Device IDs, as
-+ * found in volume 1 of the datasheet[2]:
-+ *
-+ * 0xa110-0xa11f Sunrise Point-H PCI Express Root Port #{0-16}
-+ * 0xa167-0xa16a Sunrise Point-H PCI Express Root Port #{17-20}
-+ *
-+ * NB. This doesn't fix what lspci shows.
-+ *
-+ * [1] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-2.html
-+ * [2] http://www.intel.com/content/www/us/en/chipsets/100-series-chipset-datasheet-vol-1.html
-+ */
-+static bool pci_quirk_intel_spt_pch_acs_match(struct pci_dev *dev)
-+{
-+	return pci_is_pcie(dev) &&
-+		pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT &&
-+		((dev->device & ~0xf) == 0xa110 ||
-+		 (dev->device >= 0xa167 && dev->device <= 0xa16a));
-+}
-+
-+#define INTEL_SPT_ACS_CTRL (PCI_ACS_CAP + 4)
-+
-+static int pci_quirk_intel_spt_pch_acs(struct pci_dev *dev, u16 acs_flags)
-+{
-+	int pos;
-+	u32 cap, ctrl;
-+
-+	if (!pci_quirk_intel_spt_pch_acs_match(dev))
-+		return -ENOTTY;
-+
-+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
-+	if (!pos)
-+		return -ENOTTY;
-+
-+	/* see pci_acs_flags_enabled() */
-+	pci_read_config_dword(dev, pos + PCI_ACS_CAP, &cap);
-+	acs_flags &= (cap | PCI_ACS_EC);
-+
-+	pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl);
-+
-+	return acs_flags & ~ctrl ? 0 : 1;
-+}
-+
- static int pci_quirk_mf_endpoint_acs(struct pci_dev *dev, u16 acs_flags)
- {
- 	/*
-@@ -4024,6 +4073,7 @@ static const struct pci_dev_acs_enabled {
- 	{ PCI_VENDOR_ID_INTEL, 0x15b8, pci_quirk_mf_endpoint_acs },
- 	/* Intel PCH root ports */
- 	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_pch_acs },
-+	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_intel_spt_pch_acs },
- 	{ 0x19a2, 0x710, pci_quirk_mf_endpoint_acs }, /* Emulex BE3-R */
- 	{ 0x10df, 0x720, pci_quirk_mf_endpoint_acs }, /* Emulex Skyhawk-R */
- 	/* Cavium ThunderX */
-@@ -4159,12 +4209,40 @@ static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev)
- 	return 0;
- }
- 
-+static int pci_quirk_enable_intel_spt_pch_acs(struct pci_dev *dev)
-+{
-+	int pos;
-+	u32 cap, ctrl;
-+
-+	if (!pci_quirk_intel_spt_pch_acs_match(dev))
-+		return -ENOTTY;
-+
-+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS);
-+	if (!pos)
-+		return -ENOTTY;
-+
-+	pci_read_config_dword(dev, pos + PCI_ACS_CAP, &cap);
-+	pci_read_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, &ctrl);
-+
-+	ctrl |= (cap & PCI_ACS_SV);
-+	ctrl |= (cap & PCI_ACS_RR);
-+	ctrl |= (cap & PCI_ACS_CR);
-+	ctrl |= (cap & PCI_ACS_UF);
-+
-+	pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl);
-+
-+	dev_info(&dev->dev, "Intel SPT PCH root port ACS workaround enabled\n");
-+
-+	return 0;
-+}
-+
- static const struct pci_dev_enable_acs {
- 	u16 vendor;
- 	u16 device;
- 	int (*enable_acs)(struct pci_dev *dev);
- } pci_dev_enable_acs[] = {
- 	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_pch_acs },
-+	{ PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_quirk_enable_intel_spt_pch_acs },
- 	{ 0 }
- };
- 
diff --git a/CVE-2017-6074-dccp-fix-freeing-skb-too-early-for-IPV6_RECVPKTINFO.patch b/CVE-2017-6074-dccp-fix-freeing-skb-too-early-for-IPV6_RECVPKTINFO.patch
deleted file mode 100644
index 202aa59..0000000
--- a/CVE-2017-6074-dccp-fix-freeing-skb-too-early-for-IPV6_RECVPKTINFO.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From 4feb04ade2a559e0e76a0215d259c5673e5b1cbd Mon Sep 17 00:00:00 2001
-From: Andrey Konovalov <andreyknvl at google.com>
-Date: Thu, 16 Feb 2017 17:22:46 +0100
-Subject: [PATCH] dccp: fix freeing skb too early for IPV6_RECVPKTINFO
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-In the current DCCP implementation an skb for a DCCP_PKT_REQUEST packet
-is forcibly freed via __kfree_skb in dccp_rcv_state_process if
-dccp_v6_conn_request successfully returns.
-
-However, if IPV6_RECVPKTINFO is set on a socket, the address of the skb
-is saved to ireq->pktopts and the ref count for skb is incremented in
-dccp_v6_conn_request, so skb is still in use. Nevertheless, it gets freed
-in dccp_rcv_state_process.
-
-Fix by calling consume_skb instead of doing goto discard and therefore
-calling __kfree_skb.
-
-Similar fixes for TCP:
-
-fb7e2399ec17f1004c0e0ccfd17439f8759ede01 [TCP]: skb is unexpectedly freed.
-0aea76d35c9651d55bbaf746e7914e5f9ae5a25d tcp: SYN packets are now
-simply consumed
-
-Signed-off-by: Andrey Konovalov <andreyknvl at google.com>
-Acked-by: Eric Dumazet <edumazet at google.com>
-Signed-off-by: David S. Miller <davem at davemloft.net>
-
-CVE-2017-6074
-BugLink: http://bugs.launchpad.net/bugs/1665935
-
-(cherry-picked from 5edabca9d4cff7f1f2b68f0bac55ef99d9798ba4 davem)
-Signed-off-by: Stefan Bader <stefan.bader at canonical.com>
-
-Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
----
- net/dccp/input.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/net/dccp/input.c b/net/dccp/input.c
-index 3bd14e8..dbe2573 100644
---- a/net/dccp/input.c
-+++ b/net/dccp/input.c
-@@ -606,7 +606,8 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
- 			if (inet_csk(sk)->icsk_af_ops->conn_request(sk,
- 								    skb) < 0)
- 				return 1;
--			goto discard;
-+			consume_skb(skb);
-+			return 0;
- 		}
- 		if (dh->dccph_type == DCCP_PKT_RESET)
- 			goto discard;
--- 
-2.1.4
-
diff --git a/IB-ipoib-move-back-the-IB-LL-address-into-the-hard-header.patch b/IB-ipoib-move-back-the-IB-LL-address-into-the-hard-header.patch
deleted file mode 100644
index 5b58edd..0000000
--- a/IB-ipoib-move-back-the-IB-LL-address-into-the-hard-header.patch
+++ /dev/null
@@ -1,365 +0,0 @@
-From patchwork Wed Oct 12 14:30:30 2016
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: [v2] IB/ipoib: move back IB LL address into the hard header
-From: Paolo Abeni <pabeni at redhat.com>
-X-Patchwork-Id: 681344
-X-Patchwork-Delegate: davem at davemloft.net
-Message-Id: <60efcf739ce3d45a01a7127dbaf7fe366e5ddce4.1476264804.git.pabeni at redhat.com>
-To: linux-rdma at vger.kernel.org
-Cc: Doug Ledford <dledford at redhat.com>, Sean Hefty <sean.hefty at intel.com>,
- Hal Rosenstock <hal.rosenstock at gmail.com>,
- Jason Gunthorpe <jgunthorpe at obsidianresearch.com>, netdev at vger.kernel.org
-Date: Wed, 12 Oct 2016 16:30:30 +0200
-
-After the commit 9207f9d45b0a ("net: preserve IP control block
-during GSO segmentation"), the GSO CB and the IPoIB CB conflict.
-That destroy the IPoIB address information cached there,
-causing a severe performance regression, as better described here:
-
-http://marc.info/?l=linux-kernel&m=146787279825501&w=2
-
-This change moves the data cached by the IPoIB driver from the
-skb control lock into the IPoIB hard header, as done before
-the commit 936d7de3d736 ("IPoIB: Stop lying about hard_header_len
-and use skb->cb to stash LL addresses").
-In order to avoid GRO issue, on packet reception, the IPoIB driver
-stash into the skb a dummy pseudo header, so that the received
-packets have actually a hard header matching the declared length.
-To avoid changing the connected mode maximum mtu, the allocated 
-head buffer size is increased by the pseudo header length.
-
-After this commit, IPoIB performances are back to pre-regression
-value.
-
-v1 -> v2: avoid changing the max mtu, increasing the head buf size
-
-Fixes: 9207f9d45b0a ("net: preserve IP control block during GSO segmentation")
-Signed-off-by: Paolo Abeni <pabeni at redhat.com>
----
- drivers/infiniband/ulp/ipoib/ipoib.h           | 20 +++++++---
- drivers/infiniband/ulp/ipoib/ipoib_cm.c        | 15 +++----
- drivers/infiniband/ulp/ipoib/ipoib_ib.c        | 12 +++---
- drivers/infiniband/ulp/ipoib/ipoib_main.c      | 54 ++++++++++++++++----------
- drivers/infiniband/ulp/ipoib/ipoib_multicast.c |  6 ++-
- 5 files changed, 64 insertions(+), 43 deletions(-)
-
-diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
-index 9dbfcc0..5ff64af 100644
---- a/drivers/infiniband/ulp/ipoib/ipoib.h
-+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
-@@ -63,6 +63,8 @@ enum ipoib_flush_level {
- 
- enum {
- 	IPOIB_ENCAP_LEN		  = 4,
-+	IPOIB_PSEUDO_LEN	  = 20,
-+	IPOIB_HARD_LEN		  = IPOIB_ENCAP_LEN + IPOIB_PSEUDO_LEN,
- 
- 	IPOIB_UD_HEAD_SIZE	  = IB_GRH_BYTES + IPOIB_ENCAP_LEN,
- 	IPOIB_UD_RX_SG		  = 2, /* max buffer needed for 4K mtu */
-@@ -134,15 +136,21 @@ struct ipoib_header {
- 	u16	reserved;
- };
- 
--struct ipoib_cb {
--	struct qdisc_skb_cb	qdisc_cb;
--	u8			hwaddr[INFINIBAND_ALEN];
-+struct ipoib_pseudo_header {
-+	u8	hwaddr[INFINIBAND_ALEN];
- };
- 
--static inline struct ipoib_cb *ipoib_skb_cb(const struct sk_buff *skb)
-+static inline void skb_add_pseudo_hdr(struct sk_buff *skb)
- {
--	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct ipoib_cb));
--	return (struct ipoib_cb *)skb->cb;
-+	char *data = skb_push(skb, IPOIB_PSEUDO_LEN);
-+
-+	/*
-+	 * only the ipoib header is present now, make room for a dummy
-+	 * pseudo header and set skb field accordingly
-+	 */
-+	memset(data, 0, IPOIB_PSEUDO_LEN);
-+	skb_reset_mac_header(skb);
-+	skb_pull(skb, IPOIB_HARD_LEN);
- }
- 
- /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
-diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-index 4ad297d..339a1ee 100644
---- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-@@ -63,6 +63,8 @@ MODULE_PARM_DESC(cm_data_debug_level,
- #define IPOIB_CM_RX_DELAY       (3 * 256 * HZ)
- #define IPOIB_CM_RX_UPDATE_MASK (0x3)
- 
-+#define IPOIB_CM_RX_RESERVE     (ALIGN(IPOIB_HARD_LEN, 16) - IPOIB_ENCAP_LEN)
-+
- static struct ib_qp_attr ipoib_cm_err_attr = {
- 	.qp_state = IB_QPS_ERR
- };
-@@ -146,15 +148,15 @@ static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev,
- 	struct sk_buff *skb;
- 	int i;
- 
--	skb = dev_alloc_skb(IPOIB_CM_HEAD_SIZE + 12);
-+	skb = dev_alloc_skb(ALIGN(IPOIB_CM_HEAD_SIZE + IPOIB_PSEUDO_LEN, 16));
- 	if (unlikely(!skb))
- 		return NULL;
- 
- 	/*
--	 * IPoIB adds a 4 byte header. So we need 12 more bytes to align the
-+	 * IPoIB adds a IPOIB_ENCAP_LEN byte header, this will align the
- 	 * IP header to a multiple of 16.
- 	 */
--	skb_reserve(skb, 12);
-+	skb_reserve(skb, IPOIB_CM_RX_RESERVE);
- 
- 	mapping[0] = ib_dma_map_single(priv->ca, skb->data, IPOIB_CM_HEAD_SIZE,
- 				       DMA_FROM_DEVICE);
-@@ -624,9 +626,9 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
- 	if (wc->byte_len < IPOIB_CM_COPYBREAK) {
- 		int dlen = wc->byte_len;
- 
--		small_skb = dev_alloc_skb(dlen + 12);
-+		small_skb = dev_alloc_skb(dlen + IPOIB_CM_RX_RESERVE);
- 		if (small_skb) {
--			skb_reserve(small_skb, 12);
-+			skb_reserve(small_skb, IPOIB_CM_RX_RESERVE);
- 			ib_dma_sync_single_for_cpu(priv->ca, rx_ring[wr_id].mapping[0],
- 						   dlen, DMA_FROM_DEVICE);
- 			skb_copy_from_linear_data(skb, small_skb->data, dlen);
-@@ -663,8 +665,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
- 
- copied:
- 	skb->protocol = ((struct ipoib_header *) skb->data)->proto;
--	skb_reset_mac_header(skb);
--	skb_pull(skb, IPOIB_ENCAP_LEN);
-+	skb_add_pseudo_hdr(skb);
- 
- 	++dev->stats.rx_packets;
- 	dev->stats.rx_bytes += skb->len;
-diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-index be11d5d..830fecb 100644
---- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
-@@ -128,16 +128,15 @@ static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id)
- 
- 	buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu);
- 
--	skb = dev_alloc_skb(buf_size + IPOIB_ENCAP_LEN);
-+	skb = dev_alloc_skb(buf_size + IPOIB_HARD_LEN);
- 	if (unlikely(!skb))
- 		return NULL;
- 
- 	/*
--	 * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte
--	 * header.  So we need 4 more bytes to get to 48 and align the
--	 * IP header to a multiple of 16.
-+	 * the IP header will be at IPOIP_HARD_LEN + IB_GRH_BYTES, that is
-+	 * 64 bytes aligned
- 	 */
--	skb_reserve(skb, 4);
-+	skb_reserve(skb, sizeof(struct ipoib_pseudo_header));
- 
- 	mapping = priv->rx_ring[id].mapping;
- 	mapping[0] = ib_dma_map_single(priv->ca, skb->data, buf_size,
-@@ -253,8 +252,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
- 	skb_pull(skb, IB_GRH_BYTES);
- 
- 	skb->protocol = ((struct ipoib_header *) skb->data)->proto;
--	skb_reset_mac_header(skb);
--	skb_pull(skb, IPOIB_ENCAP_LEN);
-+	skb_add_pseudo_hdr(skb);
- 
- 	++dev->stats.rx_packets;
- 	dev->stats.rx_bytes += skb->len;
-diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
-index cc1c1b0..823a528 100644
---- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
-@@ -925,9 +925,12 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
- 				ipoib_neigh_free(neigh);
- 				goto err_drop;
- 			}
--			if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE)
-+			if (skb_queue_len(&neigh->queue) <
-+			    IPOIB_MAX_PATH_REC_QUEUE) {
-+				/* put pseudoheader back on for next time */
-+				skb_push(skb, IPOIB_PSEUDO_LEN);
- 				__skb_queue_tail(&neigh->queue, skb);
--			else {
-+			} else {
- 				ipoib_warn(priv, "queue length limit %d. Packet drop.\n",
- 					   skb_queue_len(&neigh->queue));
- 				goto err_drop;
-@@ -964,7 +967,7 @@ err_drop:
- }
- 
- static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
--			     struct ipoib_cb *cb)
-+			     struct ipoib_pseudo_header *phdr)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
- 	struct ipoib_path *path;
-@@ -972,16 +975,18 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
- 
- 	spin_lock_irqsave(&priv->lock, flags);
- 
--	path = __path_find(dev, cb->hwaddr + 4);
-+	path = __path_find(dev, phdr->hwaddr + 4);
- 	if (!path || !path->valid) {
- 		int new_path = 0;
- 
- 		if (!path) {
--			path = path_rec_create(dev, cb->hwaddr + 4);
-+			path = path_rec_create(dev, phdr->hwaddr + 4);
- 			new_path = 1;
- 		}
- 		if (path) {
- 			if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-+				/* put pseudoheader back on for next time */
-+				skb_push(skb, IPOIB_PSEUDO_LEN);
- 				__skb_queue_tail(&path->queue, skb);
- 			} else {
- 				++dev->stats.tx_dropped;
-@@ -1009,10 +1014,12 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
- 			  be16_to_cpu(path->pathrec.dlid));
- 
- 		spin_unlock_irqrestore(&priv->lock, flags);
--		ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr));
-+		ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
- 		return;
- 	} else if ((path->query || !path_rec_start(dev, path)) &&
- 		   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-+		/* put pseudoheader back on for next time */
-+		skb_push(skb, IPOIB_PSEUDO_LEN);
- 		__skb_queue_tail(&path->queue, skb);
- 	} else {
- 		++dev->stats.tx_dropped;
-@@ -1026,13 +1033,15 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
- 	struct ipoib_neigh *neigh;
--	struct ipoib_cb *cb = ipoib_skb_cb(skb);
-+	struct ipoib_pseudo_header *phdr;
- 	struct ipoib_header *header;
- 	unsigned long flags;
- 
-+	phdr = (struct ipoib_pseudo_header *) skb->data;
-+	skb_pull(skb, sizeof(*phdr));
- 	header = (struct ipoib_header *) skb->data;
- 
--	if (unlikely(cb->hwaddr[4] == 0xff)) {
-+	if (unlikely(phdr->hwaddr[4] == 0xff)) {
- 		/* multicast, arrange "if" according to probability */
- 		if ((header->proto != htons(ETH_P_IP)) &&
- 		    (header->proto != htons(ETH_P_IPV6)) &&
-@@ -1045,13 +1054,13 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 			return NETDEV_TX_OK;
- 		}
- 		/* Add in the P_Key for multicast*/
--		cb->hwaddr[8] = (priv->pkey >> 8) & 0xff;
--		cb->hwaddr[9] = priv->pkey & 0xff;
-+		phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff;
-+		phdr->hwaddr[9] = priv->pkey & 0xff;
- 
--		neigh = ipoib_neigh_get(dev, cb->hwaddr);
-+		neigh = ipoib_neigh_get(dev, phdr->hwaddr);
- 		if (likely(neigh))
- 			goto send_using_neigh;
--		ipoib_mcast_send(dev, cb->hwaddr, skb);
-+		ipoib_mcast_send(dev, phdr->hwaddr, skb);
- 		return NETDEV_TX_OK;
- 	}
- 
-@@ -1060,16 +1069,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 	case htons(ETH_P_IP):
- 	case htons(ETH_P_IPV6):
- 	case htons(ETH_P_TIPC):
--		neigh = ipoib_neigh_get(dev, cb->hwaddr);
-+		neigh = ipoib_neigh_get(dev, phdr->hwaddr);
- 		if (unlikely(!neigh)) {
--			neigh_add_path(skb, cb->hwaddr, dev);
-+			neigh_add_path(skb, phdr->hwaddr, dev);
- 			return NETDEV_TX_OK;
- 		}
- 		break;
- 	case htons(ETH_P_ARP):
- 	case htons(ETH_P_RARP):
- 		/* for unicast ARP and RARP should always perform path find */
--		unicast_arp_send(skb, dev, cb);
-+		unicast_arp_send(skb, dev, phdr);
- 		return NETDEV_TX_OK;
- 	default:
- 		/* ethertype not supported by IPoIB */
-@@ -1086,11 +1095,13 @@ send_using_neigh:
- 			goto unref;
- 		}
- 	} else if (neigh->ah) {
--		ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(cb->hwaddr));
-+		ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(phdr->hwaddr));
- 		goto unref;
- 	}
- 
- 	if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
-+		/* put pseudoheader back on for next time */
-+		skb_push(skb, sizeof(*phdr));
- 		spin_lock_irqsave(&priv->lock, flags);
- 		__skb_queue_tail(&neigh->queue, skb);
- 		spin_unlock_irqrestore(&priv->lock, flags);
-@@ -1122,8 +1133,8 @@ static int ipoib_hard_header(struct sk_buff *skb,
- 			     unsigned short type,
- 			     const void *daddr, const void *saddr, unsigned len)
- {
-+	struct ipoib_pseudo_header *phdr;
- 	struct ipoib_header *header;
--	struct ipoib_cb *cb = ipoib_skb_cb(skb);
- 
- 	header = (struct ipoib_header *) skb_push(skb, sizeof *header);
- 
-@@ -1132,12 +1143,13 @@ static int ipoib_hard_header(struct sk_buff *skb,
- 
- 	/*
- 	 * we don't rely on dst_entry structure,  always stuff the
--	 * destination address into skb->cb so we can figure out where
-+	 * destination address into skb hard header so we can figure out where
- 	 * to send the packet later.
- 	 */
--	memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN);
-+	phdr = (struct ipoib_pseudo_header *) skb_push(skb, sizeof(*phdr));
-+	memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
- 
--	return sizeof *header;
-+	return IPOIB_HARD_LEN;
- }
- 
- static void ipoib_set_mcast_list(struct net_device *dev)
-@@ -1759,7 +1771,7 @@ void ipoib_setup(struct net_device *dev)
- 
- 	dev->flags		|= IFF_BROADCAST | IFF_MULTICAST;
- 
--	dev->hard_header_len	 = IPOIB_ENCAP_LEN;
-+	dev->hard_header_len	 = IPOIB_HARD_LEN;
- 	dev->addr_len		 = INFINIBAND_ALEN;
- 	dev->type		 = ARPHRD_INFINIBAND;
- 	dev->tx_queue_len	 = ipoib_sendq_size * 2;
-diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-index d3394b6..1909dd2 100644
---- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-@@ -796,9 +796,11 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
- 			__ipoib_mcast_add(dev, mcast);
- 			list_add_tail(&mcast->list, &priv->multicast_list);
- 		}
--		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
-+		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE) {
-+			/* put pseudoheader back on for next time */
-+			skb_push(skb, sizeof(struct ipoib_pseudo_header));
- 			skb_queue_tail(&mcast->pkt_queue, skb);
--		else {
-+		} else {
- 			++dev->stats.tx_dropped;
- 			dev_kfree_skb_any(skb);
- 		}
diff --git a/bug-950-tcp-fix-tcp_mark_head_lost-to-check-skb-len-before-f.patch b/bug-950-tcp-fix-tcp_mark_head_lost-to-check-skb-len-before-f.patch
deleted file mode 100644
index 2d9bebd..0000000
--- a/bug-950-tcp-fix-tcp_mark_head_lost-to-check-skb-len-before-f.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From d88270eef4b56bd7973841dd1fed387ccfa83709 Mon Sep 17 00:00:00 2001
-From: Neal Cardwell <ncardwell at google.com>
-Date: Mon, 25 Jan 2016 14:01:53 -0800
-Subject: [PATCH] tcp: fix tcp_mark_head_lost to check skb len before
- fragmenting
-
-This commit fixes a corner case in tcp_mark_head_lost() which was
-causing the WARN_ON(len > skb->len) in tcp_fragment() to fire.
-
-tcp_mark_head_lost() was assuming that if a packet has
-tcp_skb_pcount(skb) of N, then it's safe to fragment off a prefix of
-M*mss bytes, for any M < N. But with the tricky way TCP pcounts are
-maintained, this is not always true.
-
-For example, suppose the sender sends 4 1-byte packets and have the
-last 3 packet sacked. It will merge the last 3 packets in the write
-queue into an skb with pcount = 3 and len = 3 bytes. If another
-recovery happens after a sack reneging event, tcp_mark_head_lost()
-may attempt to split the skb assuming it has more than 2*MSS bytes.
-
-This sounds very counterintuitive, but as the commit description for
-the related commit c0638c247f55 ("tcp: don't fragment SACKed skbs in
-tcp_mark_head_lost()") notes, this is because tcp_shifted_skb()
-coalesces adjacent regions of SACKed skbs, and when doing this it
-preserves the sum of their packet counts in order to reflect the
-real-world dynamics on the wire. The c0638c247f55 commit tried to
-avoid problems by not fragmenting SACKed skbs, since SACKed skbs are
-where the non-proportionality between pcount and skb->len/mss is known
-to be possible. However, that commit did not handle the case where
-during a reneging event one of these weird SACKed skbs becomes an
-un-SACKed skb, which tcp_mark_head_lost() can then try to fragment.
-
-The fix is to simply mark the entire skb lost when this happens.
-This makes the recovery slightly more aggressive in such corner
-cases before we detect reordering. But once we detect reordering
-this code path is by-passed because FACK is disabled.
-
-Signed-off-by: Neal Cardwell <ncardwell at google.com>
-Signed-off-by: Yuchung Cheng <ycheng at google.com>
-Signed-off-by: Eric Dumazet <edumazet at google.com>
-Signed-off-by: David S. Miller <davem at davemloft.net>
-Cherry-picked-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
----
- net/ipv4/tcp_input.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
-index 0003d40..d2ad433 100644
---- a/net/ipv4/tcp_input.c
-+++ b/net/ipv4/tcp_input.c
-@@ -2164,8 +2164,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
- {
- 	struct tcp_sock *tp = tcp_sk(sk);
- 	struct sk_buff *skb;
--	int cnt, oldcnt;
--	int err;
-+	int cnt, oldcnt, lost;
- 	unsigned int mss;
- 	/* Use SACK to deduce losses of new sequences sent during recovery */
- 	const u32 loss_high = tcp_is_sack(tp) ?  tp->snd_nxt : tp->high_seq;
-@@ -2205,9 +2204,10 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head)
- 				break;
- 
- 			mss = tcp_skb_mss(skb);
--			err = tcp_fragment(sk, skb, (packets - oldcnt) * mss,
--					   mss, GFP_ATOMIC);
--			if (err < 0)
-+			/* If needed, chop off the prefix to mark as lost. */
-+			lost = (packets - oldcnt) * mss;
-+			if (lost < skb->len &&
-+			    tcp_fragment(sk, skb, lost, mss, GFP_ATOMIC) < 0)
- 				break;
- 			cnt = packets;
- 		}
--- 
-2.1.4
-
diff --git a/mei_bus-whitelist-watchdog-client.patch b/mei_bus-whitelist-watchdog-client.patch
deleted file mode 100644
index 5870e51..0000000
--- a/mei_bus-whitelist-watchdog-client.patch
+++ /dev/null
@@ -1,74 +0,0 @@
-From e97cdb303c04bfe60283094bdced68a0d363bd5d Mon Sep 17 00:00:00 2001
-From: Tomas Winkler <tomas.winkler at intel.com>
-Date: Fri, 8 Jan 2016 00:49:24 +0200
-Subject: mei: bus: whitelist the watchdog client
-
-The iAMT WD client has to be whitelisted sice it has two connections
-and is filtered out by number_of_connections fixup.
-Also the API has changed for BDW and SKL but firmware haven't updated
-the protocol version.
-
-Signed-off-by: Tomas Winkler <tomas.winkler at intel.com>
-Signed-off-by: Alexander Usyskin <alexander.usyskin at intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
----
- drivers/misc/mei/bus-fixup.c | 29 +++++++++++++++++++++++++++++
- 1 file changed, 29 insertions(+)
-
-diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
-index b2d2a6e..b87323f 100644
---- a/drivers/misc/mei/bus-fixup.c
-+++ b/drivers/misc/mei/bus-fixup.c
-@@ -35,6 +35,9 @@ static const uuid_le mei_nfc_info_guid = MEI_UUID_NFC_INFO;
- #define MEI_UUID_NFC_HCI UUID_LE(0x0bb17a78, 0x2a8e, 0x4c50, \
- 			0x94, 0xd4, 0x50, 0x26, 0x67, 0x23, 0x77, 0x5c)
- 
-+#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
-+			    0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
-+
- #define MEI_UUID_ANY NULL_UUID_LE
- 
- /**
-@@ -66,6 +69,31 @@ static void blacklist(struct mei_cl_device *cldev)
- 	cldev->do_match = 0;
- }
- 
-+/**
-+ * mei_wd - wd client on the bus, change protocol version
-+ *   as the API has changed.
-+ *
-+ * @cldev: me clients device
-+ */
-+#if IS_ENABLED(CONFIG_INTEL_MEI_ME)
-+#include <linux/pci.h>
-+#include "hw-me-regs.h"
-+static void mei_wd(struct mei_cl_device *cldev)
-+{
-+	struct pci_dev *pdev = to_pci_dev(cldev->dev.parent);
-+
-+	dev_dbg(&cldev->dev, "running hook %s\n", __func__);
-+	if (pdev->device == MEI_DEV_ID_WPT_LP ||
-+	    pdev->device == MEI_DEV_ID_SPT ||
-+	    pdev->device == MEI_DEV_ID_SPT_H)
-+		cldev->me_cl->props.protocol_version = 0x2;
-+
-+	cldev->do_match = 1;
-+}
-+#else
-+static inline void mei_wd(struct mei_cl_device *cldev) {}
-+#endif /* CONFIG_INTEL_MEI_ME */
-+
- struct mei_nfc_cmd {
- 	u8 command;
- 	u8 status;
-@@ -280,6 +308,7 @@ static struct mei_fixup {
- 	MEI_FIXUP(MEI_UUID_ANY, number_of_connections),
- 	MEI_FIXUP(MEI_UUID_NFC_INFO, blacklist),
- 	MEI_FIXUP(MEI_UUID_NFC_HCI, mei_nfc),
-+	MEI_FIXUP(MEI_UUID_WD, mei_wd),
- };
- 
- /**
--- 
-cgit v0.12
-
diff --git a/mei_drop-watchdog-code.patch b/mei_drop-watchdog-code.patch
deleted file mode 100644
index f33aad2..0000000
--- a/mei_drop-watchdog-code.patch
+++ /dev/null
@@ -1,754 +0,0 @@
-From fdd9b8655933c3eb3154fe1ed351c17b654258bd Mon Sep 17 00:00:00 2001
-From: Alexander Usyskin <alexander.usyskin at intel.com>
-Date: Fri, 8 Jan 2016 00:49:21 +0200
-Subject: mei: wd: drop the watchdog code from the core mei driver
-
-Instead of integrating the iAMT watchdog in the mei core driver
-we will create a watchdog device on the mei client bus and
-create a driver for it.
-
-This patch removes the watchdog code from the mei core driver.
-
-Signed-off-by: Alexander Usyskin <alexander.usyskin at intel.com>
-Signed-off-by: Tomas Winkler <tomas.winkler at intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
----
- drivers/misc/mei/Kconfig     |   6 +-
- drivers/misc/mei/Makefile    |   1 -
- drivers/misc/mei/client.c    |  12 +-
- drivers/misc/mei/client.h    |   4 -
- drivers/misc/mei/init.c      |  10 +-
- drivers/misc/mei/interrupt.c |  15 --
- drivers/misc/mei/mei_dev.h   |  61 +------
- drivers/misc/mei/wd.c        | 391 -------------------------------------------
- 8 files changed, 9 insertions(+), 491 deletions(-)
- delete mode 100644 drivers/misc/mei/wd.c
-
-diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig
-index d23384d..c49e1d2 100644
---- a/drivers/misc/mei/Kconfig
-+++ b/drivers/misc/mei/Kconfig
-@@ -1,6 +1,6 @@
- config INTEL_MEI
- 	tristate "Intel Management Engine Interface"
--	depends on X86 && PCI && WATCHDOG_CORE
-+	depends on X86 && PCI
- 	help
- 	  The Intel Management Engine (Intel ME) provides Manageability,
- 	  Security and Media services for system containing Intel chipsets.
-@@ -12,7 +12,7 @@ config INTEL_MEI
- config INTEL_MEI_ME
- 	tristate "ME Enabled Intel Chipsets"
- 	select INTEL_MEI
--	depends on X86 && PCI && WATCHDOG_CORE
-+	depends on X86 && PCI
- 	help
- 	  MEI support for ME Enabled Intel chipsets.
- 
-@@ -37,7 +37,7 @@ config INTEL_MEI_ME
- config INTEL_MEI_TXE
- 	tristate "Intel Trusted Execution Environment with ME Interface"
- 	select INTEL_MEI
--	depends on X86 && PCI && WATCHDOG_CORE
-+	depends on X86 && PCI
- 	help
- 	  MEI Support for Trusted Execution Environment device on Intel SoCs
- 
-diff --git a/drivers/misc/mei/Makefile b/drivers/misc/mei/Makefile
-index 01447ca..59e6b0a 100644
---- a/drivers/misc/mei/Makefile
-+++ b/drivers/misc/mei/Makefile
-@@ -9,7 +9,6 @@ mei-objs += interrupt.o
- mei-objs += client.o
- mei-objs += main.o
- mei-objs += amthif.o
--mei-objs += wd.o
- mei-objs += bus.o
- mei-objs += bus-fixup.o
- mei-$(CONFIG_DEBUG_FS) += debugfs.o
-diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
-index 72e3261..e069fca 100644
---- a/drivers/misc/mei/client.c
-+++ b/drivers/misc/mei/client.c
-@@ -648,7 +648,7 @@ int mei_cl_unlink(struct mei_cl *cl)
- 	if (!cl)
- 		return 0;
- 
--	/* wd and amthif might not be initialized */
-+	/* amthif might not be initialized */
- 	if (!cl->dev)
- 		return 0;
- 
-@@ -679,17 +679,11 @@ void mei_host_client_init(struct work_struct *work)
- 
- 	mutex_lock(&dev->device_lock);
- 
--
- 	me_cl = mei_me_cl_by_uuid(dev, &mei_amthif_guid);
- 	if (me_cl)
- 		mei_amthif_host_init(dev, me_cl);
- 	mei_me_cl_put(me_cl);
- 
--	me_cl = mei_me_cl_by_uuid(dev, &mei_wd_guid);
--	if (me_cl)
--		mei_wd_host_init(dev, me_cl);
--	mei_me_cl_put(me_cl);
--
- 	dev->dev_state = MEI_DEV_ENABLED;
- 	dev->reset_count = 0;
- 	mutex_unlock(&dev->device_lock);
-@@ -1153,7 +1147,7 @@ err:
-  *
-  * Return: 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
-  */
--int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
-+static int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
- {
- 	int rets;
- 
-@@ -1186,7 +1180,7 @@ int mei_cl_flow_ctrl_creds(struct mei_cl *cl)
-  *	0 on success
-  *	-EINVAL when ctrl credits are <= 0
-  */
--int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
-+static int mei_cl_flow_ctrl_reduce(struct mei_cl *cl)
- {
- 	if (WARN_ON(!cl || !cl->me_cl))
- 		return -EINVAL;
-diff --git a/drivers/misc/mei/client.h b/drivers/misc/mei/client.h
-index 04e1aa3..2e90a25 100644
---- a/drivers/misc/mei/client.h
-+++ b/drivers/misc/mei/client.h
-@@ -18,7 +18,6 @@
- #define _MEI_CLIENT_H_
- 
- #include <linux/types.h>
--#include <linux/watchdog.h>
- #include <linux/poll.h>
- #include <linux/mei.h>
- 
-@@ -120,9 +119,6 @@ struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length,
- 				  enum mei_cb_file_ops type, struct file *fp);
- int mei_cl_flush_queues(struct mei_cl *cl, const struct file *fp);
- 
--int mei_cl_flow_ctrl_creds(struct mei_cl *cl);
--
--int mei_cl_flow_ctrl_reduce(struct mei_cl *cl);
- /*
-  *  MEI input output function prototype
-  */
-diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c
-index 3edafc8..46a4302 100644
---- a/drivers/misc/mei/init.c
-+++ b/drivers/misc/mei/init.c
-@@ -156,8 +156,7 @@ int mei_reset(struct mei_device *dev)
- 		mei_cl_all_wakeup(dev);
- 
- 		/* remove entry if already in list */
--		dev_dbg(dev->dev, "remove iamthif and wd from the file list.\n");
--		mei_cl_unlink(&dev->wd_cl);
-+		dev_dbg(dev->dev, "remove iamthif from the file list.\n");
- 		mei_cl_unlink(&dev->iamthif_cl);
- 		mei_amthif_reset_params(dev);
- 	}
-@@ -165,7 +164,6 @@ int mei_reset(struct mei_device *dev)
- 	mei_hbm_reset(dev);
- 
- 	dev->rd_msg_hdr = 0;
--	dev->wd_pending = false;
- 
- 	if (ret) {
- 		dev_err(dev->dev, "hw_reset failed ret = %d\n", ret);
-@@ -335,16 +333,12 @@ void mei_stop(struct mei_device *dev)
- 
- 	mutex_lock(&dev->device_lock);
- 
--	mei_wd_stop(dev);
--
- 	dev->dev_state = MEI_DEV_POWER_DOWN;
- 	mei_reset(dev);
- 	/* move device to disabled state unconditionally */
- 	dev->dev_state = MEI_DEV_DISABLED;
- 
- 	mutex_unlock(&dev->device_lock);
--
--	mei_watchdog_unregister(dev);
- }
- EXPORT_SYMBOL_GPL(mei_stop);
- 
-@@ -394,7 +388,6 @@ void mei_device_init(struct mei_device *dev,
- 	init_waitqueue_head(&dev->wait_hw_ready);
- 	init_waitqueue_head(&dev->wait_pg);
- 	init_waitqueue_head(&dev->wait_hbm_start);
--	init_waitqueue_head(&dev->wait_stop_wd);
- 	dev->dev_state = MEI_DEV_INITIALIZING;
- 	dev->reset_count = 0;
- 
-@@ -407,7 +400,6 @@ void mei_device_init(struct mei_device *dev,
- 	INIT_WORK(&dev->init_work, mei_host_client_init);
- 	INIT_WORK(&dev->reset_work, mei_reset_work);
- 
--	INIT_LIST_HEAD(&dev->wd_cl.link);
- 	INIT_LIST_HEAD(&dev->iamthif_cl.link);
- 	mei_io_list_init(&dev->amthif_cmd_list);
- 	mei_io_list_init(&dev->amthif_rd_complete_list);
-diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
-index 64b568a..6340dee 100644
---- a/drivers/misc/mei/interrupt.c
-+++ b/drivers/misc/mei/interrupt.c
-@@ -360,21 +360,6 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
- 		list_move_tail(&cb->list, &cmpl_list->list);
- 	}
- 
--	if (dev->wd_state == MEI_WD_STOPPING) {
--		dev->wd_state = MEI_WD_IDLE;
--		wake_up(&dev->wait_stop_wd);
--	}
--
--	if (mei_cl_is_connected(&dev->wd_cl)) {
--		if (dev->wd_pending &&
--		    mei_cl_flow_ctrl_creds(&dev->wd_cl) > 0) {
--			ret = mei_wd_send(dev);
--			if (ret)
--				return ret;
--			dev->wd_pending = false;
--		}
--	}
--
- 	/* complete control write list CB */
- 	dev_dbg(dev->dev, "complete control write list cb.\n");
- 	list_for_each_entry_safe(cb, next, &dev->ctrl_wr_list.list, list) {
-diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
-index b54d9d9..da61326 100644
---- a/drivers/misc/mei/mei_dev.h
-+++ b/drivers/misc/mei/mei_dev.h
-@@ -18,7 +18,7 @@
- #define _MEI_DEV_H_
- 
- #include <linux/types.h>
--#include <linux/watchdog.h>
-+#include <linux/cdev.h>
- #include <linux/poll.h>
- #include <linux/mei.h>
- #include <linux/mei_cl_bus.h>
-@@ -26,33 +26,13 @@
- #include "hw.h"
- #include "hbm.h"
- 
--/*
-- * watch dog definition
-- */
--#define MEI_WD_HDR_SIZE       4
--#define MEI_WD_STOP_MSG_SIZE  MEI_WD_HDR_SIZE
--#define MEI_WD_START_MSG_SIZE (MEI_WD_HDR_SIZE + 16)
--
--#define MEI_WD_DEFAULT_TIMEOUT   120  /* seconds */
--#define MEI_WD_MIN_TIMEOUT       120  /* seconds */
--#define MEI_WD_MAX_TIMEOUT     65535  /* seconds */
--
--#define MEI_WD_STOP_TIMEOUT      10 /* msecs */
--
--#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT       (1 << 0)
--
--#define MEI_RD_MSG_BUF_SIZE           (128 * sizeof(u32))
--
- 
- /*
-  * AMTHI Client UUID
-  */
- extern const uuid_le mei_amthif_guid;
- 
--/*
-- * Watchdog Client UUID
-- */
--extern const uuid_le mei_wd_guid;
-+#define MEI_RD_MSG_BUF_SIZE           (128 * sizeof(u32))
- 
- /*
-  * Number of Maximum MEI Clients
-@@ -78,7 +58,6 @@ extern const uuid_le mei_wd_guid;
-  */
- #define MEI_HOST_CLIENT_ID_ANY        (-1)
- #define MEI_HBM_HOST_CLIENT_ID         0 /* not used, just for documentation */
--#define MEI_WD_HOST_CLIENT_ID          1
- #define MEI_IAMTHIF_HOST_CLIENT_ID     2
- 
- 
-@@ -123,12 +102,6 @@ enum mei_file_transaction_states {
- 	MEI_READ_COMPLETE
- };
- 
--enum mei_wd_states {
--	MEI_WD_IDLE,
--	MEI_WD_RUNNING,
--	MEI_WD_STOPPING,
--};
--
- /**
-  * enum mei_cb_file_ops  - file operation associated with the callback
-  * @MEI_FOP_READ:       read
-@@ -404,7 +377,6 @@ const char *mei_pg_state_str(enum mei_pg_state state);
-  * @wait_hw_ready : wait queue for receive HW ready message form FW
-  * @wait_pg     : wait queue for receive PG message from FW
-  * @wait_hbm_start : wait queue for receive HBM start message from FW
-- * @wait_stop_wd : wait queue for receive WD stop message from FW
-  *
-  * @reset_count : number of consecutive resets
-  * @dev_state   : device state
-@@ -435,12 +407,6 @@ const char *mei_pg_state_str(enum mei_pg_state state);
-  *
-  * @allow_fixed_address: allow user space to connect a fixed client
-  *
-- * @wd_cl       : watchdog client
-- * @wd_state    : watchdog client state
-- * @wd_pending  : watchdog command is pending
-- * @wd_timeout  : watchdog expiration timeout
-- * @wd_data     : watchdog message buffer
-- *
-  * @amthif_cmd_list : amthif list for cmd waiting
-  * @amthif_rd_complete_list : amthif list for reading completed cmd data
-  * @iamthif_file_object : file for current amthif operation
-@@ -486,7 +452,6 @@ struct mei_device {
- 	wait_queue_head_t wait_hw_ready;
- 	wait_queue_head_t wait_pg;
- 	wait_queue_head_t wait_hbm_start;
--	wait_queue_head_t wait_stop_wd;
- 
- 	/*
- 	 * mei device  states
-@@ -531,13 +496,6 @@ struct mei_device {
- 
- 	bool allow_fixed_address;
- 
--	struct mei_cl wd_cl;
--	enum mei_wd_states wd_state;
--	bool wd_pending;
--	u16 wd_timeout;
--	unsigned char wd_data[MEI_WD_START_MSG_SIZE];
--
--
- 	/* amthif list for cmd waiting */
- 	struct mei_cl_cb amthif_cmd_list;
- 	/* driver managed amthif list for reading completed amthif cmd data */
-@@ -649,21 +607,6 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl,
- 			    struct mei_cl_cb *complete_list);
- int mei_amthif_irq_read(struct mei_device *dev, s32 *slots);
- 
--int mei_wd_send(struct mei_device *dev);
--int mei_wd_stop(struct mei_device *dev);
--int mei_wd_host_init(struct mei_device *dev, struct mei_me_client *me_cl);
--/*
-- * mei_watchdog_register  - Registering watchdog interface
-- *   once we got connection to the WD Client
-- * @dev: mei device
-- */
--int mei_watchdog_register(struct mei_device *dev);
--/*
-- * mei_watchdog_unregister  - Unregistering watchdog interface
-- * @dev: mei device
-- */
--void mei_watchdog_unregister(struct mei_device *dev);
--
- /*
-  * Register Access Function
-  */
-diff --git a/drivers/misc/mei/wd.c b/drivers/misc/mei/wd.c
-deleted file mode 100644
-index b346638..0000000
---- a/drivers/misc/mei/wd.c
-+++ /dev/null
-@@ -1,391 +0,0 @@
--/*
-- *
-- * Intel Management Engine Interface (Intel MEI) Linux driver
-- * Copyright (c) 2003-2012, Intel Corporation.
-- *
-- * This program is free software; you can redistribute it and/or modify it
-- * under the terms and conditions of the GNU General Public License,
-- * version 2, as published by the Free Software Foundation.
-- *
-- * This program is distributed in the hope it will be useful, but WITHOUT
-- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-- * more details.
-- *
-- */
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/moduleparam.h>
--#include <linux/device.h>
--#include <linux/sched.h>
--#include <linux/watchdog.h>
--
--#include <linux/mei.h>
--
--#include "mei_dev.h"
--#include "hbm.h"
--#include "client.h"
--
--static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
--static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
--
--/*
-- * AMT Watchdog Device
-- */
--#define INTEL_AMT_WATCHDOG_ID "INTCAMT"
--
--/* UUIDs for AMT F/W clients */
--const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89,
--						0x9D, 0xA9, 0x15, 0x14, 0xCB,
--						0x32, 0xAB);
--
--static void mei_wd_set_start_timeout(struct mei_device *dev, u16 timeout)
--{
--	dev_dbg(dev->dev, "wd: set timeout=%d.\n", timeout);
--	memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE);
--	memcpy(dev->wd_data + MEI_WD_HDR_SIZE, &timeout, sizeof(u16));
--}
--
--/**
-- * mei_wd_host_init - connect to the watchdog client
-- *
-- * @dev: the device structure
-- * @me_cl: me client
-- *
-- * Return: -ENOTTY if wd client cannot be found
-- *         -EIO if write has failed
-- *         0 on success
-- */
--int mei_wd_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
--{
--	struct mei_cl *cl = &dev->wd_cl;
--	int ret;
--
--	mei_cl_init(cl, dev);
--
--	dev->wd_timeout = MEI_WD_DEFAULT_TIMEOUT;
--	dev->wd_state = MEI_WD_IDLE;
--
--	ret = mei_cl_link(cl, MEI_WD_HOST_CLIENT_ID);
--	if (ret < 0) {
--		dev_info(dev->dev, "wd: failed link client\n");
--		return ret;
--	}
--
--	ret = mei_cl_connect(cl, me_cl, NULL);
--	if (ret) {
--		dev_err(dev->dev, "wd: failed to connect = %d\n", ret);
--		mei_cl_unlink(cl);
--		return ret;
--	}
--
--	ret = mei_watchdog_register(dev);
--	if (ret) {
--		mei_cl_disconnect(cl);
--		mei_cl_unlink(cl);
--	}
--	return ret;
--}
--
--/**
-- * mei_wd_send - sends watch dog message to fw.
-- *
-- * @dev: the device structure
-- *
-- * Return: 0 if success,
-- *	-EIO when message send fails
-- *	-EINVAL when invalid message is to be sent
-- *	-ENODEV on flow control failure
-- */
--int mei_wd_send(struct mei_device *dev)
--{
--	struct mei_cl *cl = &dev->wd_cl;
--	struct mei_msg_hdr hdr;
--	int ret;
--
--	hdr.host_addr = cl->host_client_id;
--	hdr.me_addr = mei_cl_me_id(cl);
--	hdr.msg_complete = 1;
--	hdr.reserved = 0;
--	hdr.internal = 0;
--
--	if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_HDR_SIZE))
--		hdr.length = MEI_WD_START_MSG_SIZE;
--	else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_HDR_SIZE))
--		hdr.length = MEI_WD_STOP_MSG_SIZE;
--	else {
--		dev_err(dev->dev, "wd: invalid message is to be sent, aborting\n");
--		return -EINVAL;
--	}
--
--	ret = mei_write_message(dev, &hdr, dev->wd_data);
--	if (ret) {
--		dev_err(dev->dev, "wd: write message failed\n");
--		return ret;
--	}
--
--	ret = mei_cl_flow_ctrl_reduce(cl);
--	if (ret) {
--		dev_err(dev->dev, "wd: flow_ctrl_reduce failed.\n");
--		return ret;
--	}
--
--	return 0;
--}
--
--/**
-- * mei_wd_stop - sends watchdog stop message to fw.
-- *
-- * @dev: the device structure
-- *
-- * Return: 0 if success
-- * on error:
-- *	-EIO    when message send fails
-- *	-EINVAL when invalid message is to be sent
-- *	-ETIME  on message timeout
-- */
--int mei_wd_stop(struct mei_device *dev)
--{
--	struct mei_cl *cl = &dev->wd_cl;
--	int ret;
--
--	if (!mei_cl_is_connected(cl) ||
--	    dev->wd_state != MEI_WD_RUNNING)
--		return 0;
--
--	memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_STOP_MSG_SIZE);
--
--	dev->wd_state = MEI_WD_STOPPING;
--
--	ret = mei_cl_flow_ctrl_creds(cl);
--	if (ret < 0)
--		goto err;
--
--	if (ret && mei_hbuf_acquire(dev)) {
--		ret = mei_wd_send(dev);
--		if (ret)
--			goto err;
--		dev->wd_pending = false;
--	} else {
--		dev->wd_pending = true;
--	}
--
--	mutex_unlock(&dev->device_lock);
--
--	ret = wait_event_timeout(dev->wait_stop_wd,
--				dev->wd_state == MEI_WD_IDLE,
--				msecs_to_jiffies(MEI_WD_STOP_TIMEOUT));
--	mutex_lock(&dev->device_lock);
--	if (dev->wd_state != MEI_WD_IDLE) {
--		/* timeout */
--		ret = -ETIME;
--		dev_warn(dev->dev, "wd: stop failed to complete ret=%d\n", ret);
--		goto err;
--	}
--	dev_dbg(dev->dev, "wd: stop completed after %u msec\n",
--			MEI_WD_STOP_TIMEOUT - jiffies_to_msecs(ret));
--	return 0;
--err:
--	return ret;
--}
--
--/**
-- * mei_wd_ops_start - wd start command from the watchdog core.
-- *
-- * @wd_dev: watchdog device struct
-- *
-- * Return: 0 if success, negative errno code for failure
-- */
--static int mei_wd_ops_start(struct watchdog_device *wd_dev)
--{
--	struct mei_device *dev;
--	struct mei_cl *cl;
--	int err = -ENODEV;
--
--	dev = watchdog_get_drvdata(wd_dev);
--	if (!dev)
--		return -ENODEV;
--
--	cl = &dev->wd_cl;
--
--	mutex_lock(&dev->device_lock);
--
--	if (dev->dev_state != MEI_DEV_ENABLED) {
--		dev_dbg(dev->dev, "wd: dev_state != MEI_DEV_ENABLED  dev_state = %s\n",
--			mei_dev_state_str(dev->dev_state));
--		goto end_unlock;
--	}
--
--	if (!mei_cl_is_connected(cl)) {
--		cl_dbg(dev, cl, "MEI Driver is not connected to Watchdog Client\n");
--		goto end_unlock;
--	}
--
--	mei_wd_set_start_timeout(dev, dev->wd_timeout);
--
--	err = 0;
--end_unlock:
--	mutex_unlock(&dev->device_lock);
--	return err;
--}
--
--/**
-- * mei_wd_ops_stop -  wd stop command from the watchdog core.
-- *
-- * @wd_dev: watchdog device struct
-- *
-- * Return: 0 if success, negative errno code for failure
-- */
--static int mei_wd_ops_stop(struct watchdog_device *wd_dev)
--{
--	struct mei_device *dev;
--
--	dev = watchdog_get_drvdata(wd_dev);
--	if (!dev)
--		return -ENODEV;
--
--	mutex_lock(&dev->device_lock);
--	mei_wd_stop(dev);
--	mutex_unlock(&dev->device_lock);
--
--	return 0;
--}
--
--/**
-- * mei_wd_ops_ping - wd ping command from the watchdog core.
-- *
-- * @wd_dev: watchdog device struct
-- *
-- * Return: 0 if success, negative errno code for failure
-- */
--static int mei_wd_ops_ping(struct watchdog_device *wd_dev)
--{
--	struct mei_device *dev;
--	struct mei_cl *cl;
--	int ret;
--
--	dev = watchdog_get_drvdata(wd_dev);
--	if (!dev)
--		return -ENODEV;
--
--	cl = &dev->wd_cl;
--
--	mutex_lock(&dev->device_lock);
--
--	if (!mei_cl_is_connected(cl)) {
--		cl_err(dev, cl, "wd: not connected.\n");
--		ret = -ENODEV;
--		goto end;
--	}
--
--	dev->wd_state = MEI_WD_RUNNING;
--
--	ret = mei_cl_flow_ctrl_creds(cl);
--	if (ret < 0)
--		goto end;
--
--	/* Check if we can send the ping to HW*/
--	if (ret && mei_hbuf_acquire(dev)) {
--		dev_dbg(dev->dev, "wd: sending ping\n");
--
--		ret = mei_wd_send(dev);
--		if (ret)
--			goto end;
--		dev->wd_pending = false;
--	} else {
--		dev->wd_pending = true;
--	}
--
--end:
--	mutex_unlock(&dev->device_lock);
--	return ret;
--}
--
--/**
-- * mei_wd_ops_set_timeout - wd set timeout command from the watchdog core.
-- *
-- * @wd_dev: watchdog device struct
-- * @timeout: timeout value to set
-- *
-- * Return: 0 if success, negative errno code for failure
-- */
--static int mei_wd_ops_set_timeout(struct watchdog_device *wd_dev,
--		unsigned int timeout)
--{
--	struct mei_device *dev;
--
--	dev = watchdog_get_drvdata(wd_dev);
--	if (!dev)
--		return -ENODEV;
--
--	/* Check Timeout value */
--	if (timeout < MEI_WD_MIN_TIMEOUT || timeout > MEI_WD_MAX_TIMEOUT)
--		return -EINVAL;
--
--	mutex_lock(&dev->device_lock);
--
--	dev->wd_timeout = timeout;
--	wd_dev->timeout = timeout;
--	mei_wd_set_start_timeout(dev, dev->wd_timeout);
--
--	mutex_unlock(&dev->device_lock);
--
--	return 0;
--}
--
--/*
-- * Watchdog Device structs
-- */
--static const struct watchdog_ops wd_ops = {
--		.owner = THIS_MODULE,
--		.start = mei_wd_ops_start,
--		.stop = mei_wd_ops_stop,
--		.ping = mei_wd_ops_ping,
--		.set_timeout = mei_wd_ops_set_timeout,
--};
--static const struct watchdog_info wd_info = {
--		.identity = INTEL_AMT_WATCHDOG_ID,
--		.options = WDIOF_KEEPALIVEPING |
--			   WDIOF_SETTIMEOUT |
--			   WDIOF_ALARMONLY,
--};
--
--static struct watchdog_device amt_wd_dev = {
--		.info = &wd_info,
--		.ops = &wd_ops,
--		.timeout = MEI_WD_DEFAULT_TIMEOUT,
--		.min_timeout = MEI_WD_MIN_TIMEOUT,
--		.max_timeout = MEI_WD_MAX_TIMEOUT,
--};
--
--
--int mei_watchdog_register(struct mei_device *dev)
--{
--
--	int ret;
--
--	amt_wd_dev.parent = dev->dev;
--	/* unlock to perserve correct locking order */
--	mutex_unlock(&dev->device_lock);
--	ret = watchdog_register_device(&amt_wd_dev);
--	mutex_lock(&dev->device_lock);
--	if (ret) {
--		dev_err(dev->dev, "wd: unable to register watchdog device = %d.\n",
--			ret);
--		return ret;
--	}
--
--	dev_dbg(dev->dev, "wd: successfully register watchdog interface.\n");
--	watchdog_set_drvdata(&amt_wd_dev, dev);
--	return 0;
--}
--
--void mei_watchdog_unregister(struct mei_device *dev)
--{
--	if (watchdog_get_drvdata(&amt_wd_dev) == NULL)
--		return;
--
--	watchdog_set_drvdata(&amt_wd_dev, NULL);
--	watchdog_unregister_device(&amt_wd_dev);
--}
--
--- 
-cgit v0.12
-
diff --git a/watchdog_implement-mei-iamt-driver.patch b/watchdog_implement-mei-iamt-driver.patch
deleted file mode 100644
index dc7834c..0000000
--- a/watchdog_implement-mei-iamt-driver.patch
+++ /dev/null
@@ -1,514 +0,0 @@
-From 222818c3d84c1f3190767f5f09f2b9b9a0e0ca7f Mon Sep 17 00:00:00 2001
-From: Tomas Winkler <tomas.winkler at intel.com>
-Date: Fri, 8 Jan 2016 00:49:22 +0200
-Subject: watchdog: mei_wdt: implement MEI iAMT watchdog driver
-
-Create a driver with the generic watchdog interface
-for the MEI iAMT watchdog device.
-
-Signed-off-by: Alexander Usyskin <alexander.usyskin at intel.com>
-Signed-off-by: Tomas Winkler <tomas.winkler at intel.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
-
-PVE NOTES: the old code always enables this watchdog, but we do not
-want to use this watchdog because it does not reboot the host, and min
-timeout is 120 seconds. With this patch, we can simply blacklist mei_wdt.
-
----
- Documentation/misc-devices/mei/mei.txt |  12 +-
- MAINTAINERS                            |   1 +
- drivers/watchdog/Kconfig               |  15 ++
- drivers/watchdog/Makefile              |   1 +
- drivers/watchdog/mei_wdt.c             | 404 +++++++++++++++++++++++++++++++++
- 5 files changed, 427 insertions(+), 6 deletions(-)
- create mode 100644 drivers/watchdog/mei_wdt.c
-
-diff --git a/Documentation/misc-devices/mei/mei.txt b/Documentation/misc-devices/mei/mei.txt
-index 91c1fa3..2b80a0c 100644
---- a/Documentation/misc-devices/mei/mei.txt
-+++ b/Documentation/misc-devices/mei/mei.txt
-@@ -231,15 +231,15 @@ IT knows when a platform crashes even when there is a hard failure on the host.
- The Intel AMT Watchdog is composed of two parts:
- 	1) Firmware feature - receives the heartbeats
- 	   and sends an event when the heartbeats stop.
--	2) Intel MEI driver - connects to the watchdog feature, configures the
--	   watchdog and sends the heartbeats.
-+	2) Intel MEI iAMT watchdog driver - connects to the watchdog feature,
-+	   configures the watchdog and sends the heartbeats.
- 
--The Intel MEI driver uses the kernel watchdog API to configure the Intel AMT
--Watchdog and to send heartbeats to it. The default timeout of the
-+The Intel iAMT watchdog MEI driver uses the kernel watchdog API to configure
-+the Intel AMT Watchdog and to send heartbeats to it. The default timeout of the
- watchdog is 120 seconds.
- 
--If the Intel AMT Watchdog feature does not exist (i.e. the connection failed),
--the Intel MEI driver will disable the sending of heartbeats.
-+If the Intel AMT is not enabled in the firmware then the watchdog client won't enumerate
-+on the me client bus and watchdog devices won't be exposed.
- 
- 
- Supported Chipsets
-diff --git a/MAINTAINERS b/MAINTAINERS
-index 30aca4a..d63b3c7 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -5751,6 +5751,7 @@ S:	Supported
- F:	include/uapi/linux/mei.h
- F:	include/linux/mei_cl_bus.h
- F:	drivers/misc/mei/*
-+F:	drivers/watchdog/mei_wdt.c
- F:	Documentation/misc-devices/mei/*
- 
- INTEL MIC DRIVERS (mic)
-diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
-index 4f0e7be..57f8721 100644
---- a/drivers/watchdog/Kconfig
-+++ b/drivers/watchdog/Kconfig
-@@ -1212,6 +1212,21 @@ config SBC_EPX_C3_WATCHDOG
- 	  To compile this driver as a module, choose M here: the
- 	  module will be called sbc_epx_c3.
- 
-+config INTEL_MEI_WDT
-+	tristate "Intel MEI iAMT Watchdog"
-+	depends on INTEL_MEI && X86
-+	select WATCHDOG_CORE
-+	---help---
-+	  A device driver for the Intel MEI iAMT watchdog.
-+
-+	  The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
-+	  Whenever the OS hangs or crashes, iAMT will send an event
-+	  to any subscriber to this event. The watchdog doesn't reset the
-+	  the platform.
-+
-+	  To compile this driver as a module, choose M here:
-+	  the module will be called mei_wdt.
-+
- # M32R Architecture
- 
- # M68K Architecture
-diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
-index f566753..efc4f78 100644
---- a/drivers/watchdog/Makefile
-+++ b/drivers/watchdog/Makefile
-@@ -126,6 +126,7 @@ obj-$(CONFIG_MACHZ_WDT) += machzwd.o
- obj-$(CONFIG_SBC_EPX_C3_WATCHDOG) += sbc_epx_c3.o
- obj-$(CONFIG_INTEL_SCU_WATCHDOG) += intel_scu_watchdog.o
- obj-$(CONFIG_INTEL_MID_WATCHDOG) += intel-mid_wdt.o
-+obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o
- 
- # M32R Architecture
- 
-diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
-new file mode 100644
-index 0000000..32e3e1d
---- /dev/null
-+++ b/drivers/watchdog/mei_wdt.c
-@@ -0,0 +1,404 @@
-+/*
-+ * Intel Management Engine Interface (Intel MEI) Linux driver
-+ * Copyright (c) 2015, Intel Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-+ * more details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/watchdog.h>
-+
-+#include <linux/uuid.h>
-+#include <linux/mei_cl_bus.h>
-+
-+/*
-+ * iAMT Watchdog Device
-+ */
-+#define INTEL_AMT_WATCHDOG_ID "iamt_wdt"
-+
-+#define MEI_WDT_DEFAULT_TIMEOUT   120  /* seconds */
-+#define MEI_WDT_MIN_TIMEOUT       120  /* seconds */
-+#define MEI_WDT_MAX_TIMEOUT     65535  /* seconds */
-+
-+/* Commands */
-+#define MEI_MANAGEMENT_CONTROL 0x02
-+
-+/* MEI Management Control version number */
-+#define MEI_MC_VERSION_NUMBER  0x10
-+
-+/* Sub Commands */
-+#define MEI_MC_START_WD_TIMER_REQ  0x13
-+#define MEI_MC_STOP_WD_TIMER_REQ   0x14
-+
-+/**
-+ * enum mei_wdt_state - internal watchdog state
-+ *
-+ * @MEI_WDT_IDLE: wd is idle and not opened
-+ * @MEI_WDT_START: wd was opened, start was called
-+ * @MEI_WDT_RUNNING: wd is expecting keep alive pings
-+ * @MEI_WDT_STOPPING: wd is stopping and will move to IDLE
-+ */
-+enum mei_wdt_state {
-+	MEI_WDT_IDLE,
-+	MEI_WDT_START,
-+	MEI_WDT_RUNNING,
-+	MEI_WDT_STOPPING,
-+};
-+
-+/**
-+ * struct mei_wdt - mei watchdog driver
-+ * @wdd: watchdog device
-+ *
-+ * @cldev: mei watchdog client device
-+ * @state: watchdog internal state
-+ * @timeout: watchdog current timeout
-+ */
-+struct mei_wdt {
-+	struct watchdog_device wdd;
-+
-+	struct mei_cl_device *cldev;
-+	enum mei_wdt_state state;
-+	u16 timeout;
-+};
-+
-+/*
-+ * struct mei_mc_hdr - Management Control Command Header
-+ *
-+ * @command: Management Control (0x2)
-+ * @bytecount: Number of bytes in the message beyond this byte
-+ * @subcommand: Management Control Subcommand
-+ * @versionnumber: Management Control Version (0x10)
-+ */
-+struct mei_mc_hdr {
-+	u8 command;
-+	u8 bytecount;
-+	u8 subcommand;
-+	u8 versionnumber;
-+};
-+
-+/**
-+ * struct mei_wdt_start_request watchdog start/ping
-+ *
-+ * @hdr: Management Control Command Header
-+ * @timeout: timeout value
-+ * @reserved: reserved (legacy)
-+ */
-+struct mei_wdt_start_request {
-+	struct mei_mc_hdr hdr;
-+	u16 timeout;
-+	u8 reserved[17];
-+} __packed;
-+
-+/**
-+ * struct mei_wdt_stop_request - watchdog stop
-+ *
-+ * @hdr: Management Control Command Header
-+ */
-+struct mei_wdt_stop_request {
-+	struct mei_mc_hdr hdr;
-+} __packed;
-+
-+/**
-+ * mei_wdt_ping - send wd start/ping command
-+ *
-+ * @wdt: mei watchdog device
-+ *
-+ * Return: 0 on success,
-+ *         negative errno code on failure
-+ */
-+static int mei_wdt_ping(struct mei_wdt *wdt)
-+{
-+	struct mei_wdt_start_request req;
-+	const size_t req_len = sizeof(req);
-+	int ret;
-+
-+	memset(&req, 0, req_len);
-+	req.hdr.command = MEI_MANAGEMENT_CONTROL;
-+	req.hdr.bytecount = req_len - offsetof(struct mei_mc_hdr, subcommand);
-+	req.hdr.subcommand = MEI_MC_START_WD_TIMER_REQ;
-+	req.hdr.versionnumber = MEI_MC_VERSION_NUMBER;
-+	req.timeout = wdt->timeout;
-+
-+	ret = mei_cldev_send(wdt->cldev, (u8 *)&req, req_len);
-+	if (ret < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+/**
-+ * mei_wdt_stop - send wd stop command
-+ *
-+ * @wdt: mei watchdog device
-+ *
-+ * Return: 0 on success,
-+ *         negative errno code on failure
-+ */
-+static int mei_wdt_stop(struct mei_wdt *wdt)
-+{
-+	struct mei_wdt_stop_request req;
-+	const size_t req_len = sizeof(req);
-+	int ret;
-+
-+	memset(&req, 0, req_len);
-+	req.hdr.command = MEI_MANAGEMENT_CONTROL;
-+	req.hdr.bytecount = req_len - offsetof(struct mei_mc_hdr, subcommand);
-+	req.hdr.subcommand = MEI_MC_STOP_WD_TIMER_REQ;
-+	req.hdr.versionnumber = MEI_MC_VERSION_NUMBER;
-+
-+	ret = mei_cldev_send(wdt->cldev, (u8 *)&req, req_len);
-+	if (ret < 0)
-+		return ret;
-+
-+	return 0;
-+}
-+
-+/**
-+ * mei_wdt_ops_start - wd start command from the watchdog core.
-+ *
-+ * @wdd: watchdog device
-+ *
-+ * Return: 0 on success or -ENODEV;
-+ */
-+static int mei_wdt_ops_start(struct watchdog_device *wdd)
-+{
-+	struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
-+
-+	wdt->state = MEI_WDT_START;
-+	wdd->timeout = wdt->timeout;
-+	return 0;
-+}
-+
-+/**
-+ * mei_wdt_ops_stop - wd stop command from the watchdog core.
-+ *
-+ * @wdd: watchdog device
-+ *
-+ * Return: 0 if success, negative errno code for failure
-+ */
-+static int mei_wdt_ops_stop(struct watchdog_device *wdd)
-+{
-+	struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
-+	int ret;
-+
-+	if (wdt->state != MEI_WDT_RUNNING)
-+		return 0;
-+
-+	wdt->state = MEI_WDT_STOPPING;
-+
-+	ret = mei_wdt_stop(wdt);
-+	if (ret)
-+		return ret;
-+
-+	wdt->state = MEI_WDT_IDLE;
-+
-+	return 0;
-+}
-+
-+/**
-+ * mei_wdt_ops_ping - wd ping command from the watchdog core.
-+ *
-+ * @wdd: watchdog device
-+ *
-+ * Return: 0 if success, negative errno code on failure
-+ */
-+static int mei_wdt_ops_ping(struct watchdog_device *wdd)
-+{
-+	struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
-+	int ret;
-+
-+	if (wdt->state != MEI_WDT_START && wdt->state != MEI_WDT_RUNNING)
-+		return 0;
-+
-+	ret = mei_wdt_ping(wdt);
-+	if (ret)
-+		return ret;
-+
-+	wdt->state = MEI_WDT_RUNNING;
-+
-+	return 0;
-+}
-+
-+/**
-+ * mei_wdt_ops_set_timeout - wd set timeout command from the watchdog core.
-+ *
-+ * @wdd: watchdog device
-+ * @timeout: timeout value to set
-+ *
-+ * Return: 0 if success, negative errno code for failure
-+ */
-+static int mei_wdt_ops_set_timeout(struct watchdog_device *wdd,
-+				   unsigned int timeout)
-+{
-+
-+	struct mei_wdt *wdt = watchdog_get_drvdata(wdd);
-+
-+	/* valid value is already checked by the caller */
-+	wdt->timeout = timeout;
-+	wdd->timeout = timeout;
-+
-+	return 0;
-+}
-+
-+static const struct watchdog_ops wd_ops = {
-+	.owner       = THIS_MODULE,
-+	.start       = mei_wdt_ops_start,
-+	.stop        = mei_wdt_ops_stop,
-+	.ping        = mei_wdt_ops_ping,
-+	.set_timeout = mei_wdt_ops_set_timeout,
-+};
-+
-+/* not const as the firmware_version field need to be retrieved */
-+static struct watchdog_info wd_info = {
-+	.identity = INTEL_AMT_WATCHDOG_ID,
-+	.options  = WDIOF_KEEPALIVEPING |
-+		    WDIOF_SETTIMEOUT |
-+		    WDIOF_ALARMONLY,
-+};
-+
-+/**
-+ * mei_wdt_unregister - unregister from the watchdog subsystem
-+ *
-+ * @wdt: mei watchdog device
-+ */
-+static void mei_wdt_unregister(struct mei_wdt *wdt)
-+{
-+	watchdog_unregister_device(&wdt->wdd);
-+	watchdog_set_drvdata(&wdt->wdd, NULL);
-+}
-+
-+/**
-+ * mei_wdt_register - register with the watchdog subsystem
-+ *
-+ * @wdt: mei watchdog device
-+ *
-+ * Return: 0 if success, negative errno code for failure
-+ */
-+static int mei_wdt_register(struct mei_wdt *wdt)
-+{
-+	struct device *dev;
-+	int ret;
-+
-+	if (!wdt || !wdt->cldev)
-+		return -EINVAL;
-+
-+	dev = &wdt->cldev->dev;
-+
-+	wdt->wdd.info = &wd_info;
-+	wdt->wdd.ops = &wd_ops;
-+	wdt->wdd.parent = dev;
-+	wdt->wdd.timeout = MEI_WDT_DEFAULT_TIMEOUT;
-+	wdt->wdd.min_timeout = MEI_WDT_MIN_TIMEOUT;
-+	wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
-+
-+	watchdog_set_drvdata(&wdt->wdd, wdt);
-+	ret = watchdog_register_device(&wdt->wdd);
-+	if (ret) {
-+		dev_err(dev, "unable to register watchdog device = %d.\n", ret);
-+		watchdog_set_drvdata(&wdt->wdd, NULL);
-+	}
-+
-+	return ret;
-+}
-+
-+static int mei_wdt_probe(struct mei_cl_device *cldev,
-+			 const struct mei_cl_device_id *id)
-+{
-+	struct mei_wdt *wdt;
-+	int ret;
-+
-+	wdt = kzalloc(sizeof(struct mei_wdt), GFP_KERNEL);
-+	if (!wdt)
-+		return -ENOMEM;
-+
-+	wdt->timeout = MEI_WDT_DEFAULT_TIMEOUT;
-+	wdt->state = MEI_WDT_IDLE;
-+	wdt->cldev = cldev;
-+	mei_cldev_set_drvdata(cldev, wdt);
-+
-+	ret = mei_cldev_enable(cldev);
-+	if (ret < 0) {
-+		dev_err(&cldev->dev, "Could not enable cl device\n");
-+		goto err_out;
-+	}
-+
-+	wd_info.firmware_version = mei_cldev_ver(cldev);
-+
-+	ret = mei_wdt_register(wdt);
-+	if (ret)
-+		goto err_disable;
-+
-+	return 0;
-+
-+err_disable:
-+	mei_cldev_disable(cldev);
-+
-+err_out:
-+	kfree(wdt);
-+
-+	return ret;
-+}
-+
-+static int mei_wdt_remove(struct mei_cl_device *cldev)
-+{
-+	struct mei_wdt *wdt = mei_cldev_get_drvdata(cldev);
-+
-+	mei_wdt_unregister(wdt);
-+
-+	mei_cldev_disable(cldev);
-+
-+	kfree(wdt);
-+
-+	return 0;
-+}
-+
-+#define MEI_UUID_WD UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, \
-+			    0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB)
-+
-+static struct mei_cl_device_id mei_wdt_tbl[] = {
-+	{ .uuid = MEI_UUID_WD, .version = 0x1},
-+	/* required last entry */
-+	{ }
-+};
-+MODULE_DEVICE_TABLE(mei, mei_wdt_tbl);
-+
-+static struct mei_cl_driver mei_wdt_driver = {
-+	.id_table = mei_wdt_tbl,
-+	.name = KBUILD_MODNAME,
-+
-+	.probe = mei_wdt_probe,
-+	.remove = mei_wdt_remove,
-+};
-+
-+static int __init mei_wdt_init(void)
-+{
-+	int ret;
-+
-+	ret = mei_cldev_driver_register(&mei_wdt_driver);
-+	if (ret) {
-+		pr_err(KBUILD_MODNAME ": module registration failed\n");
-+		return ret;
-+	}
-+	return 0;
-+}
-+
-+static void __exit mei_wdt_exit(void)
-+{
-+	mei_cldev_driver_unregister(&mei_wdt_driver);
-+}
-+
-+module_init(mei_wdt_init);
-+module_exit(mei_wdt_exit);
-+
-+MODULE_AUTHOR("Intel Corporation");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Device driver for Intel MEI iAMT watchdog");
--- 
-cgit v0.12
-
-- 
2.1.4





More information about the pve-devel mailing list