code:
Subject: Add blacklist of usb hid modules

IBM Blade Center HS20 can connect PS2 kerboard and mouse, It is USB emulation.
This devices need HID_QUIRK_IGNORE option.

This patch is workaround.

[ rediffed for 2.6.28 -- herton ]
Signed-off-by: Go Taniguchi <go@turbolinux.co.jp>

---
 drivers/hid/hid-core.c |    2 ++
 drivers/hid/hid-ids.h  |    2 ++
 2 files changed, 4 insertions(+)

--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -2062,6 +2062,8 @@ static const struct hid_device_id hid_ig
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, 0x4001) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, 0x4002) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_410) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_JABRA, USB_DEVICE_ID_JABRA_SPEAK_510) },
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -46,6 +46,8 @@
 #define USB_VENDOR_ID_AFATECH		0x15a4
 #define USB_DEVICE_ID_AFATECH_AF9016	0x9016

+#define USB_VENDOR_ID_IBM		0x04b3
+
 #define USB_VENDOR_ID_AIPTEK		0x08ca
 #define USB_DEVICE_ID_AIPTEK_01		0x0001
 #define USB_DEVICE_ID_AIPTEK_10		0x0010

repo_name: ayhanyalcinsoy/main


code:
---
 drivers/ide/sis5513.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff -p -up linux-2.6.28/drivers/ide/sis5513.c.orig linux-2.6.28/drivers/ide/sis5513.c
--- linux-2.6.28/drivers/ide/sis5513.c.orig	2008-12-08 12:41:13.000000000 -0500
+++ linux-2.6.28/drivers/ide/sis5513.c	2008-12-08 12:51:32.000000000 -0500
@@ -412,6 +412,15 @@ static int __devinit sis_find_family(str
 						pci_name(dev));
 				}
 			}
+			else if (trueid == 0x180) { /* sis965L */
+				u16 pci_command;
+				pci_read_config_word(dev, PCI_COMMAND, &pci_command);
+				pci_command &= ~PCI_COMMAND_INTX_DISABLE;
+				pci_write_config_word(dev, PCI_COMMAND, pci_command);
+				chipset_family = ATA_133;
+				printk(KERN_INFO DRV_NAME " %s: SiS 965 IDE UDMA133 controller\n",
+					pci_name(dev));
+			}
 	}

 	if (!chipset_family) { /* Belongs to pci-quirks */


code:
From Thierry Vignaud <tvignaud@mandriva.com>  (Mandriva)

We now lacks /usr/include/linux/pci_ids.h which break ldetect build...
Can you readd it please?
Thanks
---
 include/linux/Kbuild |    1 +
 1 file changed, 1 insertion(+)

--- linux/include/uapi/linux/Kbuild.include-kbuild-export-pci_ids.orig
+++ linux/include/uapi/linux/Kbuild
@@ -277,6 +277,7 @@ header-y += param.h
 header-y += parport.h
 header-y += patchkey.h
 header-y += pci.h
+header-y += pci_ids.h
 header-y += pci_regs.h
 header-y += perf_event.h
 header-y += personality.h


code:
From 993b3a3f80a7842a48cd46c2b41e1b3ef6302468 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Fri, 24 Oct 2014 14:55:24 -0700
Subject: [PATCH] Input: i8042 - quirks for Fujitsu Lifebook A544 and Lifebook
 AH544

These models need i8042.notimeout, otherwise the touchpad will not work.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=69731
BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1111138
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/serio/i8042-x86ia64io.h | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index a0bcbb6..aa9b299 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -364,6 +364,22 @@ static const struct dmi_system_id __initconst i8042_dmi_notimeout_table[] = {
 		},
 	},
 	{
+		/* Fujitsu A544 laptop */
+		/* https://bugzilla.redhat.com/show_bug.cgi?id=1111138 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK A544"),
+		},
+	},
+	{
+		/* Fujitsu AH544 laptop */
+		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK AH544"),
+		},
+	},
+	{
 		/* Fujitsu U574 laptop */
 		/* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */
 		.matches = {
--
2.1.2


code:
From: Arindam Nath <arindam.nath@amd.com>

Change History
--------------

v3:
- add Fixes and CC tags
- add link to Bugzilla

v2: changes suggested by Joerg
- add flush flag to improve efficiency of flush operation

v1:
- The idea behind flush queues is to defer the IOTLB flushing
  for domains for which the mappings are no longer valid. We
  add such domains in queue_add(), and when the queue size
  reaches FLUSH_QUEUE_SIZE, we perform __queue_flush().

  Since we have already taken lock before __queue_flush()
  is called, we need to make sure the IOTLB flushing is
  performed as quickly as possible.

  In the current implementation, we perform IOTLB flushing
  for all domains irrespective of which ones were actually
  added in the flush queue initially. This can be quite
  expensive especially for domains for which unmapping is
  not required at this point of time.

  This patch makes use of domain information in
  'struct flush_queue_entry' to make sure we only flush
  IOTLBs for domains who need it, skipping others.

Bugzilla: https://bugs.freedesktop.org/101029
Fixes: b1516a14657a ("iommu/amd: Implement flush queue")
Cc: stable@vger.kernel.org
Suggested-by: Joerg Roedel <joro@8bytes.org>
Signed-off-by: Arindam Nath <arindam.nath@amd.com>
---
 drivers/iommu/amd_iommu.c       | 27 ++++++++++++++++++++-------
 drivers/iommu/amd_iommu_types.h |  2 ++
 2 files changed, 22 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
index 63cacf5..1edeebec 100644
--- a/drivers/iommu/amd_iommu.c
+++ b/drivers/iommu/amd_iommu.c
@@ -2227,15 +2227,26 @@ static struct iommu_group *amd_iommu_device_group(struct device *dev)

 static void __queue_flush(struct flush_queue *queue)
 {
-	struct protection_domain *domain;
-	unsigned long flags;
 	int idx;

-	/* First flush TLB of all known domains */
-	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
-	list_for_each_entry(domain, &amd_iommu_pd_list, list)
-		domain_flush_tlb(domain);
-	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
+	/* First flush TLB of all domains which were added to flush queue */
+	for (idx = 0; idx < queue->next; ++idx) {
+		struct flush_queue_entry *entry;
+
+		entry = queue->entries + idx;
+
+		/*
+		 * There might be cases where multiple IOVA entries for the
+		 * same domain are queued in the flush queue. To avoid
+		 * flushing the same domain again, we check whether the
+		 * flag is set or not. This improves the efficiency of
+		 * flush operation.
+		 */
+		if (!entry->dma_dom->domain.already_flushed) {
+			entry->dma_dom->domain.already_flushed = true;
+			domain_flush_tlb(&entry->dma_dom->domain);
+		}
+	}

 	/* Wait until flushes have completed */
 	domain_flush_complete(NULL);
@@ -2289,6 +2300,8 @@ static void queue_add(struct dma_ops_domain *dma_dom,
 	pages     = __roundup_pow_of_two(pages);
 	address >>= PAGE_SHIFT;

+	dma_dom->domain.already_flushed = false;
+
 	queue = get_cpu_ptr(&flush_queue);
 	spin_lock_irqsave(&queue->lock, flags);

diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h
index 4de8f41..4f5519d 100644
--- a/drivers/iommu/amd_iommu_types.h
+++ b/drivers/iommu/amd_iommu_types.h
@@ -454,6 +454,8 @@ struct protection_domain {
 	bool updated;		/* complete domain flush required */
 	unsigned dev_cnt;	/* devices assigned to this domain */
 	unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
+	bool already_flushed;	/* flag to avoid flushing the same domain again
+				   in a single invocation of __queue_flush() */
 };

 /*


code:
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f976df4..32c883b 100644
--- a/drivers/media/usb/pwc/pwc-if.c
+++ b/drivers/media/usb/pwc/pwc-if.c
@@ -119,7 +119,7 @@ static void usb_pwc_disconnect(struct us
 static void pwc_isoc_cleanup(struct pwc_device *pdev);

 static struct usb_driver pwc_driver = {
-	.name =			"Philips webcam",	/* name */
+	.name =			"pwc",	/* name */
 	.id_table =		pwc_device_table,
 	.probe =		usb_pwc_probe,		/* probe() */
 	.disconnect =		usb_pwc_disconnect,	/* disconnect() */


code:
Subject: mpt scsi modules for VMWare's emulated

The attached patch is a workaround for a bug in VMWare's emulated LSI
Fusion SCSI HBA.  The emulated firmware returns zero for the maximum
number of attached devices; the real firmware returns a positive
number.  Therefore, the kernel that boots and works fine on bare metal
will fail on VMWare because this firmware value is handed to the SCSI
midlayer, which then skips the entire bus scan.

F7 bz 241935

The patch below was submitted by Eric Moore of LSI to the linux-scsi
mailing list:

http://marc.info/?l=linux-scsi&m=117432237404247

then immediately rejected by Christoph Hellwig, who prefers that
VMWare fix their emulation instead.

This patch is workaround.

---
 drivers/message/fusion/mptbase.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -3051,8 +3051,19 @@ GetPortFacts(MPT_ADAPTER *ioc, int portn
 	pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
 	pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);

-	max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
-	    pfacts->MaxDevices;
+	switch (ioc->bus_type) {
+	case SAS:
+		max_id = pfacts->PortSCSIID;
+		break;
+	case FC:
+		max_id = pfacts->MaxDevices;
+		break;
+	case SPI:
+	default:
+		max_id = MPT_MAX_SCSI_DEVICES;
+		break;
+	}
+
 	ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
 	ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;


code:
Adapt to netlink changes in 3.6

Signed-off-by: Thomas Backlund <tmb@mageia.org>

--- linux/net/ipv4/netfilter/ipt_IFWLOG.c.orig	2012-10-17 22:44:57.000000000 +0300
+++ linux/net/ipv4/netfilter/ipt_IFWLOG.c	2012-10-17 23:17:10.012725918 +0300
@@ -56,9 +56,9 @@ static void send_packet(const struct nl_
 		return;
 	}

-	nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh));
+	nlh = nlmsg_put(skb, 0, 0, 0, size - sizeof(*nlh), 0);

-	memcpy(NLMSG_DATA(nlh), (const void *) msg, sizeof(*msg));
+	memcpy(nlmsg_data(nlh), (const void *) msg, sizeof(*msg));

 	NETLINK_CB(skb).pid = 0;  /* from kernel */
 	NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF;
@@ -169,9 +169,11 @@ static struct xt_target ipt_IFWLOG = {
 static int __init ipt_ifwlog_init(void)
 {
 	int err;
+	struct netlink_kernel_cfg cfg = {
+		.groups = IFWLOGNLGRP_MAX,
+	};

-	nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, IFWLOGNLGRP_MAX,
-				   NULL, NULL, THIS_MODULE);
+	nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, THIS_MODULE, &cfg);
 	if (!nl) {
 		PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
 		return -ENOMEM;


code:
--- linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_IFWLOG.c.orig	2010-07-30 21:17:30.000000000 +0300
+++ linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_IFWLOG.c	2010-07-31 13:46:33.834611944 +0300
@@ -135,7 +135,7 @@ static void ipt_IFWLOG_packet(const stru
 }

 static unsigned int ipt_IFWLOG_target(struct sk_buff *skb,
-				      const struct xt_target_param *target_param)
+				      const struct xt_action_param *target_param)
 {
 	const struct ipt_IFWLOG_info *info = target_param->targinfo;

@@ -144,17 +144,17 @@ static unsigned int ipt_IFWLOG_target(st
 	return IPT_CONTINUE;
 }

-static bool ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
+static int ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
 {
 	const struct ipt_IFWLOG_info *info = tgchk_param->targinfo;

 	if (info->prefix[sizeof(info->prefix)-1] != '\0') {
 		DEBUGP("IFWLOG: prefix term %i\n",
 		       info->prefix[sizeof(info->prefix)-1]);
-		return false;
+		return -EINVAL;
 	}

-	return true;
+	return 0;
 }

 static struct xt_target ipt_IFWLOG = {


code:
 net/ipv4/netfilter/ipt_IFWLOG.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- linux-2.6.37-rc3-git1-tmb0.3/net/ipv4/netfilter/ipt_IFWLOG.c.orig	2010-11-24 21:58:36.000000000 +0200
+++ linux-2.6.37-rc3-git1-tmb0.3/net/ipv4/netfilter/ipt_IFWLOG.c	2010-11-25 13:08:55.719379646 +0200
@@ -141,7 +141,7 @@ static unsigned int ipt_IFWLOG_target(st

 	ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info);

-	return IPT_CONTINUE;
+	return XT_CONTINUE;
 }

 static int ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)


code:
--- linux-3.7-rc8/net/ipv4/netfilter/ipt_IFWLOG.c.orig	2012-12-06 19:50:10.000000000 +0200
+++ linux-3.7-rc8/net/ipv4/netfilter/ipt_IFWLOG.c	2012-12-06 20:55:23.669152916 +0200
@@ -60,7 +60,7 @@ static void send_packet(const struct nl_

 	memcpy(nlmsg_data(nlh), (const void *) msg, sizeof(*msg));

-	NETLINK_CB(skb).pid = 0;  /* from kernel */
+	NETLINK_CB(skb).portid = 0;  /* from kernel */
 	NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF;

 	if (nl) {
@@ -173,7 +173,7 @@ static int __init ipt_ifwlog_init(void)
 		.groups = IFWLOGNLGRP_MAX,
 	};

-	nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, THIS_MODULE, &cfg);
+	nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, &cfg);
 	if (!nl) {
 		PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
 		return -ENOMEM;


code:
ipt_IFWLOG: Mandriva changes

This patch holds all the Mandriva changes done in ipt_IFWLOG
netfilter module.

This work is mostly done by Thomas Backlund, Herton R. Krzesinski
and Luiz Fernando N. Capitulino.

Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>

---
 include/linux/netfilter_ipv4/Kbuild       |    1
 include/linux/netfilter_ipv4/ipt_IFWLOG.h |   23 +++++-
 net/ipv4/netfilter/ipt_IFWLOG.c           |  108 +++++++++++++++---------------
 3 files changed, 77 insertions(+), 55 deletions(-)

diff -p -up linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h
--- linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h.orig	2008-12-12 10:55:07.000000000 -0500
+++ linux-2.6.28/include/linux/netfilter_ipv4/ipt_IFWLOG.h	2008-12-12 10:56:30.000000000 -0500
@@ -1,10 +1,25 @@
-#ifndef _IPT_IFWLOG_H
-#define _IPT_IFWLOG_H
+#ifndef _LINUX_IPT_IFWLOG_H
+#define _LINUX_IPT_IFWLOG_H

 #ifndef NETLINK_IFWLOG
-#define NETLINK_IFWLOG  19
+#define NETLINK_IFWLOG  20
 #endif

+#ifndef __KERNEL__
+/* Multicast groups - backwards compatiblility for userspace */
+#define IFWLOG_NLGRP_NONE 0x00000000
+#define IFWLOG_NLGRP_DEF  0x00000001 /* default message group */
+#endif
+
+enum {
+	IFWLOGNLGRP_NONE,
+#define IFWLOGNLGRP_NONE IFWLOGNLGRP_NONE
+	IFWLOGNLGRP_DEF,
+#define IFWLOGNLGRP_DEF IFWLOGNLGRP_DEF
+	__IFWLOGNLGRP_MAX
+};
+#define IFWLOGNLGRP_MAX (__IFWLOGNLGRP_MAX - 1)
+
 #define PREFSIZ         32

 struct nl_msg {				/* Netlink message */
@@ -23,4 +38,4 @@ struct ipt_IFWLOG_info {
 	char prefix[PREFSIZ];
 };

-#endif /* _IPT_IFWLOG_H */
+#endif /* _LINUX_IPT_IFWLOG_H */
diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c
--- linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c.orig	2008-12-12 10:55:07.000000000 -0500
+++ linux-2.6.28/net/ipv4/netfilter/ipt_IFWLOG.c	2008-12-12 10:57:16.000000000 -0500
@@ -4,6 +4,14 @@
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
+ *
+ * 2007-10-10 Thomas Backlund <tmb@mandriva.org>: build fixes for 2.6.22.9
+ * 2007-11-11 Herton Krzesinski <herton@mandriva.com>: build fixes for 2.6.24-rc
+ * 2007-12-03 Luiz Capitulino <lcapitulino@mandriva.com.br>: v1.1
+ * 		- Better multicast group usage
+ * 		- Coding style fixes
+ * 		- Do not return -EINVAL by default in ipt_ifwlog_init()
+ * 		- Minor refinements
  */

 #include <linux/module.h>
@@ -19,12 +27,10 @@
 #include <linux/string.h>

 #include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_IFWLOG.h>

-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
-MODULE_DESCRIPTION("Interactive firewall logging and module");

 #if 0
 #define DEBUGP PRINTR
@@ -36,44 +42,41 @@ MODULE_DESCRIPTION("Interactive firewall

 static struct sock *nl;

-#define GROUP 10
-
 /* send struct to userspace */
-static void send_packet(struct nl_msg msg)
+static void send_packet(const struct nl_msg *msg)
 {
 	struct sk_buff *skb = NULL;
 	struct nlmsghdr *nlh;
+	unsigned int size;

-	skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC);
+	size = NLMSG_SPACE(sizeof(*msg));
+	skb = alloc_skb(size, GFP_ATOMIC);
 	if (!skb) {
 		PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n");
-		return ;
+		return;
 	}

-	nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh));
+	nlh = NLMSG_PUT(skb, 0, 0, 0, size - sizeof(*nlh));

-	memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg));
+	memcpy(NLMSG_DATA(nlh), (const void *) msg, sizeof(*msg));

 	NETLINK_CB(skb).pid = 0;  /* from kernel */
-	NETLINK_CB(skb).dst_pid = 0;  /* multicast */
-	NETLINK_CB(skb).dst_group = 10;
+	NETLINK_CB(skb).dst_group = IFWLOGNLGRP_DEF;

 	if (nl) {
 		DEBUGP(KERN_WARNING
 		       "IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n",
 		       (long)nlh->nlmsg_len,  nlh->nlmsg_type, nlh->nlmsg_flags,
 		       (long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid);
-		DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix);
+		DEBUGP(KERN_WARNING "prefix : %s\n", msg->prefix);

-		netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC);
-		return ;
+		netlink_broadcast(nl, skb, 0, IFWLOGNLGRP_DEF, GFP_ATOMIC);
+		return;
 	}

- nlmsg_failure:
-        if (skb)
-                kfree_skb(skb);
-        PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
-        return ;
+nlmsg_failure:
+	kfree_skb(skb);
+	PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
 }

 /* fill struct for userspace */
@@ -128,73 +131,76 @@ static void ipt_IFWLOG_packet(const stru
 	do_gettimeofday((struct timeval *)&tv);
         msg.timestamp_sec = tv.tv_sec;

-	send_packet(msg);
+	send_packet(&msg);
 }

-static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb,
-				      const struct net_device *in,
-				      const struct net_device *out,
-				      unsigned int hooknum,
-				      const void *targinfo,
-				      void *userinfo)
+static unsigned int ipt_IFWLOG_target(struct sk_buff *skb,
+				      const struct xt_target_param *target_param)
 {
-	const struct ipt_IFWLOG_info *info = targinfo;
+	const struct ipt_IFWLOG_info *info = target_param->targinfo;

-	ipt_IFWLOG_packet(*pskb, in, out, info);
+	ipt_IFWLOG_packet(skb, target_param->in, target_param->out, info);

 	return IPT_CONTINUE;
 }

-static int ipt_IFWLOG_checkentry(const char *tablename,
-				 const struct ipt_entry *e,
-				 void *targinfo,
-				 unsigned int targinfosize,
-				 unsigned int hook_mask)
+static bool ipt_IFWLOG_checkentry(const struct xt_tgchk_param *tgchk_param)
 {
-	const struct ipt_IFWLOG_info *info = targinfo;
+	const struct ipt_IFWLOG_info *info = tgchk_param->targinfo;

 	if (info->prefix[sizeof(info->prefix)-1] != '\0') {
 		DEBUGP("IFWLOG: prefix term %i\n",
 		       info->prefix[sizeof(info->prefix)-1]);
-		return 0;
+		return false;
 	}

-	return 1;
+	return true;
 }

-static struct ipt_target ipt_IFWLOG = {
+static struct xt_target ipt_IFWLOG = {
 	.name		= "IFWLOG",
+	.family		= AF_INET,
 	.target		= ipt_IFWLOG_target,
 	.targetsize	= sizeof(struct ipt_IFWLOG_info),
 	.checkentry	= ipt_IFWLOG_checkentry,
 	.me		= THIS_MODULE,
 };

-static int __init init(void)
+static int __init ipt_ifwlog_init(void)
 {
-	nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE);
-        if (!nl) {
-                PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
-                return -EINVAL;
-        }
+	int err;

-	if (ipt_register_target(&ipt_IFWLOG)) {
+	nl = netlink_kernel_create(&init_net, NETLINK_IFWLOG, IFWLOGNLGRP_MAX,
+				   NULL, NULL, THIS_MODULE);
+	if (!nl) {
+		PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
+		return -ENOMEM;
+	}
+
+	err = xt_register_target(&ipt_IFWLOG);
+	if (err) {
 		if (nl && nl->sk_socket)
 			sock_release(nl->sk_socket);
-		return -EINVAL;
+		return err;
 	}

 	PRINTR(KERN_INFO "IFWLOG: register target\n");
 	return 0;
 }

-static void __exit fini(void)
+static void __exit ipt_ifwlog_fini(void)
 {
 	if (nl && nl->sk_socket)
-                sock_release(nl->sk_socket);
+		sock_release(nl->sk_socket);
 	PRINTR(KERN_INFO "IFWLOG: unregister target\n");
-	ipt_unregister_target(&ipt_IFWLOG);
+	xt_unregister_target(&ipt_IFWLOG);
 }

-module_init(init);
-module_exit(fini);
+module_init(ipt_ifwlog_init);
+module_exit(ipt_ifwlog_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
+MODULE_AUTHOR("Luiz Capitulino <lcapitulino@mandriva.com.br>");
+MODULE_DESCRIPTION("Interactive firewall logging and module");
+MODULE_VERSION("v1.1");
--- linux/include/uapi/linux/netfilter_ipv4/Kbuild.net-netfilter-IFWLOG-mdv.orig
+++ linux/include/uapi/linux/netfilter_ipv4/Kbuild
@@ -2,6 +2,7 @@ header-y += ip_queue.h
 header-y += ip_tables.h
 header-y += ipt_CLUSTERIP.h
 header-y += ipt_ECN.h
+header-y += ipt_IFWLOG.h
 header-y += ipt_LOG.h
 header-y += ipt_REJECT.h
 header-y += ipt_TTL.h


code:
--- linux-4.4/net/ipv4/netfilter/ipt_IFWLOG.c~	2016-01-24 13:19:13.233713998 +0100
+++ linux-4.4/net/ipv4/netfilter/ipt_IFWLOG.c	2016-01-24 20:49:10.145823623 +0100
@@ -74,7 +74,6 @@
 		return;
 	}

-nlmsg_failure:
 	kfree_skb(skb);
 	PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
 }


code:
---
 include/linux/netfilter_ipv4/ipt_IFWLOG.h |   26 +++
 net/ipv4/netfilter/Kconfig                |   11 +
 net/ipv4/netfilter/Makefile               |    1
 net/ipv4/netfilter/ipt_IFWLOG.c           |  200 ++++++++++++++++++++++++++++++
 4 files changed, 238 insertions(+)

--- /dev/null
+++ b/net/ipv4/netfilter/ipt_IFWLOG.c
@@ -0,0 +1,200 @@
+/* Interactive Firewall for Mandriva
+ * Samir Bellabes <sbellabes@mandriva.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <asm/types.h>
+#include <linux/jiffies.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/icmp.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+#include <net/sock.h>
+#include <linux/netlink.h>
+#include <linux/string.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_IFWLOG.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Samir Bellabes <sbellabes@mandriva.com>");
+MODULE_DESCRIPTION("Interactive firewall logging and module");
+
+#if 0
+#define DEBUGP PRINTR
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#define PRINTR(format, args...) do { if(net_ratelimit()) printk(format, ##args); } while(0)
+
+static struct sock *nl;
+
+#define GROUP 10
+
+/* send struct to userspace */
+static void send_packet(struct nl_msg msg)
+{
+	struct sk_buff *skb = NULL;
+	struct nlmsghdr *nlh;
+
+	skb = alloc_skb(NLMSG_SPACE(sizeof(struct nl_msg)), GFP_ATOMIC);
+	if (!skb) {
+		PRINTR(KERN_WARNING "IFWLOG: OOM can't allocate skb\n");
+		return ;
+	}
+
+	nlh = NLMSG_PUT(skb, 0, 0, 0, sizeof(struct nl_msg) - sizeof(*nlh));
+
+	memcpy(NLMSG_DATA(nlh), (const void*)&msg, sizeof(struct nl_msg));
+
+	NETLINK_CB(skb).pid = 0;  /* from kernel */
+	NETLINK_CB(skb).dst_pid = 0;  /* multicast */
+	NETLINK_CB(skb).dst_group = 10;
+
+	if (nl) {
+		DEBUGP(KERN_WARNING
+		       "IFWLOG: nlmsg_len=%ld\nnlmsg_type=%d nlmsg_flags=%d\nnlmsg_seq=%ld nlmsg_pid = %ld\n",
+		       (long)nlh->nlmsg_len,  nlh->nlmsg_type, nlh->nlmsg_flags,
+		       (long)nlh->nlmsg_seq, (long)nlh->nlmsg_pid);
+		DEBUGP(KERN_WARNING "prefix : %s\n", msg.prefix);
+
+		netlink_broadcast(nl, skb, 0, 10, GFP_ATOMIC);
+		return ;
+	}
+
+ nlmsg_failure:
+        if (skb)
+                kfree_skb(skb);
+        PRINTR(KERN_WARNING "IFWLOG: Error sending netlink packet\n");
+        return ;
+}
+
+/* fill struct for userspace */
+static void ipt_IFWLOG_packet(const struct sk_buff *skb,
+			      const struct net_device *in,
+			      const struct net_device *out,
+			      const struct ipt_IFWLOG_info *info)
+{
+	struct iphdr iph;
+	struct tcphdr tcph;
+	struct udphdr udph;
+	struct nl_msg msg;
+	struct iphdr _iph, *ih;
+	struct timeval tv;
+
+	memset(&msg, 0, sizeof(struct nl_msg));
+
+	ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
+	if (ih == NULL) {
+		PRINTR(KERN_WARNING "IFWLOG: skb truncated");
+		return;
+	}
+
+	/* save interface name */
+	if (in)
+		strcpy(msg.indev_name, in->name);
+	if (out)
+		strcpy(msg.outdev_name, out->name);
+
+	/* save log-prefix */
+	strcpy(msg.prefix, info->prefix);
+
+	/* save ip header */
+	skb_copy_bits(skb, 0, &iph, sizeof(iph));
+	memcpy(&msg.ip, &iph, sizeof(struct iphdr));
+
+	/* save transport header */
+	switch (iph.protocol){
+	case IPPROTO_TCP:
+		skb_copy_bits(skb, iph.ihl*4 , &tcph, sizeof(tcph));
+		memcpy(&msg.h.th, &tcph, sizeof(struct tcphdr));
+		break;
+	case IPPROTO_UDP:
+		skb_copy_bits(skb, iph.ihl*4 , &udph, sizeof(udph));
+		memcpy(&msg.h.uh, &udph, sizeof(struct udphdr));
+		break;
+	default:
+		break;
+	}
+
+	/* save timetamp */
+	do_gettimeofday((struct timeval *)&tv);
+        msg.timestamp_sec = tv.tv_sec;
+
+	send_packet(msg);
+}
+
+static unsigned int ipt_IFWLOG_target(struct sk_buff **pskb,
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      unsigned int hooknum,
+				      const void *targinfo,
+				      void *userinfo)
+{
+	const struct ipt_IFWLOG_info *info = targinfo;
+
+	ipt_IFWLOG_packet(*pskb, in, out, info);
+
+	return IPT_CONTINUE;
+}
+
+static int ipt_IFWLOG_checkentry(const char *tablename,
+				 const struct ipt_entry *e,
+				 void *targinfo,
+				 unsigned int targinfosize,
+				 unsigned int hook_mask)
+{
+	const struct ipt_IFWLOG_info *info = targinfo;
+
+	if (info->prefix[sizeof(info->prefix)-1] != '\0') {
+		DEBUGP("IFWLOG: prefix term %i\n",
+		       info->prefix[sizeof(info->prefix)-1]);
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ipt_target ipt_IFWLOG = {
+	.name		= "IFWLOG",
+	.target		= ipt_IFWLOG_target,
+	.targetsize	= sizeof(struct ipt_IFWLOG_info),
+	.checkentry	= ipt_IFWLOG_checkentry,
+	.me		= THIS_MODULE,
+};
+
+static int __init init(void)
+{
+	nl = (struct sock*) netlink_kernel_create(NETLINK_IFWLOG, GROUP, NULL, THIS_MODULE);
+        if (!nl) {
+                PRINTR(KERN_WARNING "IFWLOG: cannot create netlink socket\n");
+                return -EINVAL;
+        }
+
+	if (ipt_register_target(&ipt_IFWLOG)) {
+		if (nl && nl->sk_socket)
+			sock_release(nl->sk_socket);
+		return -EINVAL;
+	}
+
+	PRINTR(KERN_INFO "IFWLOG: register target\n");
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	if (nl && nl->sk_socket)
+                sock_release(nl->sk_socket);
+	PRINTR(KERN_INFO "IFWLOG: unregister target\n");
+	ipt_unregister_target(&ipt_IFWLOG);
+}
+
+module_init(init);
+module_exit(fini);
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -331,6 +331,17 @@ config IP_NF_TARGET_TTL
 	(e.g. when running oldconfig). It selects
 	CONFIG_NETFILTER_XT_TARGET_HL.

+config IP_NF_TARGET_IFWLOG
+	tristate  'IFWLOG target support'
+	depends on IP_NF_IPTABLES
+	help
+	  This option adds a `IFWLOG' target, which is used by
+	  Interactive Firewall for sending informations to a userspace
+	  daemon
+
+	  If you want to compile it as a module, say M here and read
+	  Documentation/modules.txt.  If unsure, say `N'.
+
 # raw + specific targets
 config IP_NF_RAW
 	tristate  'raw table support (required for NOTRACK/TRACE)'
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_IFWLOG.h
@@ -0,0 +1,26 @@
+#ifndef _IPT_IFWLOG_H
+#define _IPT_IFWLOG_H
+
+#ifndef NETLINK_IFWLOG
+#define NETLINK_IFWLOG  19
+#endif
+
+#define PREFSIZ         32
+
+struct nl_msg {				/* Netlink message */
+	long timestamp_sec;             /* time packet */
+	char indev_name[IFNAMSIZ];      /* name of the ingoing interface */
+	char outdev_name[IFNAMSIZ];     /* name of the outgoing interface */
+	unsigned char prefix[PREFSIZ];  /* informations on the logging reason */
+	struct iphdr ip;
+	union {
+		struct tcphdr th;
+		struct udphdr uh;
+	} h;
+};
+
+struct ipt_IFWLOG_info {
+	char prefix[PREFSIZ];
+};
+
+#endif /* _IPT_IFWLOG_H */
--- linux/net/ipv4/netfilter/Makefile.net-netfilter-IFWLOG.orig	2013-10-13 11:29:08.799136037 +0300
+++ linux/net/ipv4/netfilter/Makefile	2013-10-13 11:30:28.085842333 +0300
@@ -44,6 +44,7 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ip
 # targets
 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
+obj-$(CONFIG_IP_NF_TARGET_IFWLOG) += ipt_IFWLOG.o
 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
 obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o
 obj-$(CONFIG_IP_NF_TARGET_SYNPROXY) += ipt_SYNPROXY.o


code:
--- linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_psd.c.orig	2010-07-30 21:17:30.000000000 +0300
+++ linux-2.6.35-rc6-git-mnb0.1/net/ipv4/netfilter/ipt_psd.c	2010-07-31 13:29:00.623601957 +0300
@@ -98,7 +98,7 @@ static inline int hashfunc(struct in_add

 static bool
 ipt_psd_match(const struct sk_buff *pskb,
-	      const struct xt_match_param *match_param)
+	      struct xt_action_param *match_param)
 {
 	struct iphdr *ip_hdr;
 	struct tcphdr *tcp_hdr;


code:
Make defines psd specific so they dont redefine in-kernel defines like
HASH_SIZE.

Signed-off-by: Thomas Backlund <tmb@mageia.org>

 include/linux/netfilter_ipv4/ipt_psd.h |   14 +++++++-------
 net/ipv4/netfilter/ipt_psd.c           |   14 +++++++-------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff -Nurp linux-4.9.5-psd/include/linux/netfilter_ipv4/ipt_psd.h linux-4.9.5-psd-fix/include/linux/netfilter_ipv4/ipt_psd.h
--- linux-4.9.5-psd/include/linux/netfilter_ipv4/ipt_psd.h	2017-01-20 21:47:19.788931403 +0200
+++ linux-4.9.5-psd-fix/include/linux/netfilter_ipv4/ipt_psd.h	2017-01-20 21:58:09.995871253 +0200
@@ -21,14 +21,14 @@
 #define SCAN_DELAY_THRESHOLD		(300) /* old usage of HZ here was erroneously and broke under uml */

 /*
- * Keep track of up to LIST_SIZE source addresses, using a hash table of
- * HASH_SIZE entries for faster lookups, but limiting hash collisions to
- * HASH_MAX source addresses per the same hash value.
+ * Keep track of up to PSD_LIST_SIZE source addresses, using a hash table of
+ * PSD_HASH_SIZE entries for faster lookups, but limiting hash collisions to
+ * PSD_HASH_MAX source addresses per the same hash value.
  */
-#define LIST_SIZE			0x100
-#define HASH_LOG			9
-#define HASH_SIZE			(1 << HASH_LOG)
-#define HASH_MAX			0x10
+#define PSD_LIST_SIZE			0x100
+#define PSD_HASH_LOG			9
+#define PSD_HASH_SIZE			(1 << PSD_HASH_LOG)
+#define PSD_HASH_MAX			0x10

 struct ipt_psd_info {
 	unsigned int weight_threshold;
diff -Nurp linux-4.9.5-psd/net/ipv4/netfilter/ipt_psd.c linux-4.9.5-psd-fix/net/ipv4/netfilter/ipt_psd.c
--- linux-4.9.5-psd/net/ipv4/netfilter/ipt_psd.c	2017-01-20 21:47:19.792931402 +0200
+++ linux-4.9.5-psd-fix/net/ipv4/netfilter/ipt_psd.c	2017-01-20 21:58:09.998871253 +0200
@@ -74,8 +74,8 @@ struct host {
  */
 static struct {
 	spinlock_t lock;
-	struct host list[LIST_SIZE];	/* List of source addresses */
-	struct host *hash[HASH_SIZE];	/* Hash: pointers into the list */
+	struct host list[PSD_LIST_SIZE];	/* List of source addresses */
+	struct host *hash[PSD_HASH_SIZE];	/* Hash: pointers into the list */
 	int index;			/* Oldest entry to be replaced */
 } state;

@@ -91,9 +91,9 @@ static inline int hashfunc(struct in_add
 	hash = 0;
 	do {
 		hash ^= value;
-	} while ((value >>= HASH_LOG));
+	} while ((value >>= PSD_HASH_LOG));

-	return hash & (HASH_SIZE - 1);
+	return hash & (PSD_HASH_SIZE - 1);
 }

 static bool
@@ -245,11 +245,11 @@ ipt_psd_match(const struct sk_buff *pskb
 	/* Got too many source addresses with the same hash value? Then remove the
 	 * oldest one from the hash table, so that they can't take too much of our
 	 * CPU time even with carefully chosen spoofed IP addresses. */
-	if (count >= HASH_MAX && last) last->next = NULL;
+	if (count >= PSD_HASH_MAX && last) last->next = NULL;

 	/* We're going to re-use the oldest list entry, so remove it from the hash
 	 * table first (if it is really already in use, and isn't removed from the
-	 * hash table already because of the HASH_MAX check above). */
+	 * hash table already because of the PSD_HASH_MAX check above). */

 	/* First, find it */
 	if (state.list[state.index].src_addr.s_addr)
@@ -273,7 +273,7 @@ ipt_psd_match(const struct sk_buff *pskb

 	/* Get our list entry */
 	curr = &state.list[state.index++];
-	if (state.index >= LIST_SIZE) state.index = 0;
+	if (state.index >= PSD_LIST_SIZE) state.index = 0;

 	/* Link it into the hash table */
 	head = &state.hash[hash];


code:
ipt_psd: Mandriva changes

This patch holds all the Mandriva changes done in ipt_psd
netfilter module.

Most of the time they're just upgrades to match with new
API in the kernel.

This work is mostly done by Thomas Backlund, Herton R.
Krzesinski and Luiz Fernando N. Capitulino.

Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
Signed-off-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>

---
 include/linux/netfilter_ipv4/Kbuild |    1
 net/ipv4/netfilter/Kconfig          |    8 ++
 net/ipv4/netfilter/ipt_psd.c        |  113 ++++++++++++++----------------------
 3 files changed, 55 insertions(+), 67 deletions(-)

diff -p -up linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig linux-2.6.28/net/ipv4/netfilter/ipt_psd.c
--- linux-2.6.28/net/ipv4/netfilter/ipt_psd.c.orig	2008-12-12 11:03:05.000000000 -0500
+++ linux-2.6.28/net/ipv4/netfilter/ipt_psd.c	2008-12-12 11:04:03.000000000 -0500
@@ -1,21 +1,24 @@
 /*
-  This is a module which is used for PSD (portscan detection)
-  Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
-  and LOG target module.
-
-  Copyright (C) 2000,2001 astaro AG
-
-  This file is distributed under the terms of the GNU General Public
-  License (GPL). Copies of the GPL can be obtained from:
-     ftp://prep.ai.mit.edu/pub/gnu/GPL
-
-  2000-05-04 Markus Hennig <hennig@astaro.de> : initial
-  2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
-  2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
-  2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
-  2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
-  2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
-*/
+ * This is a module which is used for PSD (portscan detection)
+ * Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
+ * and LOG target module.
+ *
+ * Copyright (C) 2000,2001 astaro AG
+ *
+ * This file is distributed under the terms of the GNU General Public
+ * License (GPL). Copies of the GPL can be obtained from:
+ *    ftp://prep.ai.mit.edu/pub/gnu/GPL
+ *
+ * 2000-05-04 Markus Hennig <hennig@astaro.de> : initial
+ * 2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
+ * 2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
+ * 2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
+ * 2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
+ * 2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
+ * 2007-10-10 Thomas Backlund <tmb@mandriva.org>: 2.6.22 update
+ * 2007-11-14 Luiz Capitulino <lcapitulino@mandriva.com> : 2.6.22 API usage fixes
+ * 2007-11-26 Herton Ronaldo Krzesinski <herton@mandriva.com>: switch xt_match->match to bool
+ */

 #include <linux/module.h>
 #include <linux/skbuff.h>
@@ -54,7 +57,7 @@ struct port {
  */
 struct host {
 	struct host *next;		/* Next entry with the same hash */
-	clock_t timestamp;		/* Last update time */
+	unsigned long timestamp;	/* Last update time */
 	struct in_addr src_addr;	/* Source address */
 	struct in_addr dest_addr;	/* Destination address */
 	unsigned short src_port;	/* Source port */
@@ -93,33 +96,29 @@ static inline int hashfunc(struct in_add
 	return hash & (HASH_SIZE - 1);
 }

-static int
+static bool
 ipt_psd_match(const struct sk_buff *pskb,
-	      const struct net_device *in,
-	      const struct net_device *out,
-	      const void *matchinfo,
-	      int offset,
-	      int *hotdrop)
+	      const struct xt_match_param *match_param)
 {
 	struct iphdr *ip_hdr;
 	struct tcphdr *tcp_hdr;
 	struct in_addr addr;
 	u_int16_t src_port,dest_port;
   	u_int8_t tcp_flags, proto;
-	clock_t now;
+	unsigned long now;
 	struct host *curr, *last, **head;
 	int hash, index, count;

 	/* Parameters from userspace */
-	const struct ipt_psd_info *psdinfo = matchinfo;
+	const struct ipt_psd_info *psdinfo = match_param->matchinfo;

 	/* IP header */
-	ip_hdr = pskb->nh.iph;
+	ip_hdr = ipip_hdr(pskb);

 	/* Sanity check */
 	if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
 		DEBUGP("PSD: sanity check failed\n");
-		return 0;
+		return false;
 	}

 	/* TCP or UDP ? */
@@ -127,7 +126,7 @@ ipt_psd_match(const struct sk_buff *pskb

 	if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
 		DEBUGP("PSD: protocol not supported\n");
-		return 0;
+		return false;
 	}

 	/* Get the source address, source & destination ports, and TCP flags */
@@ -151,7 +150,7 @@ ipt_psd_match(const struct sk_buff *pskb
 	 * them spoof us. [DHCP needs this feature - HW] */
 	if (!addr.s_addr) {
 		DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
-		return 0;
+		return false;
 	}

 	/* Use jiffies here not to depend on someone setting the time while we're
@@ -298,46 +297,26 @@ ipt_psd_match(const struct sk_buff *pskb

 out_no_match:
 	spin_unlock(&state.lock);
-	return 0;
+	return false;

 out_match:
 	spin_unlock(&state.lock);
-	return 1;
+	DEBUGP("PSD: Dropping packets from "NIPQUAD_FMT" \n",
+	       NIPQUAD(curr->src_addr.s_addr));
+	return true;
 }

-static int ipt_psd_checkentry(const char *tablename,
-			      const struct ipt_ip *e,
-			      void *matchinfo,
-			      unsigned int matchsize,
-			      unsigned int hook_mask)
-{
-/*	const struct ipt_psd_info *psdinfo = targinfo;*/
-
-	/* we accept TCP only */
-/*  	if (e->ip.proto != IPPROTO_TCP) { */
-/*  		DEBUGP("PSD: specified protocol may be TCP only\n"); */
-/*  		return 0; */
-/*  	} */
-
-	if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
-		DEBUGP("PSD: matchsize %u != %u\n",
-		       matchsize,
-		       IPT_ALIGN(sizeof(struct ipt_psd_info)));
-		return 0;
-	}
-
-	return 1;
-}
-
-static struct ipt_match ipt_psd_reg = {
-	.name = "psd",
-	.match = ipt_psd_match,
-	.checkentry = ipt_psd_checkentry,
-	.me = THIS_MODULE };
+static struct xt_match ipt_psd_reg = {
+	.name      = "psd",
+	.family    = AF_INET,
+	.match     = ipt_psd_match,
+	.matchsize = sizeof(struct ipt_psd_info),
+	.me        = THIS_MODULE
+};

-static int __init init(void)
+static int __init ipt_psd_init(void)
 {
-	if (ipt_register_match(&ipt_psd_reg))
+	if (xt_register_match(&ipt_psd_reg))
 		return -EINVAL;

 	memset(&state, 0, sizeof(state));
@@ -348,11 +327,11 @@ static int __init init(void)
 	return 0;
 }

-static void __exit fini(void)
+static void __exit ipt_psd_fini(void)
 {
-	ipt_unregister_match(&ipt_psd_reg);
+	xt_unregister_match(&ipt_psd_reg);
 	printk("netfilter PSD unloaded - (c) astaro AG\n");
 }

-module_init(init);
-module_exit(fini);
+module_init(ipt_psd_init);
+module_exit(ipt_psd_fini);
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -193,6 +193,14 @@ config IP_NF_MATCH_ECN
 	(e.g. when running oldconfig). It selects
 	CONFIG_NETFILTER_XT_MATCH_ECN.

+config IP_NF_MATCH_PSD
+	tristate 'Port scanner detection support'
+	depends on NETFILTER_ADVANCED
+	help
+	  Module used for PSD (portscan detection).
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_NF_MATCH_RPFILTER
 	tristate '"rpfilter" reverse path filter match support'
 	depends on NETFILTER_ADVANCED
--- linux/include/uapi/linux/netfilter_ipv4/Kbuild.orig
+++ linux/include/uapi/linux/netfilter_ipv4/Kbuild
@@ -8,4 +8,5 @@ header-y += ipt_REJECT.h
 header-y += ipt_TTL.h
 header-y += ipt_ah.h
 header-y += ipt_ecn.h
+header-y += ipt_psd.h
 header-y += ipt_ttl.h


code:
---
 include/linux/netfilter_ipv4/ipt_psd.h |   40 +++
 net/ipv4/netfilter/Makefile            |    1
 net/ipv4/netfilter/ipt_psd.c           |  358 +++++++++++++++++++++++++++++++++
 3 files changed, 399 insertions(+)

--- /dev/null
+++ b/net/ipv4/netfilter/ipt_psd.c
@@ -0,0 +1,358 @@
+/*
+  This is a module which is used for PSD (portscan detection)
+  Derived from scanlogd v2.1 written by Solar Designer <solar@false.com>
+  and LOG target module.
+
+  Copyright (C) 2000,2001 astaro AG
+
+  This file is distributed under the terms of the GNU General Public
+  License (GPL). Copies of the GPL can be obtained from:
+     ftp://prep.ai.mit.edu/pub/gnu/GPL
+
+  2000-05-04 Markus Hennig <hennig@astaro.de> : initial
+  2000-08-18 Dennis Koslowski <koslowski@astaro.de> : first release
+  2000-12-01 Dennis Koslowski <koslowski@astaro.de> : UDP scans detection added
+  2001-01-02 Dennis Koslowski <koslowski@astaro.de> : output modified
+  2001-02-04 Jan Rekorajski <baggins@pld.org.pl> : converted from target to match
+  2004-05-05 Martijn Lievaart <m@rtij.nl> : ported to 2.6
+*/
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/tcp.h>
+#include <linux/spinlock.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_psd.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dennis Koslowski <koslowski@astaro.com>");
+
+#define HF_DADDR_CHANGING   0x01
+#define HF_SPORT_CHANGING   0x02
+#define HF_TOS_CHANGING	    0x04
+#define HF_TTL_CHANGING	    0x08
+
+/*
+ * Information we keep per each target port
+ */
+struct port {
+	u_int16_t number;      /* port number */
+	u_int8_t proto;        /* protocol number */
+	u_int8_t and_flags;    /* tcp ANDed flags */
+	u_int8_t or_flags;     /* tcp ORed flags */
+};
+
+/*
+ * Information we keep per each source address.
+ */
+struct host {
+	struct host *next;		/* Next entry with the same hash */
+	clock_t timestamp;		/* Last update time */
+	struct in_addr src_addr;	/* Source address */
+	struct in_addr dest_addr;	/* Destination address */
+	unsigned short src_port;	/* Source port */
+	int count;			/* Number of ports in the list */
+	int weight;			/* Total weight of ports in the list */
+	struct port ports[SCAN_MAX_COUNT - 1];	/* List of ports */
+	unsigned char tos;		/* TOS */
+	unsigned char ttl;		/* TTL */
+	unsigned char flags;		/* HF_ flags bitmask */
+};
+
+/*
+ * State information.
+ */
+static struct {
+	spinlock_t lock;
+	struct host list[LIST_SIZE];	/* List of source addresses */
+	struct host *hash[HASH_SIZE];	/* Hash: pointers into the list */
+	int index;			/* Oldest entry to be replaced */
+} state;
+
+/*
+ * Convert an IP address into a hash table index.
+ */
+static inline int hashfunc(struct in_addr addr)
+{
+	unsigned int value;
+	int hash;
+
+	value = addr.s_addr;
+	hash = 0;
+	do {
+		hash ^= value;
+	} while ((value >>= HASH_LOG));
+
+	return hash & (HASH_SIZE - 1);
+}
+
+static int
+ipt_psd_match(const struct sk_buff *pskb,
+	      const struct net_device *in,
+	      const struct net_device *out,
+	      const void *matchinfo,
+	      int offset,
+	      int *hotdrop)
+{
+	struct iphdr *ip_hdr;
+	struct tcphdr *tcp_hdr;
+	struct in_addr addr;
+	u_int16_t src_port,dest_port;
+  	u_int8_t tcp_flags, proto;
+	clock_t now;
+	struct host *curr, *last, **head;
+	int hash, index, count;
+
+	/* Parameters from userspace */
+	const struct ipt_psd_info *psdinfo = matchinfo;
+
+	/* IP header */
+	ip_hdr = pskb->nh.iph;
+
+	/* Sanity check */
+	if (ntohs(ip_hdr->frag_off) & IP_OFFSET) {
+		DEBUGP("PSD: sanity check failed\n");
+		return 0;
+	}
+
+	/* TCP or UDP ? */
+	proto = ip_hdr->protocol;
+
+	if (proto != IPPROTO_TCP && proto != IPPROTO_UDP) {
+		DEBUGP("PSD: protocol not supported\n");
+		return 0;
+	}
+
+	/* Get the source address, source & destination ports, and TCP flags */
+
+	addr.s_addr = ip_hdr->saddr;
+
+	tcp_hdr = (struct tcphdr*)((u_int32_t *)ip_hdr + ip_hdr->ihl);
+
+	/* Yep, it´s dirty */
+	src_port = tcp_hdr->source;
+	dest_port = tcp_hdr->dest;
+
+	if (proto == IPPROTO_TCP) {
+		tcp_flags = *((u_int8_t*)tcp_hdr + 13);
+	}
+	else {
+		tcp_flags = 0x00;
+	}
+
+	/* We're using IP address 0.0.0.0 for a special purpose here, so don't let
+	 * them spoof us. [DHCP needs this feature - HW] */
+	if (!addr.s_addr) {
+		DEBUGP("PSD: spoofed source address (0.0.0.0)\n");
+		return 0;
+	}
+
+	/* Use jiffies here not to depend on someone setting the time while we're
+	 * running; we need to be careful with possible return value overflows. */
+	now = jiffies;
+
+	spin_lock(&state.lock);
+
+	/* Do we know this source address already? */
+	count = 0;
+	last = NULL;
+	if ((curr = *(head = &state.hash[hash = hashfunc(addr)])))
+		do {
+			if (curr->src_addr.s_addr == addr.s_addr) break;
+			count++;
+			if (curr->next) last = curr;
+		} while ((curr = curr->next));
+
+	if (curr) {
+
+		/* We know this address, and the entry isn't too old. Update it. */
+		if (now - curr->timestamp <= (psdinfo->delay_threshold*HZ)/100 &&
+		    time_after_eq(now, curr->timestamp)) {
+
+			/* Just update the appropriate list entry if we've seen this port already */
+			for (index = 0; index < curr->count; index++) {
+				if (curr->ports[index].number == dest_port) {
+					curr->ports[index].proto = proto;
+					curr->ports[index].and_flags &= tcp_flags;
+					curr->ports[index].or_flags |= tcp_flags;
+					goto out_no_match;
+				}
+			}
+
+			/* TCP/ACK and/or TCP/RST to a new port? This could be an outgoing connection. */
+			if (proto == IPPROTO_TCP && (tcp_hdr->ack || tcp_hdr->rst))
+				goto out_no_match;
+
+			/* Packet to a new port, and not TCP/ACK: update the timestamp */
+			curr->timestamp = now;
+
+			/* Logged this scan already? Then drop the packet. */
+			if (curr->weight >= psdinfo->weight_threshold)
+				goto out_match;
+
+			/* Specify if destination address, source port, TOS or TTL are not fixed */
+			if (curr->dest_addr.s_addr != ip_hdr->daddr)
+				curr->flags |= HF_DADDR_CHANGING;
+			if (curr->src_port != src_port)
+				curr->flags |= HF_SPORT_CHANGING;
+			if (curr->tos != ip_hdr->tos)
+				curr->flags |= HF_TOS_CHANGING;
+			if (curr->ttl != ip_hdr->ttl)
+				curr->flags |= HF_TTL_CHANGING;
+
+			/* Update the total weight */
+			curr->weight += (ntohs(dest_port) < 1024) ?
+				psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
+
+			/* Got enough destination ports to decide that this is a scan? */
+			/* Then log it and drop the packet. */
+			if (curr->weight >= psdinfo->weight_threshold)
+				goto out_match;
+
+			/* Remember the new port */
+			if (curr->count < SCAN_MAX_COUNT) {
+				curr->ports[curr->count].number = dest_port;
+				curr->ports[curr->count].proto = proto;
+				curr->ports[curr->count].and_flags = tcp_flags;
+				curr->ports[curr->count].or_flags = tcp_flags;
+				curr->count++;
+			}
+
+			goto out_no_match;
+		}
+
+		/* We know this address, but the entry is outdated. Mark it unused, and
+		 * remove from the hash table. We'll allocate a new entry instead since
+		 * this one might get re-used too soon. */
+		curr->src_addr.s_addr = 0;
+		if (last)
+			last->next = last->next->next;
+		else if (*head)
+			*head = (*head)->next;
+		last = NULL;
+	}
+
+	/* We don't need an ACK from a new source address */
+	if (proto == IPPROTO_TCP && tcp_hdr->ack)
+		goto out_no_match;
+
+	/* Got too many source addresses with the same hash value? Then remove the
+	 * oldest one from the hash table, so that they can't take too much of our
+	 * CPU time even with carefully chosen spoofed IP addresses. */
+	if (count >= HASH_MAX && last) last->next = NULL;
+
+	/* We're going to re-use the oldest list entry, so remove it from the hash
+	 * table first (if it is really already in use, and isn't removed from the
+	 * hash table already because of the HASH_MAX check above). */
+
+	/* First, find it */
+	if (state.list[state.index].src_addr.s_addr)
+		head = &state.hash[hashfunc(state.list[state.index].src_addr)];
+	else
+		head = &last;
+	last = NULL;
+	if ((curr = *head))
+	do {
+		if (curr == &state.list[state.index]) break;
+		last = curr;
+	} while ((curr = curr->next));
+
+	/* Then, remove it */
+	if (curr) {
+		if (last)
+			last->next = last->next->next;
+		else if (*head)
+			*head = (*head)->next;
+	}
+
+	/* Get our list entry */
+	curr = &state.list[state.index++];
+	if (state.index >= LIST_SIZE) state.index = 0;
+
+	/* Link it into the hash table */
+	head = &state.hash[hash];
+	curr->next = *head;
+	*head = curr;
+
+	/* And fill in the fields */
+	curr->timestamp = now;
+	curr->src_addr = addr;
+	curr->dest_addr.s_addr = ip_hdr->daddr;
+	curr->src_port = src_port;
+	curr->count = 1;
+	curr->weight = (ntohs(dest_port) < 1024) ?
+		psdinfo->lo_ports_weight : psdinfo->hi_ports_weight;
+	curr->ports[0].number = dest_port;
+	curr->ports[0].proto = proto;
+	curr->ports[0].and_flags = tcp_flags;
+	curr->ports[0].or_flags = tcp_flags;
+	curr->tos = ip_hdr->tos;
+	curr->ttl = ip_hdr->ttl;
+
+out_no_match:
+	spin_unlock(&state.lock);
+	return 0;
+
+out_match:
+	spin_unlock(&state.lock);
+	return 1;
+}
+
+static int ipt_psd_checkentry(const char *tablename,
+			      const struct ipt_ip *e,
+			      void *matchinfo,
+			      unsigned int matchsize,
+			      unsigned int hook_mask)
+{
+/*	const struct ipt_psd_info *psdinfo = targinfo;*/
+
+	/* we accept TCP only */
+/*  	if (e->ip.proto != IPPROTO_TCP) { */
+/*  		DEBUGP("PSD: specified protocol may be TCP only\n"); */
+/*  		return 0; */
+/*  	} */
+
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_psd_info))) {
+		DEBUGP("PSD: matchsize %u != %u\n",
+		       matchsize,
+		       IPT_ALIGN(sizeof(struct ipt_psd_info)));
+		return 0;
+	}
+
+	return 1;
+}
+
+static struct ipt_match ipt_psd_reg = {
+	.name = "psd",
+	.match = ipt_psd_match,
+	.checkentry = ipt_psd_checkentry,
+	.me = THIS_MODULE };
+
+static int __init init(void)
+{
+	if (ipt_register_match(&ipt_psd_reg))
+		return -EINVAL;
+
+	memset(&state, 0, sizeof(state));
+
+	spin_lock_init(&(state.lock));
+
+	printk("netfilter PSD loaded - (c) astaro AG\n");
+	return 0;
+}
+
+static void __exit fini(void)
+{
+	ipt_unregister_match(&ipt_psd_reg);
+	printk("netfilter PSD unloaded - (c) astaro AG\n");
+}
+
+module_init(init);
+module_exit(fini);
--- /dev/null
+++ b/include/linux/netfilter_ipv4/ipt_psd.h
@@ -0,0 +1,40 @@
+#ifndef _IPT_PSD_H
+#define _IPT_PSD_H
+
+#include <linux/param.h>
+#include <linux/types.h>
+
+/*
+ * High port numbers have a lower weight to reduce the frequency of false
+ * positives, such as from passive mode FTP transfers.
+ */
+#define PORT_WEIGHT_PRIV		3
+#define PORT_WEIGHT_HIGH		1
+
+/*
+ * Port scan detection thresholds: at least COUNT ports need to be scanned
+ * from the same source, with no longer than DELAY ticks between ports.
+ */
+#define SCAN_MIN_COUNT			7
+#define SCAN_MAX_COUNT			(SCAN_MIN_COUNT * PORT_WEIGHT_PRIV)
+#define SCAN_WEIGHT_THRESHOLD		SCAN_MAX_COUNT
+#define SCAN_DELAY_THRESHOLD		(300) /* old usage of HZ here was erroneously and broke under uml */
+
+/*
+ * Keep track of up to LIST_SIZE source addresses, using a hash table of
+ * HASH_SIZE entries for faster lookups, but limiting hash collisions to
+ * HASH_MAX source addresses per the same hash value.
+ */
+#define LIST_SIZE			0x100
+#define HASH_LOG			9
+#define HASH_SIZE			(1 << HASH_LOG)
+#define HASH_MAX			0x10
+
+struct ipt_psd_info {
+	unsigned int weight_threshold;
+	unsigned int delay_threshold;
+	unsigned short lo_ports_weight;
+	unsigned short hi_ports_weight;
+};
+
+#endif /*_IPT_PSD_H*/
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -49,6 +49,7 @@

 # matches
 obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
+obj-$(CONFIG_IP_NF_MATCH_PSD) += ipt_psd.o
 obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o

 # targets


code:
---
 drivers/net/ethernet/sis/sis190.c |   10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- linux/drivers/net/ethernet/sis/sis190.c.net-sis190-fix-list-usage.orig
+++ linux/drivers/net/ethernet/sis/sis190.c
@@ -1252,6 +1252,7 @@ static u16 sis190_default_phy(struct net
 	struct sis190_private *tp = netdev_priv(dev);
 	struct mii_if_info *mii_if = &tp->mii_if;
 	void __iomem *ioaddr = tp->mmio_addr;
+	struct list_head *l;
 	u16 status;

 	phy_home = phy_default = phy_lan = NULL;
@@ -1280,9 +1281,12 @@ static u16 sis190_default_phy(struct net
 			phy_default = phy_home;
 		else if (phy_lan)
 			phy_default = phy_lan;
-		else
-			phy_default = list_first_entry(&tp->first_phy,
-						 struct sis190_phy, list);
+		else {
+			l = &tp->first_phy;
+			l = l->next;
+			phy_default = list_first_entry(l, struct sis190_phy, list);
+
+		}
 	}

 	if (mii_if->phy_id != phy_default->phy_id) {


code:
From 22b68b93ae2506bd56ee3bf232a51bc8ab955b56 Mon Sep 17 00:00:00 2001
From: Larry Finger <Larry.Finger@lwfinger.net>
Date: Mon, 19 Dec 2016 20:38:12 -0600
Subject: [PATCH] rtlwifi: Fix kernel oops introduced with commit e49656147359

With commit e49656147359 {"rtlwifi: Use dev_kfree_skb_irq instead of
kfree_skb"), the method used to free an skb was changed because the
kfree_skb() was inside a spinlock. What was forgotten is that kfree_skb()
guards against a NULL value for the argument. Routine dev_kfree_skb_irq()
does not, and a test is needed to prevent kernel panics.

Fixes: e49656147359 ("rtlwifi: Use dev_kfree_skb_irq instead of kfree_skb")
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Stable <stable@vger.kernel.org> # 4.9+
Cc: Wei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
 drivers/net/wireless/realtek/rtlwifi/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index 2caa4ad..ded1493 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -1829,7 +1829,8 @@ bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)

 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 	pskb = __skb_dequeue(&ring->queue);
-	dev_kfree_skb_irq(pskb);
+	if (pskb)
+		dev_kfree_skb_irq(pskb);

 	/*this is wrong, fill_tx_cmddesc needs update*/
 	pdesc = &ring->desc[0];
--
2.10.2


code:
From e49656147359411fb7529a211e852e587e5970dd Mon Sep 17 00:00:00 2001
From: Wei Yongjun <weiyongjun1@huawei.com>
Date: Tue, 1 Nov 2016 14:48:40 +0000
Subject: [PATCH] rtlwifi: Use dev_kfree_skb_irq instead of kfree_skb

It is not allowed to call kfree_skb() from hardware interrupt
context or with interrupts being disabled, spin_lock_irqsave()
make sure always in irq disable context. So the kfree_skb()
should be replaced with dev_kfree_skb_irq().

This is detected by Coccinelle semantic patch.

Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
 drivers/net/wireless/realtek/rtlwifi/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
index f95760c..a11e8f5 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -1832,7 +1832,7 @@ bool rtl_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb)

 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
 	pskb = __skb_dequeue(&ring->queue);
-	kfree_skb(pskb);
+	dev_kfree_skb_irq(pskb);

 	/*this is wrong, fill_tx_cmddesc needs update*/
 	pdesc = &ring->desc[0];
--
2.10.2


code:
From: Joerg Roedel <jroedel@suse.de>

ATS is broken on these devices. Under invalidation load, the
GPU does not reply to invalidations anymore, causing
Completion-wait loop timeouts on the AMD IOMMU driver side.
Fix it by not enabling ATS on these devices.

Note that below mentioned commit is not broken, it just
triggers the issue because it might cause invalidation
storms on devices.

Fixes: b1516a14657a ('iommu/amd: Implement flush queue')
Reported-by: Daniel Drake <drake@endlessm.com>
Cc: Daniel Drake <drake@endlessm.com>
Cc: Alexander Deucher <Alexander.Deucher@amd.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
---
 drivers/pci/ats.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/pci/ats.c b/drivers/pci/ats.c
index eeb9fb2..711bdb2 100644
--- a/drivers/pci/ats.c
+++ b/drivers/pci/ats.c
@@ -17,10 +17,18 @@

 #include "pci.h"

+static const struct pci_device_id broken_ats_tbl[] = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x98e4) }, /* AMD Stoney GPU part */
+	{ 0 }
+};
+
 void pci_ats_init(struct pci_dev *dev)
 {
 	int pos;

+	if (pci_match_id(broken_ats_tbl, dev))
+		return;
+
 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ATS);
 	if (!pos)
 		return;


code:
PCI: Add ALI M5229 comaptibility mode quirk

The libata driver will not work with an M5229 set into native IDE
mode (the old drivers/pci one does) if the M5229 does not provide
it's own IRQ.

The M5229 implementation embedded into the ALI M1543 uses the
M1543's ISA PIC to provide the interrupts and thus does not have
an valid PCI IRQ set. This quirk detects the abscence of IRQ and
sets the M5229 back into compatibility mode to use IRQs 14 and 15
so that libata works correctly.

Note, I belive that the check for an valid interrupt line is
correct, I only have an M5229 in an ALI M1543 to check this
on. It would be useful to confirm that a M5229 with an valid IRQ
does not trigger this quirk.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>

---
 drivers/pci/quirks.c |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -964,6 +964,34 @@ static void __devinit quirk_svwks_csb5id
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide);

+/* Some systems set the ALI M5229 in the ALI M1543 bridge to native mode,
+ * which cannot be supported by the pata_ali.c driver (the old drivers/ide
+ * makes a compatibility effort to change the IDE interrupts).
+ */
+static void __devinit quirk_ali_ide_compatibility(struct pci_dev *pdev)
+{
+	u8 tmp;
+
+	/* pdev->irq and pdev->pin have yet to be initialised, so check
+	 * by reading from the configuration header to see if we've got
+	 * a valid interrupt line. */
+
+	pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp);
+	if (tmp != 0xff)
+		return;
+
+	pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp);
+	if (tmp & 0x5) {
+		dev_info(&pdev->dev, "quirk: changing to IDE compatibility mode\n");
+
+		tmp &= ~0x05;
+		pdev->class &= ~0x05;
+		pci_write_config_byte(pdev, PCI_CLASS_PROG, tmp);
+	}
+}
+
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5229, quirk_ali_ide_compatibility);
+
 /*
  *	Intel 82801CAM ICH3-M datasheet says IDE modes must be the same
  */


code:
--- ./drivers/pci/quirks.c.orig	2013-01-16 18:13:57.000000000 +0200
+++ ./drivers/pci/quirks.c	2013-01-16 18:42:24.331008402 +0200
@@ -1083,7 +1083,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SE
  * which cannot be supported by the pata_ali.c driver (the old drivers/ide
  * makes a compatibility effort to change the IDE interrupts).
  */
-static void __devinit quirk_ali_ide_compatibility(struct pci_dev *pdev)
+static void quirk_ali_ide_compatibility(struct pci_dev *pdev)
 {
 	u8 tmp;


code:
From ba714a9c1dea85e0bf2899d02dfeb9c70040427c Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Tue, 23 May 2017 23:23:32 +0200
Subject: [PATCH] pinctrl/amd: Use regular interrupt instead of chained

The AMD pinctrl driver uses a chained interrupt to demultiplex the GPIO
interrupts. Kevin Vandeventer reported, that his new AMD Ryzen locks up
hard on boot when the AMD pinctrl driver is initialized. The reason is an
interrupt storm. It's not clear whether that's caused by hardware or
firmware or both.

Using chained interrupts on X86 is a dangerous endavour. If a system is
misconfigured or the hardware buggy there is no safety net to catch an
interrupt storm.

Convert the driver to use a regular interrupt for the demultiplex
handler. This allows the interrupt storm detector to catch the malfunction
and lets the system boot up.

This should be backported to stable because it's likely that more users run
into this problem as the AMD Ryzen machines are spreading.

Reported-by: Kevin Vandeventer
Link: https://bugzilla.suse.com/show_bug.cgi?id=1034261
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Backported to 4.9 by: Borislav Petkov <bp@alien8.de>

---
 drivers/pinctrl/pinctrl-amd.c | 91 +++++++++++++++++++------------------------
 1 file changed, 41 insertions(+), 50 deletions(-)

Date: Thu, 22 Jun 2017 11:16:31 +0200
From:
To: Thomas Backlund <tmb@mageia.org>
Cc: stable <stable@vger.kernel.org>, Thomas Gleixner <tglx@linutronix.de>,
        Linus Walleij <linus.walleij@linaro.org>,
        "Shah, Nehal-bakulchandra" <Nehal-bakulchandra.Shah@amd.com>,
        "Xue, Ken" <Ken.Xue@amd.com>,
        "S-k, Shyam-sundar" <Shyam-sundar.S-k@amd.com>,
        Sherry Hurwitz <sherry.hurwitz@amd.com>
Subject: Re: ba714a9c1dea ("pinctrl/amd: Use regular interrupt instead of chained")

On Thu, Jun 22, 2017 at 12:03:50PM +0300, Thomas Backlund wrote:
> If it's intended for 4.9 -longterm, a proper backport is needed.

Something like this, I guess. But I need to find a box to test it.

Regards/Gruss,
    Boris.

diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
index c9a146948192..531e2224f38f 100644
--- a/drivers/pinctrl/pinctrl-amd.c
+++ b/drivers/pinctrl/pinctrl-amd.c
@@ -476,64 +476,54 @@ static struct irq_chip amd_gpio_irqchip = {
 	.irq_set_type = amd_gpio_irq_set_type,
 };

-static void amd_gpio_irq_handler(struct irq_desc *desc)
+#define PIN_IRQ_PENDING	(BIT(INTERRUPT_STS_OFF) | BIT(WAKE_STS_OFF))
+
+static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id)
 {
-	u32 i;
-	u32 off;
-	u32 reg;
-	u32 pin_reg;
-	u64 reg64;
-	int handled = 0;
-	unsigned int irq;
+	struct amd_gpio *gpio_dev = dev_id;
+	struct gpio_chip *gc = &gpio_dev->gc;
+	irqreturn_t ret = IRQ_NONE;
+	unsigned int i, irqnr;
 	unsigned long flags;
-	struct irq_chip *chip = irq_desc_get_chip(desc);
-	struct gpio_chip *gc = irq_desc_get_handler_data(desc);
-	struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+	u32 *regs, regval;
+	u64 status, mask;

-	chained_irq_enter(chip, desc);
-	/*enable GPIO interrupt again*/
+	/* Read the wake status */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
-	reg64 = reg;
-	reg64 = reg64 << 32;
-
-	reg = readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
-	reg64 |= reg;
+	status = readl(gpio_dev->base + WAKE_INT_STATUS_REG1);
+	status <<= 32;
+	status |= readl(gpio_dev->base + WAKE_INT_STATUS_REG0);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);

-	/*
-	 * first 46 bits indicates interrupt status.
-	 * one bit represents four interrupt sources.
-	*/
-	for (off = 0; off < 46 ; off++) {
-		if (reg64 & BIT(off)) {
-			for (i = 0; i < 4; i++) {
-				pin_reg = readl(gpio_dev->base +
-						(off * 4 + i) * 4);
-				if ((pin_reg & BIT(INTERRUPT_STS_OFF)) ||
-					(pin_reg & BIT(WAKE_STS_OFF))) {
-					irq = irq_find_mapping(gc->irqdomain,
-								off * 4 + i);
-					generic_handle_irq(irq);
-					writel(pin_reg,
-						gpio_dev->base
-						+ (off * 4 + i) * 4);
-					handled++;
-				}
-			}
+	/* Bit 0-45 contain the relevant status bits */
+	status &= (1ULL << 46) - 1;
+	regs = gpio_dev->base;
+	for (mask = 1, irqnr = 0; status; mask <<= 1, regs += 4, irqnr += 4) {
+		if (!(status & mask))
+			continue;
+		status &= ~mask;
+
+		/* Each status bit covers four pins */
+		for (i = 0; i < 4; i++) {
+			regval = readl(regs + i);
+			if (!(regval & PIN_IRQ_PENDING))
+				continue;
+			irq = irq_find_mapping(gc->irqdomain, irqnr + i);
+			generic_handle_irq(irq);
+			/* Clear interrupt */
+			writel(regval, regs + i);
+			ret = IRQ_HANDLED;
 		}
 	}

-	if (handled == 0)
-		handle_bad_irq(desc);
-
+	/* Signal EOI to the GPIO unit */
 	spin_lock_irqsave(&gpio_dev->lock, flags);
-	reg = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
-	reg |= EOI_MASK;
-	writel(reg, gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval = readl(gpio_dev->base + WAKE_INT_MASTER_REG);
+	regval |= EOI_MASK;
+	writel(regval, gpio_dev->base + WAKE_INT_MASTER_REG);
 	spin_unlock_irqrestore(&gpio_dev->lock, flags);

-	chained_irq_exit(chip, desc);
+	return ret;
 }

 static int amd_get_groups_count(struct pinctrl_dev *pctldev)
@@ -801,10 +791,11 @@ static int amd_gpio_probe(struct platform_device *pdev)
 		goto out2;
 	}

-	gpiochip_set_chained_irqchip(&gpio_dev->gc,
-				 &amd_gpio_irqchip,
-				 irq_base,
-				 amd_gpio_irq_handler);
+	ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler, 0,
+			       KBUILD_MODNAME, gpio_dev);
+	if (ret)
+		goto out2;
+

 	platform_set_drvdata(pdev, gpio_dev);

--
Regards/Gruss,
    Boris.

Good mailing practices for 400: avoid top-posting and trim the reply.