diff --git a/bsp/fri2/fri2-preempt-rt.scc b/bsp/fri2/fri2-preempt-rt.scc
index c474c711b652bb762c5cac43454e498853762887..a7cc7bb6519eee0497a00cdde48780c29530732f 100644
--- a/bsp/fri2/fri2-preempt-rt.scc
+++ b/bsp/fri2/fri2-preempt-rt.scc
@@ -14,5 +14,4 @@ include cfg/usb-mass-storage.scc
 include cfg/boot-live.scc
 include features/latencytop/latencytop.scc
 include features/profiling/profiling.scc
-patch pch_uart-Add-eg20t_port-lock-field-avoid-recursive-s.patch
 patch pch_uart-Correct-spin_lock-and-irqsave-usage-in-pch_.patch
diff --git a/bsp/fri2/pch_uart-Add-eg20t_port-lock-field-avoid-recursive-s.patch b/bsp/fri2/pch_uart-Add-eg20t_port-lock-field-avoid-recursive-s.patch
deleted file mode 100644
index 12a72bbaafe871bd9ceca957bd7b9ba95aaefddf..0000000000000000000000000000000000000000
--- a/bsp/fri2/pch_uart-Add-eg20t_port-lock-field-avoid-recursive-s.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 120899d27d5ffc9e1fc73684ffd60642ed0fc605 Mon Sep 17 00:00:00 2001
-From: Darren Hart <dvhart@linux.intel.com>
-Date: Thu, 31 May 2012 00:37:51 -0700
-Subject: [PATCH 1/2] pch_uart: Add eg20t_port lock field, avoid recursive
- spinlocks
-
-pch_uart_interrupt() takes priv->port.lock which leads to two recursive
-spinlock calls if low_latency==1 or CONFIG_PREEMPT_RT_FULL=y (one
-otherwise):
-
-pch_uart_interrupt
-  spin_lock_irqsave(priv->port.lock, flags)
-  case PCH_UART_IID_RDR_TO (data ready)
-  handle_rx_to
-    push_rx
-      tty_port_tty_get
-        spin_lock_irqsave(&port->lock, flags) <--- already hold this lock
-        ...
-      tty_flip_buffer_push
-        ...
-        flush_to_ldisc
-          spin_lock_irqsave(&tty->buf.lock)
-            spin_lock_irqsave(&tty->buf.lock)
-            disc->ops->receive_buf(tty, char_buf)
-              n_tty_receive_buf
-                tty->ops->flush_chars()
-                uart_flush_chars
-                  uart_start
-                    spin_lock_irqsave(&port->lock) <--- already hold this lock
-
-Avoid this by using a dedicated lock to protect the eg20t_port structure
-and IO access to its membase. This is more consistent with the 8250
-driver.  Ensure priv->lock is always take prior to priv->port.lock when
-taken at the same time.
-
-Signed-off-by: Darren Hart <dvhart@linux.intel.com>
-CC: Tomoya MORINAGA <tomoya.rohm@gmail.com>
-CC: Feng Tang <feng.tang@intel.com>
-CC: Alexander Stein <alexander.stein@systec-electronic.com>
-CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-CC: Alan Cox <alan@linux.intel.com>
-CC: linux-serial@vger.kernel.org
----
- drivers/tty/serial/pch_uart.c |   23 +++++++++++++++++------
- 1 files changed, 17 insertions(+), 6 deletions(-)
-
-diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
-index c2816f4..f11ee7b 100644
---- a/drivers/tty/serial/pch_uart.c
-+++ b/drivers/tty/serial/pch_uart.c
-@@ -251,6 +251,9 @@ struct eg20t_port {
- 	void				*rx_buf_virt;
- 	dma_addr_t			rx_buf_dma;
- 
-+	/* protect the eg20t_port private structure and io access to membase */
-+	spinlock_t lock;
-+
- 	struct dentry	*debugfs;
- };
- 
-@@ -1056,7 +1059,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
- 	unsigned int iid;
- 	unsigned long flags;
- 
--	spin_lock_irqsave(&priv->port.lock, flags);
-+	spin_lock_irqsave(&priv->lock, flags);
- 	handled = 0;
- 	while ((iid = pch_uart_hal_get_iid(priv)) > 1) {
- 		switch (iid) {
-@@ -1107,7 +1110,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
- 			priv->int_dis_flag = 0;
- 	}
- 
--	spin_unlock_irqrestore(&priv->port.lock, flags);
-+	spin_unlock_irqrestore(&priv->lock, flags);
- 	return IRQ_RETVAL(handled);
- }
- 
-@@ -1218,9 +1221,9 @@ static void pch_uart_break_ctl(struct uart_port *port, int ctl)
- 	unsigned long flags;
- 
- 	priv = container_of(port, struct eg20t_port, port);
--	spin_lock_irqsave(&port->lock, flags);
-+	spin_lock_irqsave(&priv->lock, flags);
- 	pch_uart_hal_set_break(priv, ctl);
--	spin_unlock_irqrestore(&port->lock, flags);
-+	spin_unlock_irqrestore(&priv->lock, flags);
- }
- 
- /* Grab any interrupt resources and initialise any low level driver state. */
-@@ -1368,7 +1371,8 @@ static void pch_uart_set_termios(struct uart_port *port,
- 
- 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
- 
--	spin_lock_irqsave(&port->lock, flags);
-+	spin_lock_irqsave(&priv->lock, flags);
-+	spin_lock(&port->lock);
- 
- 	uart_update_timeout(port, termios->c_cflag, baud);
- 	rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb);
-@@ -1381,7 +1385,8 @@ static void pch_uart_set_termios(struct uart_port *port,
- 		tty_termios_encode_baud_rate(termios, baud, baud);
- 
- out:
--	spin_unlock_irqrestore(&port->lock, flags);
-+	spin_unlock(&port->lock);
-+	spin_unlock_irqrestore(&priv->lock, flags);
- }
- 
- static const char *pch_uart_type(struct uart_port *port)
-@@ -1539,6 +1544,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
- 	touch_nmi_watchdog();
- 
- 	local_irq_save(flags);
-+	spin_lock(&priv->lock);
- 	if (priv->port.sysrq) {
- 		/* serial8250_handle_port() already took the lock */
- 		locked = 0;
-@@ -1547,6 +1553,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
- 	} else
- 		spin_lock(&priv->port.lock);
- 
-+
- 	/*
- 	 *	First save the IER then disable the interrupts
- 	 */
-@@ -1565,7 +1572,9 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
- 
- 	if (locked)
- 		spin_unlock(&priv->port.lock);
-+	spin_unlock(&priv->lock);
- 	local_irq_restore(flags);
-+
- }
- 
- static int __init pch_console_setup(struct console *co, char *options)
-@@ -1662,6 +1671,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
- 	pci_enable_msi(pdev);
- 	pci_set_master(pdev);
- 
-+	spin_lock_init(&priv->lock);
-+
- 	iobase = pci_resource_start(pdev, 0);
- 	mapbase = pci_resource_start(pdev, 1);
- 	priv->mapbase = mapbase;
--- 
-1.7.5.4
-
diff --git a/bsp/fri2/pch_uart-Correct-spin_lock-and-irqsave-usage-in-pch_.patch b/bsp/fri2/pch_uart-Correct-spin_lock-and-irqsave-usage-in-pch_.patch
index a1e5472724a8e2edac4efc344ee9a67bbea1e84a..4e6a81e229ac8d3ef00afbae605e4bad86f4576d 100644
--- a/bsp/fri2/pch_uart-Correct-spin_lock-and-irqsave-usage-in-pch_.patch
+++ b/bsp/fri2/pch_uart-Correct-spin_lock-and-irqsave-usage-in-pch_.patch
@@ -38,32 +38,25 @@ CC: Alan Cox <alan@linux.intel.com>
 CC: Steven Rostedt <rostedt@goodmis.org>
 CC: Peter Zijlstra <peterz@infradead.org>
 CC: linux-serial@vger.kernel.org
----
- drivers/tty/serial/pch_uart.c |    4 ++--
- 1 files changed, 2 insertions(+), 2 deletions(-)
-
 diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c
-index f11ee7b..7f5c998 100644
+index 558ce85..7bc887b 100644
 --- a/drivers/tty/serial/pch_uart.c
 +++ b/drivers/tty/serial/pch_uart.c
-@@ -1543,7 +1543,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
+@@ -1558,7 +1558,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
  
  	touch_nmi_watchdog();
  
 -	local_irq_save(flags);
 +	local_irq_save_nort(flags);
- 	spin_lock(&priv->lock);
  	if (priv->port.sysrq) {
- 		/* serial8250_handle_port() already took the lock */
-@@ -1573,7 +1573,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
- 	if (locked)
+ 		spin_lock(&priv->lock);
+ 		/* serial8250_handle_port() already took the port lock */
+@@ -1591,7 +1591,7 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
  		spin_unlock(&priv->port.lock);
- 	spin_unlock(&priv->lock);
+ 	if (priv_locked)
+ 		spin_unlock(&priv->lock);
 -	local_irq_restore(flags);
 +	local_irq_restore_nort(flags);
- 
  }
  
--- 
-1.7.5.4
-
+ static int __init pch_console_setup(struct console *co, char *options)
diff --git a/bsp/routerstationpro/441-block2mtd_refresh.patch b/bsp/routerstationpro/441-block2mtd_refresh.patch
index 8ee98bc81b54ab5ca4c8498255f347a85f762932..c0b3761ce2fd41e818a14e3bdca648157a70d961 100644
--- a/bsp/routerstationpro/441-block2mtd_refresh.patch
+++ b/bsp/routerstationpro/441-block2mtd_refresh.patch
@@ -19,12 +19,8 @@ Path to patch in the repo is: target/linux/generic/patches-3.3
 Repo is: git://nbd.name/openwrt.git
 
 Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- drivers/mtd/devices/block2mtd.c |  185 +++++++++++++++++++++++++++++----------
- 1 file changed, 141 insertions(+), 44 deletions(-)
-
 diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
-index 2ebb4c6..4052874 100644
+index d1c2b88..c2766ab 100644
 --- a/drivers/mtd/devices/block2mtd.c
 +++ b/drivers/mtd/devices/block2mtd.c
 @@ -29,6 +29,8 @@ struct block2mtd_dev {
@@ -36,7 +32,7 @@ index 2ebb4c6..4052874 100644
  };
  
  
-@@ -81,6 +83,12 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+@@ -79,6 +81,12 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
  	size_t len = instr->len;
  	int err;
  
@@ -49,7 +45,7 @@ index 2ebb4c6..4052874 100644
  	instr->state = MTD_ERASING;
  	mutex_lock(&dev->write_mutex);
  	err = _block2mtd_erase(dev, from, len);
-@@ -92,6 +100,10 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
+@@ -90,6 +98,10 @@ static int block2mtd_erase(struct mtd_info *mtd, struct erase_info *instr)
  		instr->state = MTD_ERASE_DONE;
  
  	mtd_erase_callback(instr);
@@ -60,7 +56,7 @@ index 2ebb4c6..4052874 100644
  	return err;
  }
  
-@@ -103,7 +115,13 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+@@ -101,7 +113,13 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
  	struct page *page;
  	int index = from >> PAGE_SHIFT;
  	int offset = from & (PAGE_SIZE-1);
@@ -75,18 +71,13 @@ index 2ebb4c6..4052874 100644
  
  	while (len) {
  		if ((offset + len) > PAGE_SIZE)
-@@ -113,10 +131,14 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+@@ -111,8 +129,11 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
  		len = len - cpylen;
  
  		page = page_read(dev->blkdev->bd_inode->i_mapping, index);
--		if (!page)
--			return -ENOMEM;
 -		if (IS_ERR(page))
 -			return PTR_ERR(page);
-+		if (!page) {
-+			err = -ENOMEM;
-+			goto done;
-+		}
++
 +		if (IS_ERR(page)) {
 +			err = PTR_ERR(page);
 +			goto done;
@@ -94,7 +85,7 @@ index 2ebb4c6..4052874 100644
  
  		memcpy(buf, page_address(page) + offset, cpylen);
  		page_cache_release(page);
-@@ -127,7 +149,10 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
+@@ -123,7 +144,10 @@ static int block2mtd_read(struct mtd_info *mtd, loff_t from, size_t len,
  		offset = 0;
  		index++;
  	}
@@ -106,7 +97,7 @@ index 2ebb4c6..4052874 100644
  }
  
  
-@@ -140,6 +165,13 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
+@@ -136,6 +160,13 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
  	int index = to >> PAGE_SHIFT;	// page index
  	int offset = to & ~PAGE_MASK;	// page offset
  	int cpylen;
@@ -120,18 +111,13 @@ index 2ebb4c6..4052874 100644
  
  	while (len) {
  		if ((offset+len) > PAGE_SIZE)
-@@ -149,10 +181,14 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
+@@ -145,8 +176,11 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
  		len = len - cpylen;
  
  		page = page_read(mapping, index);
--		if (!page)
--			return -ENOMEM;
 -		if (IS_ERR(page))
 -			return PTR_ERR(page);
-+		if (!page) {
-+			err = -ENOMEM;
-+			goto done;
-+		}
++
 +		if (IS_ERR(page)) {
 +			err =  PTR_ERR(page);
 +			goto done;
@@ -139,7 +125,7 @@ index 2ebb4c6..4052874 100644
  
  		if (memcmp(page_address(page)+offset, buf, cpylen)) {
  			lock_page(page);
-@@ -169,7 +205,9 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
+@@ -163,7 +197,9 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf,
  		offset = 0;
  		index++;
  	}
@@ -150,7 +136,7 @@ index 2ebb4c6..4052874 100644
  }
  
  
-@@ -192,33 +230,110 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
+@@ -186,33 +222,110 @@ static int block2mtd_write(struct mtd_info *mtd, loff_t to, size_t len,
  static void block2mtd_sync(struct mtd_info *mtd)
  {
  	struct block2mtd_dev *dev = mtd->priv;
@@ -271,7 +257,7 @@ index 2ebb4c6..4052874 100644
  	struct block2mtd_dev *dev;
  	struct mtd_partition *part;
  	char *name;
-@@ -226,36 +341,17 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, const cha
+@@ -220,36 +333,17 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, const cha
  	if (!devname)
  		return NULL;
  
@@ -287,7 +273,8 @@ index 2ebb4c6..4052874 100644
 -
 -		/* We might not have rootfs mounted at this point. Try
 -		   to resolve the device name by other means. */
--
++	strcpy(dev->devname, devname);
+ 
 -		dev_t devt = name_to_dev_t(devname);
 -		if (devt)
 -			bdev = blkdev_get_by_dev(devt, mode, dev);
@@ -296,15 +283,14 @@ index 2ebb4c6..4052874 100644
 -
 -	if (IS_ERR(bdev)) {
 -		ERROR("error: cannot open device %s", devname);
--		goto devinit_err;
++	if (_open_bdev(dev))
+ 		goto devinit_err;
 -	}
 -	dev->blkdev = bdev;
-+	strcpy(dev->devname, devname);
- 
+-
 -	if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
 -		ERROR("attempting to use an MTD device as a block device");
-+	if (_open_bdev(dev))
- 		goto devinit_err;
+-		goto devinit_err;
 -	}
  
  	mutex_init(&dev->write_mutex);
@@ -312,7 +298,7 @@ index 2ebb4c6..4052874 100644
  
  	/* Setup the MTD structure */
  	/* make the name contain the block device in */
-@@ -281,6 +377,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, const cha
+@@ -274,6 +368,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, const cha
  	dev->mtd._read = block2mtd_read;
  	dev->mtd.priv = dev;
  	dev->mtd.owner = THIS_MODULE;
@@ -320,6 +306,3 @@ index 2ebb4c6..4052874 100644
  
  	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
  	part->name = name;
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/473-mtd_m25p80_add_w25q128.patch b/bsp/routerstationpro/473-mtd_m25p80_add_w25q128.patch
index 1fbbe4a8fb7120280cc0bd6de73b679a6777032a..6af74c744008cb9e73becad6fbdca7618e4d2b33 100644
--- a/bsp/routerstationpro/473-mtd_m25p80_add_w25q128.patch
+++ b/bsp/routerstationpro/473-mtd_m25p80_add_w25q128.patch
@@ -19,22 +19,15 @@ Path to patch in the repo is: target/linux/generic/patches-3.3
 Repo is: git://nbd.name/openwrt.git
 
 Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- drivers/mtd/devices/m25p80.c |    1 +
- 1 file changed, 1 insertion(+)
-
 diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
-index 0351b17..4ee1352 100644
+index 363ecc9..04882c1 100644
 --- a/drivers/mtd/devices/m25p80.c
 +++ b/drivers/mtd/devices/m25p80.c
-@@ -734,6 +734,7 @@ static const struct spi_device_id m25p_ids[] = {
- 	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
+@@ -739,6 +739,7 @@ static const struct spi_device_id m25p_ids[] = {
  	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
  	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+ 	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
 +	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
  
  	/* Catalyst / On Semiconductor -- non-JEDEC */
  	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/721-phy_packets.patch b/bsp/routerstationpro/721-phy_packets.patch
index 69893b0c35f02c1f4287ae2aa3c44db6926b44c4..927555824d965b3a079c14f5172781e1290fb74a 100644
--- a/bsp/routerstationpro/721-phy_packets.patch
+++ b/bsp/routerstationpro/721-phy_packets.patch
@@ -19,33 +19,24 @@ Path to patch in the repo is: target/linux/generic/patches-3.3
 Repo is: git://nbd.name/openwrt.git
 
 Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- include/linux/if.h        |    1 +
- include/linux/netdevice.h |    8 ++++++++
- include/linux/skbuff.h    |   14 ++++----------
- net/Kconfig               |    6 ++++++
- net/core/dev.c            |   32 ++++++++++++++++++++++++++------
- net/core/skbuff.c         |   17 +++++++++++++++++
- net/ethernet/eth.c        |    6 ++++++
- 7 files changed, 68 insertions(+), 16 deletions(-)
-
 diff --git a/include/linux/if.h b/include/linux/if.h
-index f995c66..99bd777 100644
+index 1ec407b..dadb899 100644
 --- a/include/linux/if.h
 +++ b/include/linux/if.h
-@@ -81,6 +81,7 @@
- #define IFF_UNICAST_FLT	0x20000		/* Supports unicast filtering	*/
- #define IFF_TEAM_PORT	0x40000		/* device used as team port */
- #define IFF_SUPP_NOFCS	0x80000		/* device supports sending custom FCS */
-+#define IFF_NO_IP_ALIGN	0x100000	/* do not ip-align allocated rx pkts */
+@@ -84,6 +84,8 @@
+ #define IFF_LIVE_ADDR_CHANGE 0x100000	/* device supports hardware address
+ 					 * change when it's running */
  
++#define IFF_NO_IP_ALIGN	0x200000	/* do not ip-align allocated rx pkts */
++
  
  #define IF_GET_IFACE	0x0001		/* for querying only */
+ #define IF_GET_PROTO	0x0002
 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
-index 33900a5..879d8db 100644
+index 59dc05f3..0d87c9d 100644
 --- a/include/linux/netdevice.h
 +++ b/include/linux/netdevice.h
-@@ -1079,6 +1079,11 @@ struct net_device {
+@@ -1102,6 +1102,11 @@ struct net_device {
  	const struct net_device_ops *netdev_ops;
  	const struct ethtool_ops *ethtool_ops;
  
@@ -57,7 +48,7 @@ index 33900a5..879d8db 100644
  	/* Hardware header description */
  	const struct header_ops *header_ops;
  
-@@ -1136,6 +1141,9 @@ struct net_device {
+@@ -1158,6 +1163,9 @@ struct net_device {
  	void			*ax25_ptr;	/* AX.25 specific data */
  	struct wireless_dev	*ieee80211_ptr;	/* IEEE 802.11 specific data,
  						   assign before registering */
@@ -68,24 +59,24 @@ index 33900a5..879d8db 100644
  /*
   * Cache lines mostly used on receive path (including eth_type_trans())
 diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
-index 111f26b..6ea1851 100644
+index 7632c87..033fa6e 100644
 --- a/include/linux/skbuff.h
 +++ b/include/linux/skbuff.h
-@@ -1690,6 +1690,10 @@ extern struct sk_buff *dev_alloc_skb(unsigned int length);
- extern struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
- 		unsigned int length, gfp_t gfp_mask);
+@@ -1687,6 +1687,10 @@ static inline void skb_orphan(struct sk_buff *skb)
+ 	skb->sk		= NULL;
+ }
  
 +extern struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
 +		unsigned int length, gfp_t gfp);
 +
 +
  /**
-  *	netdev_alloc_skb - allocate an skbuff for rx on a specific device
-  *	@dev: network device to receive on
-@@ -1709,16 +1713,6 @@ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
- 	return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
+  *	skb_orphan_frags - orphan the frags contained in a buffer
+  *	@skb: buffer to orphan frags from
+@@ -1758,16 +1762,6 @@ static inline struct sk_buff *dev_alloc_skb(unsigned int length)
  }
  
+ 
 -static inline struct sk_buff *__netdev_alloc_skb_ip_align(struct net_device *dev,
 -		unsigned int length, gfp_t gfp)
 -{
@@ -100,7 +91,7 @@ index 111f26b..6ea1851 100644
  		unsigned int length)
  {
 diff --git a/net/Kconfig b/net/Kconfig
-index e07272d..b3904e8 100644
+index 245831b..900e9dd 100644
 --- a/net/Kconfig
 +++ b/net/Kconfig
 @@ -23,6 +23,12 @@ menuconfig NET
@@ -117,10 +108,10 @@ index e07272d..b3904e8 100644
  	bool
  	help
 diff --git a/net/core/dev.c b/net/core/dev.c
-index 99e1d75..47c8660 100644
+index 8398836..374a4e8 100644
 --- a/net/core/dev.c
 +++ b/net/core/dev.c
-@@ -2231,9 +2231,19 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
+@@ -2242,9 +2242,19 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
  			}
  		}
  
@@ -143,7 +134,7 @@ index 99e1d75..47c8660 100644
  		if (rc == NETDEV_TX_OK)
  			txq_trans_update(txq);
  		return rc;
-@@ -2253,9 +2263,19 @@ gso:
+@@ -2264,9 +2274,19 @@ gso:
  		if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
  			skb_dst_drop(nskb);
  
@@ -167,10 +158,10 @@ index 99e1d75..47c8660 100644
  			if (rc & ~NETDEV_TX_MASK)
  				goto out_kfree_gso_skb;
 diff --git a/net/core/skbuff.c b/net/core/skbuff.c
-index e598400..66f366f 100644
+index fe00d12..9b77747 100644
 --- a/net/core/skbuff.c
 +++ b/net/core/skbuff.c
-@@ -58,6 +58,7 @@
+@@ -60,6 +60,7 @@
  #include <linux/scatterlist.h>
  #include <linux/errqueue.h>
  #include <linux/prefetch.h>
@@ -178,7 +169,7 @@ index e598400..66f366f 100644
  
  #include <net/protocol.h>
  #include <net/dst.h>
-@@ -319,6 +320,22 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
+@@ -441,6 +442,22 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
  }
  EXPORT_SYMBOL(__netdev_alloc_skb);
  
@@ -202,7 +193,7 @@ index e598400..66f366f 100644
  		     int size, unsigned int truesize)
  {
 diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
-index bf10a31..54ec04a 100644
+index 4efad53..20de891 100644
 --- a/net/ethernet/eth.c
 +++ b/net/ethernet/eth.c
 @@ -159,6 +159,12 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
@@ -218,6 +209,3 @@ index bf10a31..54ec04a 100644
  	skb_reset_mac_header(skb);
  	skb_pull_inline(skb, ETH_HLEN);
  	eth = eth_hdr(skb);
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch b/bsp/routerstationpro/MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch
deleted file mode 100644
index c47a625494a5a0a0dc8d90dfd17f720ae0e111f4..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch
+++ /dev/null
@@ -1,71 +0,0 @@
-From 9393ad8cc039e33c60f0c2677654bf2df61ccd06 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:26 +0100
-Subject: [PATCH 058/123] MIPS: ath79: add AR934X specific glue to
- ath79_device_reset_{clear,set}
-
-commit 42184768b36b2dad88a3705d689891b5da884c85 upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3511/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/common.c                       |    9 ++++++++-
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    1 +
- 2 files changed, 9 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
-index f0fda98..5a4adfc 100644
---- a/arch/mips/ath79/common.c
-+++ b/arch/mips/ath79/common.c
-@@ -1,9 +1,12 @@
- /*
-  *  Atheros AR71XX/AR724X/AR913X common routines
-  *
-- *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
-+ *
-  *  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.
-@@ -67,6 +70,8 @@ void ath79_device_reset_set(u32 mask)
- 		reg = AR913X_RESET_REG_RESET_MODULE;
- 	else if (soc_is_ar933x())
- 		reg = AR933X_RESET_REG_RESET_MODULE;
-+	else if (soc_is_ar934x())
-+		reg = AR934X_RESET_REG_RESET_MODULE;
- 	else
- 		BUG();
- 
-@@ -91,6 +96,8 @@ void ath79_device_reset_clear(u32 mask)
- 		reg = AR913X_RESET_REG_RESET_MODULE;
- 	else if (soc_is_ar933x())
- 		reg = AR933X_RESET_REG_RESET_MODULE;
-+	else if (soc_is_ar934x())
-+		reg = AR934X_RESET_REG_RESET_MODULE;
- 	else
- 		BUG();
- 
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index d6af4eb..32abbf9 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -227,6 +227,7 @@
- #define AR933X_RESET_REG_RESET_MODULE		0x1c
- #define AR933X_RESET_REG_BOOTSTRAP		0xac
- 
-+#define AR934X_RESET_REG_RESET_MODULE		0x1c
- #define AR934X_RESET_REG_BOOTSTRAP		0xb0
- #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS	0xac
- 
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-GPIO-support-code-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-GPIO-support-code-for-AR934X.patch
deleted file mode 100644
index 3d4ff5542be50c397c2ab109aceff9c6f1693579..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-GPIO-support-code-for-AR934X.patch
+++ /dev/null
@@ -1,112 +0,0 @@
-From 1888cc4c0970b6ce35613fae377714c9e84009c4 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:23 +0100
-Subject: [PATCH 055/123] MIPS: ath79: add GPIO support code for AR934X
-
-commit 5b5b544ed32a1b6ad4d7706fcee530eb67670e71 upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3508/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/gpio.c                         |   47 +++++++++++++++++++++++-
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    1 +
- 2 files changed, 47 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
-index a2f8ca6..29054f2 100644
---- a/arch/mips/ath79/gpio.c
-+++ b/arch/mips/ath79/gpio.c
-@@ -1,9 +1,12 @@
- /*
-  *  Atheros AR71XX/AR724X/AR913X GPIO API support
-  *
-- *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
-+ *
-  *  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.
-@@ -89,6 +92,42 @@ static int ath79_gpio_direction_output(struct gpio_chip *chip,
- 	return 0;
- }
- 
-+static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
-+{
-+	void __iomem *base = ath79_gpio_base;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&ath79_gpio_lock, flags);
-+
-+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
-+		     base + AR71XX_GPIO_REG_OE);
-+
-+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
-+
-+	return 0;
-+}
-+
-+static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
-+					int value)
-+{
-+	void __iomem *base = ath79_gpio_base;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&ath79_gpio_lock, flags);
-+
-+	if (value)
-+		__raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
-+	else
-+		__raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
-+
-+	__raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
-+		     base + AR71XX_GPIO_REG_OE);
-+
-+	spin_unlock_irqrestore(&ath79_gpio_lock, flags);
-+
-+	return 0;
-+}
-+
- static struct gpio_chip ath79_gpio_chip = {
- 	.label			= "ath79",
- 	.get			= ath79_gpio_get_value,
-@@ -155,11 +194,17 @@ void __init ath79_gpio_init(void)
- 		ath79_gpio_count = AR913X_GPIO_COUNT;
- 	else if (soc_is_ar933x())
- 		ath79_gpio_count = AR933X_GPIO_COUNT;
-+	else if (soc_is_ar934x())
-+		ath79_gpio_count = AR934X_GPIO_COUNT;
- 	else
- 		BUG();
- 
- 	ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
- 	ath79_gpio_chip.ngpio = ath79_gpio_count;
-+	if (soc_is_ar934x()) {
-+		ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
-+		ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
-+	}
- 
- 	err = gpiochip_add(&ath79_gpio_chip);
- 	if (err)
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index bc1c345..1a9234b 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -367,5 +367,6 @@
- #define AR724X_GPIO_COUNT		18
- #define AR913X_GPIO_COUNT		22
- #define AR933X_GPIO_COUNT		30
-+#define AR934X_GPIO_COUNT		23
- 
- #endif /* __ASM_MACH_AR71XX_REGS_H */
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch
deleted file mode 100644
index f4b83c609962abe9c1ca33a21a4e6972d70205a2..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch
+++ /dev/null
@@ -1,206 +0,0 @@
-From ccc78b5eb7858c59cf6e1a55baa5a45c7ce6d461 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:25 +0100
-Subject: [PATCH 057/123] MIPS: ath79: add IRQ handling code for AR934X
-
-commit fce5cc6e0ddc601e504063548034766c5c5a78d1 upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3510/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/irq.c                          |   55 +++++++++++++++++++++++-
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |   25 +++++++++++
- arch/mips/include/asm/mach-ath79/irq.h         |    6 ++-
- 3 files changed, 83 insertions(+), 3 deletions(-)
-
-diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
-index 9f87ade..90d09fc 100644
---- a/arch/mips/ath79/irq.c
-+++ b/arch/mips/ath79/irq.c
-@@ -1,10 +1,11 @@
- /*
-  *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
-  *
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-- *  Parts of this file are based on Atheros' 2.6.15 BSP
-+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
-  *
-  *  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
-@@ -129,7 +130,7 @@ static void __init ath79_misc_irq_init(void)
- 
- 	if (soc_is_ar71xx() || soc_is_ar913x())
- 		ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
--	else if (soc_is_ar724x() || soc_is_ar933x())
-+	else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x())
- 		ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
- 	else
- 		BUG();
-@@ -143,6 +144,39 @@ static void __init ath79_misc_irq_init(void)
- 	irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
- }
- 
-+static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
-+{
-+	u32 status;
-+
-+	disable_irq_nosync(irq);
-+
-+	status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS);
-+
-+	if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) {
-+		ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE);
-+		generic_handle_irq(ATH79_IP2_IRQ(0));
-+	} else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) {
-+		ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC);
-+		generic_handle_irq(ATH79_IP2_IRQ(1));
-+	} else {
-+		spurious_interrupt();
-+	}
-+
-+	enable_irq(irq);
-+}
-+
-+static void ar934x_ip2_irq_init(void)
-+{
-+	int i;
-+
-+	for (i = ATH79_IP2_IRQ_BASE;
-+	     i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
-+		irq_set_chip_and_handler(i, &dummy_irq_chip,
-+					 handle_level_irq);
-+
-+	irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch);
-+}
-+
- asmlinkage void plat_irq_dispatch(void)
- {
- 	unsigned long pending;
-@@ -202,6 +236,11 @@ static void ar933x_ip2_handler(void)
- 	do_IRQ(ATH79_CPU_IRQ_IP2);
- }
- 
-+static void ar934x_ip2_handler(void)
-+{
-+	do_IRQ(ATH79_CPU_IRQ_IP2);
-+}
-+
- static void ar71xx_ip3_handler(void)
- {
- 	ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
-@@ -226,6 +265,12 @@ static void ar933x_ip3_handler(void)
- 	do_IRQ(ATH79_CPU_IRQ_USB);
- }
- 
-+static void ar934x_ip3_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB);
-+	do_IRQ(ATH79_CPU_IRQ_USB);
-+}
-+
- void __init arch_init_irq(void)
- {
- 	if (soc_is_ar71xx()) {
-@@ -240,6 +285,9 @@ void __init arch_init_irq(void)
- 	} else if (soc_is_ar933x()) {
- 		ath79_ip2_handler = ar933x_ip2_handler;
- 		ath79_ip3_handler = ar933x_ip3_handler;
-+	} else if (soc_is_ar934x()) {
-+		ath79_ip2_handler = ar934x_ip2_handler;
-+		ath79_ip3_handler = ar934x_ip3_handler;
- 	} else {
- 		BUG();
- 	}
-@@ -247,4 +295,7 @@ void __init arch_init_irq(void)
- 	cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
- 	mips_cpu_irq_init();
- 	ath79_misc_irq_init();
-+
-+	if (soc_is_ar934x())
-+		ar934x_ip2_irq_init();
- }
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index 1a9234b..d6af4eb 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -92,6 +92,12 @@
- #define AR933X_DDR_REG_FLUSH_USB	0x84
- #define AR933X_DDR_REG_FLUSH_WMAC	0x88
- 
-+#define AR934X_DDR_REG_FLUSH_GE0	0x9c
-+#define AR934X_DDR_REG_FLUSH_GE1	0xa0
-+#define AR934X_DDR_REG_FLUSH_USB	0xa4
-+#define AR934X_DDR_REG_FLUSH_PCIE	0xa8
-+#define AR934X_DDR_REG_FLUSH_WMAC	0xac
-+
- /*
-  * PLL block
-  */
-@@ -222,6 +228,7 @@
- #define AR933X_RESET_REG_BOOTSTRAP		0xac
- 
- #define AR934X_RESET_REG_BOOTSTRAP		0xb0
-+#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS	0xac
- 
- #define MISC_INT_ETHSW			BIT(12)
- #define MISC_INT_TIMER4			BIT(10)
-@@ -295,6 +302,24 @@
- #define AR934X_BOOTSTRAP_SDRAM_DISABLED	BIT(1)
- #define AR934X_BOOTSTRAP_DDR1		BIT(0)
- 
-+#define AR934X_PCIE_WMAC_INT_WMAC_MISC		BIT(0)
-+#define AR934X_PCIE_WMAC_INT_WMAC_TX		BIT(1)
-+#define AR934X_PCIE_WMAC_INT_WMAC_RXLP		BIT(2)
-+#define AR934X_PCIE_WMAC_INT_WMAC_RXHP		BIT(3)
-+#define AR934X_PCIE_WMAC_INT_PCIE_RC		BIT(4)
-+#define AR934X_PCIE_WMAC_INT_PCIE_RC0		BIT(5)
-+#define AR934X_PCIE_WMAC_INT_PCIE_RC1		BIT(6)
-+#define AR934X_PCIE_WMAC_INT_PCIE_RC2		BIT(7)
-+#define AR934X_PCIE_WMAC_INT_PCIE_RC3		BIT(8)
-+#define AR934X_PCIE_WMAC_INT_WMAC_ALL \
-+	(AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \
-+	 AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP)
-+
-+#define AR934X_PCIE_WMAC_INT_PCIE_ALL \
-+	(AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \
-+	 AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
-+	 AR934X_PCIE_WMAC_INT_PCIE_RC3)
-+
- #define REV_ID_MAJOR_MASK		0xfff0
- #define REV_ID_MAJOR_AR71XX		0x00a0
- #define REV_ID_MAJOR_AR913X		0x00b0
-diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
-index 6ae2646..0968f69 100644
---- a/arch/mips/include/asm/mach-ath79/irq.h
-+++ b/arch/mips/include/asm/mach-ath79/irq.h
-@@ -10,7 +10,7 @@
- #define __ASM_MACH_ATH79_IRQ_H
- 
- #define MIPS_CPU_IRQ_BASE	0
--#define NR_IRQS			46
-+#define NR_IRQS			48
- 
- #define ATH79_MISC_IRQ_BASE	8
- #define ATH79_MISC_IRQ_COUNT	32
-@@ -19,6 +19,10 @@
- #define ATH79_PCI_IRQ_COUNT	6
- #define ATH79_PCI_IRQ(_x)	(ATH79_PCI_IRQ_BASE + (_x))
- 
-+#define ATH79_IP2_IRQ_BASE	(ATH79_PCI_IRQ_BASE + ATH79_PCI_IRQ_COUNT)
-+#define ATH79_IP2_IRQ_COUNT	2
-+#define ATH79_IP2_IRQ(_x)	(ATH79_IP2_IRQ_BASE + (_x))
-+
- #define ATH79_CPU_IRQ_IP2	(MIPS_CPU_IRQ_BASE + 2)
- #define ATH79_CPU_IRQ_USB	(MIPS_CPU_IRQ_BASE + 3)
- #define ATH79_CPU_IRQ_GE0	(MIPS_CPU_IRQ_BASE + 4)
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch b/bsp/routerstationpro/MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch
deleted file mode 100644
index 7456b0db743c41602a3f55a6929bf42e39a7fe43..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch
+++ /dev/null
@@ -1,226 +0,0 @@
-From 2ca92e63aa807d3daccb6af4b11a9bf2ec1809b5 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:07 +0100
-Subject: [PATCH 043/123] MIPS: ath79: add PCI IRQ handling code for AR724X
- SoCs
-
-commit 4c07c7dfa0f3575dc3276c544349fbf181381167 upstream.
-
-The PCI Host Controller of the AR724x SoC has a
-built-in IRQ controller. The current code does
-not supports that, so the IRQ lines wired to this
-controller are not usable. This leads to failed
-'request_irq' calls:
-
-  ath9k 0000:00:00.0: request_irq failed
-  ath9k: probe of 0000:00:00.0 failed with error -89
-
-This patch adds support for the IRQ controller
-in order to make PCI IRQs work.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc:  linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3496/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/pci.c                  |    3 +-
- arch/mips/include/asm/mach-ath79/pci.h |    4 +-
- arch/mips/pci/pci-ar724x.c             |  118 +++++++++++++++++++++++++++++++-
- 3 files changed, 120 insertions(+), 5 deletions(-)
-
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 72281fb..14f981c2 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -10,6 +10,7 @@
- 
- #include <linux/pci.h>
- #include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/irq.h>
- #include <asm/mach-ath79/pci.h>
- #include "pci.h"
- 
-@@ -50,7 +51,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
- int __init ath79_register_pci(void)
- {
- 	if (soc_is_ar724x())
--		return ar724x_pcibios_init();
-+		return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);
- 
- 	return -ENODEV;
- }
-diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
-index 6d7a837..2eb0181 100644
---- a/arch/mips/include/asm/mach-ath79/pci.h
-+++ b/arch/mips/include/asm/mach-ath79/pci.h
-@@ -12,9 +12,9 @@
- #define __ASM_MACH_ATH79_PCI_H
- 
- #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X)
--int ar724x_pcibios_init(void);
-+int ar724x_pcibios_init(int irq);
- #else
--static inline int ar724x_pcibios_init(void) { return 0; }
-+static inline int ar724x_pcibios_init(int irq) { return 0; }
- #endif
- 
- #endif /* __ASM_MACH_ATH79_PCI_H */
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index 07b7e30..04f433a 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -8,19 +8,32 @@
-  *  by the Free Software Foundation.
-  */
- 
-+#include <linux/irq.h>
- #include <linux/pci.h>
- #include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/ar71xx_regs.h>
- #include <asm/mach-ath79/pci.h>
- 
- #define AR724X_PCI_CFG_BASE	0x14000000
- #define AR724X_PCI_CFG_SIZE	0x1000
-+#define AR724X_PCI_CTRL_BASE	(AR71XX_APB_BASE + 0x000f0000)
-+#define AR724X_PCI_CTRL_SIZE	0x100
-+
- #define AR724X_PCI_MEM_BASE	0x10000000
- #define AR724X_PCI_MEM_SIZE	0x08000000
- 
-+#define AR724X_PCI_REG_INT_STATUS	0x4c
-+#define AR724X_PCI_REG_INT_MASK		0x50
-+
-+#define AR724X_PCI_INT_DEV0		BIT(14)
-+
-+#define AR724X_PCI_IRQ_COUNT		1
-+
- #define AR7240_BAR0_WAR_VALUE	0xffff
- 
- static DEFINE_SPINLOCK(ar724x_pci_lock);
- static void __iomem *ar724x_pci_devcfg_base;
-+static void __iomem *ar724x_pci_ctrl_base;
- 
- static u32 ar724x_pci_bar0_value;
- static bool ar724x_pci_bar0_is_cached;
-@@ -164,14 +177,115 @@ static struct pci_controller ar724x_pci_controller = {
- 	.mem_resource	= &ar724x_mem_resource,
- };
- 
--int __init ar724x_pcibios_init(void)
-+static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
-+{
-+	void __iomem *base;
-+	u32 pending;
-+
-+	base = ar724x_pci_ctrl_base;
-+
-+	pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) &
-+		  __raw_readl(base + AR724X_PCI_REG_INT_MASK);
-+
-+	if (pending & AR724X_PCI_INT_DEV0)
-+		generic_handle_irq(ATH79_PCI_IRQ(0));
-+
-+	else
-+		spurious_interrupt();
-+}
-+
-+static void ar724x_pci_irq_unmask(struct irq_data *d)
-+{
-+	void __iomem *base;
-+	u32 t;
-+
-+	base = ar724x_pci_ctrl_base;
-+
-+	switch (d->irq) {
-+	case ATH79_PCI_IRQ(0):
-+		t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
-+		__raw_writel(t | AR724X_PCI_INT_DEV0,
-+			     base + AR724X_PCI_REG_INT_MASK);
-+		/* flush write */
-+		__raw_readl(base + AR724X_PCI_REG_INT_MASK);
-+	}
-+}
-+
-+static void ar724x_pci_irq_mask(struct irq_data *d)
-+{
-+	void __iomem *base;
-+	u32 t;
-+
-+	base = ar724x_pci_ctrl_base;
-+
-+	switch (d->irq) {
-+	case ATH79_PCI_IRQ(0):
-+		t = __raw_readl(base + AR724X_PCI_REG_INT_MASK);
-+		__raw_writel(t & ~AR724X_PCI_INT_DEV0,
-+			     base + AR724X_PCI_REG_INT_MASK);
-+
-+		/* flush write */
-+		__raw_readl(base + AR724X_PCI_REG_INT_MASK);
-+
-+		t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS);
-+		__raw_writel(t | AR724X_PCI_INT_DEV0,
-+			     base + AR724X_PCI_REG_INT_STATUS);
-+
-+		/* flush write */
-+		__raw_readl(base + AR724X_PCI_REG_INT_STATUS);
-+	}
-+}
-+
-+static struct irq_chip ar724x_pci_irq_chip = {
-+	.name		= "AR724X PCI ",
-+	.irq_mask	= ar724x_pci_irq_mask,
-+	.irq_unmask	= ar724x_pci_irq_unmask,
-+	.irq_mask_ack	= ar724x_pci_irq_mask,
-+};
-+
-+static void __init ar724x_pci_irq_init(int irq)
-+{
-+	void __iomem *base;
-+	int i;
-+
-+	base = ar724x_pci_ctrl_base;
-+
-+	__raw_writel(0, base + AR724X_PCI_REG_INT_MASK);
-+	__raw_writel(0, base + AR724X_PCI_REG_INT_STATUS);
-+
-+	BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT);
-+
-+	for (i = ATH79_PCI_IRQ_BASE;
-+	     i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++)
-+		irq_set_chip_and_handler(i, &ar724x_pci_irq_chip,
-+					 handle_level_irq);
-+
-+	irq_set_chained_handler(irq, ar724x_pci_irq_handler);
-+}
-+
-+int __init ar724x_pcibios_init(int irq)
- {
-+	int ret;
-+
-+	ret = -ENOMEM;
-+
- 	ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
- 					 AR724X_PCI_CFG_SIZE);
- 	if (ar724x_pci_devcfg_base == NULL)
--		return -ENOMEM;
-+		goto err;
- 
-+	ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE,
-+				       AR724X_PCI_CTRL_SIZE);
-+	if (ar724x_pci_ctrl_base == NULL)
-+		goto err_unmap_devcfg;
-+
-+	ar724x_pci_irq_init(irq);
- 	register_pci_controller(&ar724x_pci_controller);
- 
- 	return PCIBIOS_SUCCESSFUL;
-+
-+err_unmap_devcfg:
-+	iounmap(ar724x_pci_devcfg_base);
-+err:
-+	return ret;
- }
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-PCI-registration-code-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-PCI-registration-code-for-AR934X.patch
deleted file mode 100644
index 8ed3bc8ab7365fb767b13ad646474a93e019dc31..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-PCI-registration-code-for-AR934X.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From 948c9cb436fa221a59d92774151d99c1e0e8a3f6 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:30 +0100
-Subject: [PATCH 062/123] MIPS: ath79: add PCI registration code for AR934X
-
-commit ec9502599cd837c8e4e279585817d1ffb1249126 upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3516/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Kconfig |    2 ++
- arch/mips/ath79/pci.c   |   13 ++++++++++++-
- 2 files changed, 14 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
-index 123cc37..ea28e89 100644
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -72,6 +72,8 @@ config SOC_AR933X
- 
- config SOC_AR934X
- 	select USB_ARCH_HAS_EHCI
-+	select HW_HAS_PCI
-+	select PCI_AR724X if PCI
- 	def_bool n
- 
- config PCI_AR724X
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index bc40070..ca83abd 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -14,6 +14,7 @@
- 
- #include <linux/init.h>
- #include <linux/pci.h>
-+#include <asm/mach-ath79/ar71xx_regs.h>
- #include <asm/mach-ath79/ath79.h>
- #include <asm/mach-ath79/irq.h>
- #include <asm/mach-ath79/pci.h>
-@@ -57,7 +58,9 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
- 		if (soc_is_ar71xx()) {
- 			ath79_pci_irq_map = ar71xx_pci_irq_map;
- 			ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map);
--		} else if (soc_is_ar724x()) {
-+		} else if (soc_is_ar724x() ||
-+			   soc_is_ar9342() ||
-+			   soc_is_ar9344()) {
- 			ath79_pci_irq_map = ar724x_pci_irq_map;
- 			ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
- 		} else {
-@@ -115,5 +118,13 @@ int __init ath79_register_pci(void)
- 	if (soc_is_ar724x())
- 		return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);
- 
-+	if (soc_is_ar9342() || soc_is_ar9344()) {
-+		u32 bootstrap;
-+
-+		bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
-+		if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC)
-+			return ar724x_pcibios_init(ATH79_IP2_IRQ(0));
-+	}
-+
- 	return -ENODEV;
- }
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch b/bsp/routerstationpro/MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch
deleted file mode 100644
index b4b6e55ea736ec2536233dc2277ffb14d09c6538..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From d3d4cb2e7177db47d9200a0a50db11fafc20b5d9 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:29 +0100
-Subject: [PATCH 061/123] MIPS: ath79: add PCI_AR724X Kconfig symbol
-
-commit 67644c547fef2739f49c80e5eb1ace82f3e916e2 upstream.
-
-The AR724X specific PCI code can be used for the
-AR934X SoCs, however it can be selected only if
-SOC_AR724X is set.
-
-Introduce a new Kconfig symbol in order to be able
-to use the code for AR934X as well.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3514/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Kconfig                |    4 ++++
- arch/mips/include/asm/mach-ath79/pci.h |    2 +-
- arch/mips/pci/Makefile                 |    2 +-
- 3 files changed, 6 insertions(+), 2 deletions(-)
-
-diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
-index 5fa3d7b..123cc37 100644
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -59,6 +59,7 @@ config SOC_AR724X
- 	select USB_ARCH_HAS_EHCI
- 	select USB_ARCH_HAS_OHCI
- 	select HW_HAS_PCI
-+	select PCI_AR724X if PCI
- 	def_bool n
- 
- config SOC_AR913X
-@@ -73,6 +74,9 @@ config SOC_AR934X
- 	select USB_ARCH_HAS_EHCI
- 	def_bool n
- 
-+config PCI_AR724X
-+	def_bool n
-+
- config ATH79_DEV_GPIO_BUTTONS
- 	def_bool n
- 
-diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
-index 4f2222d..7868f7f 100644
---- a/arch/mips/include/asm/mach-ath79/pci.h
-+++ b/arch/mips/include/asm/mach-ath79/pci.h
-@@ -19,7 +19,7 @@ int ar71xx_pcibios_init(void);
- static inline int ar71xx_pcibios_init(void) { return 0; }
- #endif
- 
--#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X)
-+#if defined(CONFIG_PCI_AR724X)
- int ar724x_pcibios_init(int irq);
- #else
- static inline int ar724x_pcibios_init(int irq) { return 0; }
-diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
-index b1c0a1c..43c5138 100644
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -20,7 +20,7 @@ obj-$(CONFIG_BCM63XX)		+= pci-bcm63xx.o fixup-bcm63xx.o \
- 					ops-bcm63xx.o
- obj-$(CONFIG_MIPS_ALCHEMY)	+= pci-alchemy.o
- obj-$(CONFIG_SOC_AR71XX)	+= pci-ar71xx.o
--obj-$(CONFIG_SOC_AR724X)	+= pci-ar724x.o
-+obj-$(CONFIG_PCI_AR724X)	+= pci-ar724x.o
- 
- #
- # These are still pretty much in the old state, watch, go blind.
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-SoC-detection-code-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-SoC-detection-code-for-AR934X.patch
deleted file mode 100644
index 80fea083f04687bbe39933b82eb138aec5c04f69..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-SoC-detection-code-for-AR934X.patch
+++ /dev/null
@@ -1,138 +0,0 @@
-From 7f3d182ab0f3ad8b4a4be610c1d5372de11882a4 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:21 +0100
-Subject: [PATCH 053/123] MIPS: ath79: add SoC detection code for AR934X
-
-commit d84114660a65e89e27ebd3fb21ce71ff579ee882 upstream.
-
-Also add 'soc_is_ar934[124x]' helper functions and a Kconfig
-symbol for the AR934X SoCs.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3506/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Kconfig                        |    4 ++++
- arch/mips/ath79/setup.c                        |   21 ++++++++++++++++++++-
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    2 ++
- arch/mips/include/asm/mach-ath79/ath79.h       |   23 +++++++++++++++++++++++
- 4 files changed, 49 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
-index bc6edad..7db8e89 100644
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -69,6 +69,10 @@ config SOC_AR933X
- 	select USB_ARCH_HAS_EHCI
- 	def_bool n
- 
-+config SOC_AR934X
-+	select USB_ARCH_HAS_EHCI
-+	def_bool n
-+
- config ATH79_DEV_GPIO_BUTTONS
- 	def_bool n
- 
-diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
-index 24dfedf..60d212e 100644
---- a/arch/mips/ath79/setup.c
-+++ b/arch/mips/ath79/setup.c
-@@ -1,10 +1,11 @@
- /*
-  *  Atheros AR71XX/AR724X/AR913X specific setup
-  *
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-- *  Parts of this file are based on Atheros' 2.6.15 BSP
-+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
-  *
-  *  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
-@@ -145,6 +146,24 @@ static void __init ath79_detect_sys_type(void)
- 		rev = id & AR933X_REV_ID_REVISION_MASK;
- 		break;
- 
-+	case REV_ID_MAJOR_AR9341:
-+		ath79_soc = ATH79_SOC_AR9341;
-+		chip = "9341";
-+		rev = id & AR934X_REV_ID_REVISION_MASK;
-+		break;
-+
-+	case REV_ID_MAJOR_AR9342:
-+		ath79_soc = ATH79_SOC_AR9342;
-+		chip = "9342";
-+		rev = id & AR934X_REV_ID_REVISION_MASK;
-+		break;
-+
-+	case REV_ID_MAJOR_AR9344:
-+		ath79_soc = ATH79_SOC_AR9344;
-+		chip = "9344";
-+		rev = id & AR934X_REV_ID_REVISION_MASK;
-+		break;
-+
- 	default:
- 		panic("ath79: unknown SoC, id:0x%08x", id);
- 	}
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index b7df674..4e3c55d 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -271,6 +271,8 @@
- 
- #define AR724X_REV_ID_REVISION_MASK	0x3
- 
-+#define AR934X_REV_ID_REVISION_MASK     0xf
-+
- /*
-  * SPI block
-  */
-diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
-index 6d0c6c9..4f248c3 100644
---- a/arch/mips/include/asm/mach-ath79/ath79.h
-+++ b/arch/mips/include/asm/mach-ath79/ath79.h
-@@ -29,6 +29,9 @@ enum ath79_soc_type {
- 	ATH79_SOC_AR9132,
- 	ATH79_SOC_AR9330,
- 	ATH79_SOC_AR9331,
-+	ATH79_SOC_AR9341,
-+	ATH79_SOC_AR9342,
-+	ATH79_SOC_AR9344,
- };
- 
- extern enum ath79_soc_type ath79_soc;
-@@ -75,6 +78,26 @@ static inline int soc_is_ar933x(void)
- 		ath79_soc == ATH79_SOC_AR9331);
- }
- 
-+static inline int soc_is_ar9341(void)
-+{
-+	return (ath79_soc == ATH79_SOC_AR9341);
-+}
-+
-+static inline int soc_is_ar9342(void)
-+{
-+	return (ath79_soc == ATH79_SOC_AR9342);
-+}
-+
-+static inline int soc_is_ar9344(void)
-+{
-+	return (ath79_soc == ATH79_SOC_AR9344);
-+}
-+
-+static inline int soc_is_ar934x(void)
-+{
-+	return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
-+}
-+
- extern void __iomem *ath79_ddr_base;
- extern void __iomem *ath79_pll_base;
- extern void __iomem *ath79_reset_base;
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch
deleted file mode 100644
index 9132133e13a2c431b39a52994367a208860f1f31..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From eeed43de7f1608439208d463b702ce999c2df92d Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:28 +0100
-Subject: [PATCH 060/123] MIPS: ath79: add WMAC registration code for AR934X
-
-commit 574d6e70ea25a8d5dd4b77464ae7314d40f1caf2 upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3513/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Kconfig                        |    2 +-
- arch/mips/ath79/dev-wmac.c                     |   30 ++++++++++++++++++++++--
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    3 +++
- 3 files changed, 32 insertions(+), 3 deletions(-)
-
-diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
-index 7db8e89..5fa3d7b 100644
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -86,7 +86,7 @@ config ATH79_DEV_USB
- 	def_bool n
- 
- config ATH79_DEV_WMAC
--	depends on (SOC_AR913X || SOC_AR933X)
-+	depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X)
- 	def_bool n
- 
- endif
-diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c
-index 9c717bf..d6d893c 100644
---- a/arch/mips/ath79/dev-wmac.c
-+++ b/arch/mips/ath79/dev-wmac.c
-@@ -1,9 +1,12 @@
- /*
-  *  Atheros AR913X/AR933X SoC built-in WMAC device support
-  *
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-  *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-+ *  Parts of this file are based on Atheros 2.6.15/2.6.31 BSP
-+ *
-  *  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.
-@@ -26,8 +29,7 @@ static struct resource ath79_wmac_resources[] = {
- 		/* .start and .end fields are filled dynamically */
- 		.flags	= IORESOURCE_MEM,
- 	}, {
--		.start	= ATH79_CPU_IRQ_IP2,
--		.end	= ATH79_CPU_IRQ_IP2,
-+		/* .start and .end fields are filled dynamically */
- 		.flags	= IORESOURCE_IRQ,
- 	},
- };
-@@ -53,6 +55,8 @@ static void __init ar913x_wmac_setup(void)
- 
- 	ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
- 	ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
-+	ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2;
-+	ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2;
- }
- 
- 
-@@ -79,6 +83,8 @@ static void __init ar933x_wmac_setup(void)
- 
- 	ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
- 	ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
-+	ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2;
-+	ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2;
- 
- 	t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
- 	if (t & AR933X_BOOTSTRAP_REF_CLK_40)
-@@ -92,12 +98,32 @@ static void __init ar933x_wmac_setup(void)
- 	ath79_wmac_data.external_reset = ar933x_wmac_reset;
- }
- 
-+static void ar934x_wmac_setup(void)
-+{
-+	u32 t;
-+
-+	ath79_wmac_device.name = "ar934x_wmac";
-+
-+	ath79_wmac_resources[0].start = AR934X_WMAC_BASE;
-+	ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1;
-+	ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
-+	ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
-+
-+	t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
-+	if (t & AR934X_BOOTSTRAP_REF_CLK_40)
-+		ath79_wmac_data.is_clk_25mhz = false;
-+	else
-+		ath79_wmac_data.is_clk_25mhz = true;
-+}
-+
- void __init ath79_register_wmac(u8 *cal_data)
- {
- 	if (soc_is_ar913x())
- 		ar913x_wmac_setup();
- 	else if (soc_is_ar933x())
- 		ar933x_wmac_setup();
-+	else if (soc_is_ar934x())
-+		ar934x_wmac_setup();
- 	else
- 		BUG();
- 
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index 32abbf9..1caa78a 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -61,6 +61,9 @@
- #define AR933X_EHCI_BASE	0x1b000000
- #define AR933X_EHCI_SIZE	0x1000
- 
-+#define AR934X_WMAC_BASE	(AR71XX_APB_BASE + 0x00100000)
-+#define AR934X_WMAC_SIZE	0x20000
-+
- /*
-  * DDR_CTRL block
-  */
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-a-common-PCI-registration-function.patch b/bsp/routerstationpro/MIPS-ath79-add-a-common-PCI-registration-function.patch
deleted file mode 100644
index 1656642e91dcfd317bba6e0374a99227c761b944..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-a-common-PCI-registration-function.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From ef2ca80937f45011e5fb105de35db8581be0d556 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:24 +0100
-Subject: [PATCH 035/123] MIPS: ath79: add a common PCI registration function
-
-commit 6335aef59c55f50e6d8017a28c0ee985b533ea29 upstream.
-
-The current code unconditionally registers the AR724X
-specific PCI controller, even if the kernel is running
-on a different SoC.
-
-Add a common function for PCI controller registration,
-and only register the AR724X PCI controller if the kernel
-is running on an AR724X SoC.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3488/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c |    1 +
- arch/mips/ath79/pci.c          |   10 ++++++++++
- arch/mips/ath79/pci.h          |    6 ++++++
- arch/mips/pci/pci-ath724x.c    |    2 --
- 4 files changed, 17 insertions(+), 2 deletions(-)
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index a043500..edbc093 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -111,6 +111,7 @@ static void __init ubnt_xm_init(void)
- 	ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
- #endif /* CONFIG_PCI */
- 
-+	ath79_register_pci();
- }
- 
- MIPS_MACHINE(ATH79_MACH_UBNT_XM,
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 4957428..855a69d 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -9,6 +9,8 @@
-  */
- 
- #include <linux/pci.h>
-+#include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/pci.h>
- #include "pci.h"
- 
- static struct ath724x_pci_data *pci_data;
-@@ -44,3 +46,11 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
-+
-+int __init ath79_register_pci(void)
-+{
-+	if (soc_is_ar724x())
-+		return ath724x_pcibios_init();
-+
-+	return -ENODEV;
-+}
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-index 454885f..787fac2 100644
---- a/arch/mips/ath79/pci.h
-+++ b/arch/mips/ath79/pci.h
-@@ -18,4 +18,10 @@ struct ath724x_pci_data {
- 
- void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
- 
-+#ifdef CONFIG_PCI
-+int ath79_register_pci(void);
-+#else
-+static inline int ath79_register_pci(void) { return 0; }
-+#endif
-+
- #endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
-diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c
-index be01b7f..ebefc16 100644
---- a/arch/mips/pci/pci-ath724x.c
-+++ b/arch/mips/pci/pci-ath724x.c
-@@ -137,5 +137,3 @@ int __init ath724x_pcibios_init(void)
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
--
--arch_initcall(ath724x_pcibios_init);
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch b/bsp/routerstationpro/MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch
deleted file mode 100644
index 6b9bb6d34d0deac23ab71c98d82a0da41869a88d..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From 8ee7c348d8c2898872bc2b016c98bfa46b463317 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:05 +0100
-Subject: [PATCH 041/123] MIPS: ath79: add a workaround for a PCI controller
- bug in AR7240 SoCs
-
-commit 6015a856f16ccf33e9f83643d04c2e15be2384eb upstream.
-
-The PCI controller of the AR724X SoCs has a hardware
-bag. If the BAR0 register of the PCI device is set to
-the proper base address, the memory address space of
-the device is not accessible.
-
-When the device driver tries to access the memory
-address space of the PCI device, it leads to data
-bus error, similiar to this:
-
-Data bus error, epc == 801f69a0, ra == 801f698c
-Oops[#1]:
-Cpu 0
-$ 0   : 00000000 00000061 deadbeef 000000ff
-$ 4   : 00000000 000000ff 00000014 00000000
-$ 8   : ff000000 fffffffc 00000000 00000000
-$12   : 000001f5 00000006 00000000 6e637920
-$16   : 81ca4000 81ca0260 81ca4000 804d70f0
-$20   : fffffff4 0000002b 803ad4c4 00000000
-$24   : 00000003 00000000
-$28   : 81c20000 81c21c60 00000000 801f698c
-Hi    : 00000000
-Lo    : 00000000
-epc   : 801f69a0 ath9k_hw_init+0xd0/0xa70
-    Not tainted
-ra    : 801f698c ath9k_hw_init+0xbc/0xa70
-Status: 1000c103    KERNEL EXL IE
-Cause : 1080001c
-PrId  : 00019374 (MIPS 24Kc)
-Modules linked in:
-Process swapper (pid: 1, threadinfo=81c20000, task=81c18000, tls=00000000)
-Stack : 00000000 00000000 00000000 00000000 81c21c78 81ca0260 00000000 804d70f0
-        81ca0260 81c21cc0 81ca0e80 81ca0260 81ca4000 804d70f0 fffffff4 0000002b
-        803ad4c4 00000000 00000000 801e3ae8 81c9d080 81ca0e80 b0000000 800b9b9c
-        00000008 81c9d000 8031aeb0 802d38a0 00000000 81c14c00 81c14c60 00000000
-        81ca0e80 81ca0260 b0000000 801f08a4 81c9c820 81c21d48 81c9c820 80144320
-        ...
-Call Trace:
-[<801f69a0>] ath9k_hw_init+0xd0/0xa70
-[<801e3ae8>] ath9k_init_device+0x174/0x680
-[<801f08a4>] ath_pci_probe+0x27c/0x380
-[<8019e490>] pci_device_probe+0x74/0x9c
-[<801bfadc>] driver_probe_device+0x9c/0x1b4
-[<801bfcb0>] __driver_attach+0xbc/0xc4
-[<801bea0c>] bus_for_each_dev+0x5c/0x98
-[<801bf394>] bus_add_driver+0x1d0/0x2a4
-[<801c0364>] driver_register+0x8c/0x16c
-[<8019e72c>] __pci_register_driver+0x4c/0xe4
-[<803d3d40>] ath9k_init+0x3c/0x88
-[<80060930>] do_one_initcall+0x3c/0x1cc
-[<803c297c>] kernel_init+0xa4/0x138
-[<80063c04>] kernel_thread_helper+0x10/0x18
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3494/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/pci/pci-ar724x.c |   36 +++++++++++++++++++++++++++++++++++-
- 1 file changed, 35 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index bb4f216..07b7e30 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -9,6 +9,7 @@
-  */
- 
- #include <linux/pci.h>
-+#include <asm/mach-ath79/ath79.h>
- #include <asm/mach-ath79/pci.h>
- 
- #define AR724X_PCI_CFG_BASE	0x14000000
-@@ -16,9 +17,14 @@
- #define AR724X_PCI_MEM_BASE	0x10000000
- #define AR724X_PCI_MEM_SIZE	0x08000000
- 
-+#define AR7240_BAR0_WAR_VALUE	0xffff
-+
- static DEFINE_SPINLOCK(ar724x_pci_lock);
- static void __iomem *ar724x_pci_devcfg_base;
- 
-+static u32 ar724x_pci_bar0_value;
-+static bool ar724x_pci_bar0_is_cached;
-+
- static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 			    int size, uint32_t *value)
- {
-@@ -56,7 +62,14 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 	}
- 
- 	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
--	*value = data;
-+
-+	if (where == PCI_BASE_ADDRESS_0 && size == 4 &&
-+	    ar724x_pci_bar0_is_cached) {
-+		/* use the cached value */
-+		*value = ar724x_pci_bar0_value;
-+	} else {
-+		*value = data;
-+	}
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
-@@ -72,6 +85,27 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
- 
-+	if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) {
-+		if (value != 0xffffffff) {
-+			/*
-+			 * WAR for a hw issue. If the BAR0 register of the
-+			 * device is set to the proper base address, the
-+			 * memory space of the device is not accessible.
-+			 *
-+			 * Cache the intended value so it can be read back,
-+			 * and write a SoC specific constant value to the
-+			 * BAR0 register in order to make the device memory
-+			 * accessible.
-+			 */
-+			ar724x_pci_bar0_is_cached = true;
-+			ar724x_pci_bar0_value = value;
-+
-+			value = AR7240_BAR0_WAR_VALUE;
-+		} else {
-+			ar724x_pci_bar0_is_cached = false;
-+		}
-+	}
-+
- 	base = ar724x_pci_devcfg_base;
- 
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-clock-initialization-code-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-clock-initialization-code-for-AR934X.patch
deleted file mode 100644
index 1d5b36771feee857d49c8ca0fe64c88d71a9439b..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-clock-initialization-code-for-AR934X.patch
+++ /dev/null
@@ -1,209 +0,0 @@
-From 7e45fa2d4ced8609fe0178e77a86ba2e9e152567 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:22 +0100
-Subject: [PATCH 054/123] MIPS: ath79: add clock initialization code for
- AR934X
-
-commit 8889612b3e2054617219581ae10dbe33cf3bddfe upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3507/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/clock.c                        |   81 ++++++++++++++++++++++++
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |   53 ++++++++++++++++
- 2 files changed, 134 insertions(+)
-
-diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
-index 54d0eb4db..b91ad3e 100644
---- a/arch/mips/ath79/clock.c
-+++ b/arch/mips/ath79/clock.c
-@@ -1,8 +1,11 @@
- /*
-  *  Atheros AR71XX/AR724X/AR913X common routines
-  *
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-  *  Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
-  *
-+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
-+ *
-  *  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.
-@@ -163,6 +166,82 @@ static void __init ar933x_clocks_init(void)
- 	ath79_uart_clk.rate = ath79_ref_clk.rate;
- }
- 
-+static void __init ar934x_clocks_init(void)
-+{
-+	u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
-+	u32 cpu_pll, ddr_pll;
-+	u32 bootstrap;
-+
-+	bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
-+	if (bootstrap &	AR934X_BOOTSTRAP_REF_CLK_40)
-+		ath79_ref_clk.rate = 40 * 1000 * 1000;
-+	else
-+		ath79_ref_clk.rate = 25 * 1000 * 1000;
-+
-+	pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG);
-+	out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
-+		  AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
-+	ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
-+		  AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
-+	nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
-+	       AR934X_PLL_CPU_CONFIG_NINT_MASK;
-+	frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
-+	       AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
-+
-+	cpu_pll = nint * ath79_ref_clk.rate / ref_div;
-+	cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6));
-+	cpu_pll /= (1 << out_div);
-+
-+	pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG);
-+	out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
-+		  AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
-+	ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
-+		  AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
-+	nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
-+	       AR934X_PLL_DDR_CONFIG_NINT_MASK;
-+	frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
-+	       AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
-+
-+	ddr_pll = nint * ath79_ref_clk.rate / ref_div;
-+	ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10));
-+	ddr_pll /= (1 << out_div);
-+
-+	clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
-+
-+	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) &
-+		  AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK;
-+
-+	if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS)
-+		ath79_cpu_clk.rate = ath79_ref_clk.rate;
-+	else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL)
-+		ath79_cpu_clk.rate = cpu_pll / (postdiv + 1);
-+	else
-+		ath79_cpu_clk.rate = ddr_pll / (postdiv + 1);
-+
-+	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) &
-+		  AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK;
-+
-+	if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS)
-+		ath79_ddr_clk.rate = ath79_ref_clk.rate;
-+	else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL)
-+		ath79_ddr_clk.rate = ddr_pll / (postdiv + 1);
-+	else
-+		ath79_ddr_clk.rate = cpu_pll / (postdiv + 1);
-+
-+	postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) &
-+		  AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK;
-+
-+	if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS)
-+		ath79_ahb_clk.rate = ath79_ref_clk.rate;
-+	else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL)
-+		ath79_ahb_clk.rate = ddr_pll / (postdiv + 1);
-+	else
-+		ath79_ahb_clk.rate = cpu_pll / (postdiv + 1);
-+
-+	ath79_wdt_clk.rate = ath79_ref_clk.rate;
-+	ath79_uart_clk.rate = ath79_ref_clk.rate;
-+}
-+
- void __init ath79_clocks_init(void)
- {
- 	if (soc_is_ar71xx())
-@@ -173,6 +252,8 @@ void __init ath79_clocks_init(void)
- 		ar913x_clocks_init();
- 	else if (soc_is_ar933x())
- 		ar933x_clocks_init();
-+	else if (soc_is_ar934x())
-+		ar934x_clocks_init();
- 	else
- 		BUG();
- 
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index 4e3c55d..bc1c345 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -151,6 +151,41 @@
- #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT	15
- #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK	0x7
- 
-+#define AR934X_PLL_CPU_CONFIG_REG		0x00
-+#define AR934X_PLL_DDR_CONFIG_REG		0x04
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG		0x08
-+
-+#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT	0
-+#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK	0x3f
-+#define AR934X_PLL_CPU_CONFIG_NINT_SHIFT	6
-+#define AR934X_PLL_CPU_CONFIG_NINT_MASK		0x3f
-+#define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT	12
-+#define AR934X_PLL_CPU_CONFIG_REFDIV_MASK	0x1f
-+#define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT	19
-+#define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK	0x3
-+
-+#define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT	0
-+#define AR934X_PLL_DDR_CONFIG_NFRAC_MASK	0x3ff
-+#define AR934X_PLL_DDR_CONFIG_NINT_SHIFT	10
-+#define AR934X_PLL_DDR_CONFIG_NINT_MASK		0x3f
-+#define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT	16
-+#define AR934X_PLL_DDR_CONFIG_REFDIV_MASK	0x1f
-+#define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT	23
-+#define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK	0x7
-+
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS	BIT(2)
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS	BIT(3)
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS	BIT(4)
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT	5
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK	0x1f
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT	10
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK	0x1f
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT	15
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK	0x1f
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL	BIT(20)
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL	BIT(21)
-+#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL	BIT(24)
-+
- /*
-  * USB_CONFIG block
-  */
-@@ -186,6 +221,8 @@
- #define AR933X_RESET_REG_RESET_MODULE		0x1c
- #define AR933X_RESET_REG_BOOTSTRAP		0xac
- 
-+#define AR934X_RESET_REG_BOOTSTRAP		0xb0
-+
- #define MISC_INT_ETHSW			BIT(12)
- #define MISC_INT_TIMER4			BIT(10)
- #define MISC_INT_TIMER3			BIT(9)
-@@ -242,6 +279,22 @@
- 
- #define AR933X_BOOTSTRAP_REF_CLK_40	BIT(0)
- 
-+#define AR934X_BOOTSTRAP_SW_OPTION8	BIT(23)
-+#define AR934X_BOOTSTRAP_SW_OPTION7	BIT(22)
-+#define AR934X_BOOTSTRAP_SW_OPTION6	BIT(21)
-+#define AR934X_BOOTSTRAP_SW_OPTION5	BIT(20)
-+#define AR934X_BOOTSTRAP_SW_OPTION4	BIT(19)
-+#define AR934X_BOOTSTRAP_SW_OPTION3	BIT(18)
-+#define AR934X_BOOTSTRAP_SW_OPTION2	BIT(17)
-+#define AR934X_BOOTSTRAP_SW_OPTION1	BIT(16)
-+#define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7)
-+#define AR934X_BOOTSTRAP_PCIE_RC	BIT(6)
-+#define AR934X_BOOTSTRAP_EJTAG_MODE	BIT(5)
-+#define AR934X_BOOTSTRAP_REF_CLK_40	BIT(4)
-+#define AR934X_BOOTSTRAP_BOOT_FROM_SPI	BIT(2)
-+#define AR934X_BOOTSTRAP_SDRAM_DISABLED	BIT(1)
-+#define AR934X_BOOTSTRAP_DDR1		BIT(0)
-+
- #define REV_ID_MAJOR_MASK		0xfff0
- #define REV_ID_MAJOR_AR71XX		0x00a0
- #define REV_ID_MAJOR_AR913X		0x00b0
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-early_printk-support-for-AR934X.patch b/bsp/routerstationpro/MIPS-ath79-add-early_printk-support-for-AR934X.patch
deleted file mode 100644
index 0d484471eaf124511a95e9233127f14d45abfa3d..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-early_printk-support-for-AR934X.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-From 3802fecde5ef3e16312b4fd4ddfb9bd9a427885b Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:19 +0100
-Subject: [PATCH 051/123] MIPS: ath79: add early_printk support for AR934X
-
-commit 703327ddcc736a054f4e2c132235a8370d2f7870 upstream.
-
-The patch allows to see kernel messages on AR934X SoCs in
-early boot stage.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3504/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/early_printk.c                 |    3 +++
- arch/mips/include/asm/mach-ath79/ar71xx_regs.h |    6 +++++-
- 2 files changed, 8 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
-index 6a51ced..dc938cb 100644
---- a/arch/mips/ath79/early_printk.c
-+++ b/arch/mips/ath79/early_printk.c
-@@ -71,6 +71,9 @@ static void prom_putchar_init(void)
- 	case REV_ID_MAJOR_AR7241:
- 	case REV_ID_MAJOR_AR7242:
- 	case REV_ID_MAJOR_AR913X:
-+	case REV_ID_MAJOR_AR9341:
-+	case REV_ID_MAJOR_AR9342:
-+	case REV_ID_MAJOR_AR9344:
- 		_prom_putchar = prom_putchar_ar71xx;
- 		break;
- 
-diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-index 2f0becb..b7df674 100644
---- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
-@@ -1,10 +1,11 @@
- /*
-  *  Atheros AR71XX/AR724X/AR913X SoC register definitions
-  *
-+ *  Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
-  *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-- *  Parts of this file are based on Atheros' 2.6.15 BSP
-+ *  Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
-  *
-  *  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
-@@ -249,6 +250,9 @@
- #define REV_ID_MAJOR_AR7242		0x1100
- #define REV_ID_MAJOR_AR9330		0x0110
- #define REV_ID_MAJOR_AR9331		0x1110
-+#define REV_ID_MAJOR_AR9341		0x0120
-+#define REV_ID_MAJOR_AR9342		0x1120
-+#define REV_ID_MAJOR_AR9344		0x2120
- 
- #define AR71XX_REV_ID_MINOR_MASK	0x3
- #define AR71XX_REV_ID_MINOR_AR7130	0x0
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch b/bsp/routerstationpro/MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch
deleted file mode 100644
index c5f4e074aa803d01e3d2c13985415cd46b94b478..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch
+++ /dev/null
@@ -1,212 +0,0 @@
-From 325a993a7a611442509543c363cc7077bae51b02 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 20:39:35 +0100
-Subject: [PATCH 063/123] MIPS: ath79: add initial support for the Atheros
- DB120 board
-
-commit 9598111f49ade848aa44f431ee81a42a000c8b3c upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3517/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Kconfig      |   12 ++++
- arch/mips/ath79/Makefile     |    1 +
- arch/mips/ath79/mach-db120.c |  134 ++++++++++++++++++++++++++++++++++++++++++
- arch/mips/ath79/machtypes.h  |    1 +
- 4 files changed, 148 insertions(+)
- create mode 100644 arch/mips/ath79/mach-db120.c
-
-diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
-index ea28e89..f44feee 100644
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -26,6 +26,18 @@ config ATH79_MACH_AP81
- 	  Say 'Y' here if you want your kernel to support the
- 	  Atheros AP81 reference board.
- 
-+config ATH79_MACH_DB120
-+	bool "Atheros DB120 reference board"
-+	select SOC_AR934X
-+	select ATH79_DEV_GPIO_BUTTONS
-+	select ATH79_DEV_LEDS_GPIO
-+	select ATH79_DEV_SPI
-+	select ATH79_DEV_USB
-+	select ATH79_DEV_WMAC
-+	help
-+	  Say 'Y' here if you want your kernel to support the
-+	  Atheros DB120 reference board.
-+
- config ATH79_MACH_PB44
- 	bool "Atheros PB44 reference board"
- 	select SOC_AR71XX
-diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
-index 221a76a..2b54d98 100644
---- a/arch/mips/ath79/Makefile
-+++ b/arch/mips/ath79/Makefile
-@@ -28,5 +28,6 @@ obj-$(CONFIG_ATH79_DEV_WMAC)		+= dev-wmac.o
- #
- obj-$(CONFIG_ATH79_MACH_AP121)		+= mach-ap121.o
- obj-$(CONFIG_ATH79_MACH_AP81)		+= mach-ap81.o
-+obj-$(CONFIG_ATH79_MACH_DB120)		+= mach-db120.o
- obj-$(CONFIG_ATH79_MACH_PB44)		+= mach-pb44.o
- obj-$(CONFIG_ATH79_MACH_UBNT_XM)	+= mach-ubnt-xm.o
-diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c
-new file mode 100644
-index 0000000..1983e4d
---- /dev/null
-+++ b/arch/mips/ath79/mach-db120.c
-@@ -0,0 +1,134 @@
-+/*
-+ * Atheros DB120 reference board support
-+ *
-+ * Copyright (c) 2011 Qualcomm Atheros
-+ * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org>
-+ *
-+ * Permission to use, copy, modify, and/or distribute this software for any
-+ * purpose with or without fee is hereby granted, provided that the above
-+ * copyright notice and this permission notice appear in all copies.
-+ *
-+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+ *
-+ */
-+
-+#include <linux/pci.h>
-+#include <linux/ath9k_platform.h>
-+
-+#include "machtypes.h"
-+#include "dev-gpio-buttons.h"
-+#include "dev-leds-gpio.h"
-+#include "dev-spi.h"
-+#include "dev-wmac.h"
-+#include "pci.h"
-+
-+#define DB120_GPIO_LED_WLAN_5G		12
-+#define DB120_GPIO_LED_WLAN_2G		13
-+#define DB120_GPIO_LED_STATUS		14
-+#define DB120_GPIO_LED_WPS		15
-+
-+#define DB120_GPIO_BTN_WPS		16
-+
-+#define DB120_KEYS_POLL_INTERVAL	20	/* msecs */
-+#define DB120_KEYS_DEBOUNCE_INTERVAL	(3 * DB120_KEYS_POLL_INTERVAL)
-+
-+#define DB120_WMAC_CALDATA_OFFSET 0x1000
-+#define DB120_PCIE_CALDATA_OFFSET 0x5000
-+
-+static struct gpio_led db120_leds_gpio[] __initdata = {
-+	{
-+		.name		= "db120:green:status",
-+		.gpio		= DB120_GPIO_LED_STATUS,
-+		.active_low	= 1,
-+	},
-+	{
-+		.name		= "db120:green:wps",
-+		.gpio		= DB120_GPIO_LED_WPS,
-+		.active_low	= 1,
-+	},
-+	{
-+		.name		= "db120:green:wlan-5g",
-+		.gpio		= DB120_GPIO_LED_WLAN_5G,
-+		.active_low	= 1,
-+	},
-+	{
-+		.name		= "db120:green:wlan-2g",
-+		.gpio		= DB120_GPIO_LED_WLAN_2G,
-+		.active_low	= 1,
-+	},
-+};
-+
-+static struct gpio_keys_button db120_gpio_keys[] __initdata = {
-+	{
-+		.desc		= "WPS button",
-+		.type		= EV_KEY,
-+		.code		= KEY_WPS_BUTTON,
-+		.debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL,
-+		.gpio		= DB120_GPIO_BTN_WPS,
-+		.active_low	= 1,
-+	},
-+};
-+
-+static struct spi_board_info db120_spi_info[] = {
-+	{
-+		.bus_num	= 0,
-+		.chip_select	= 0,
-+		.max_speed_hz	= 25000000,
-+		.modalias	= "s25sl064a",
-+	}
-+};
-+
-+static struct ath79_spi_platform_data db120_spi_data = {
-+	.bus_num	= 0,
-+	.num_chipselect	= 1,
-+};
-+
-+#ifdef CONFIG_PCI
-+static struct ath9k_platform_data db120_ath9k_data;
-+
-+static int db120_pci_plat_dev_init(struct pci_dev *dev)
-+{
-+	switch (PCI_SLOT(dev->devfn)) {
-+	case 0:
-+		dev->dev.platform_data = &db120_ath9k_data;
-+		break;
-+	}
-+
-+	return 0;
-+}
-+
-+static void __init db120_pci_init(u8 *eeprom)
-+{
-+	memcpy(db120_ath9k_data.eeprom_data, eeprom,
-+	       sizeof(db120_ath9k_data.eeprom_data));
-+
-+	ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init);
-+	ath79_register_pci();
-+}
-+#else
-+static inline void db120_pci_init(void) {}
-+#endif /* CONFIG_PCI */
-+
-+static void __init db120_setup(void)
-+{
-+	u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
-+
-+	ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
-+				 db120_leds_gpio);
-+	ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
-+					ARRAY_SIZE(db120_gpio_keys),
-+					db120_gpio_keys);
-+	ath79_register_spi(&db120_spi_data, db120_spi_info,
-+			   ARRAY_SIZE(db120_spi_info));
-+	ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
-+	db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
-+}
-+
-+MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board",
-+	     db120_setup);
-diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
-index 9a1f382..af92e5c 100644
---- a/arch/mips/ath79/machtypes.h
-+++ b/arch/mips/ath79/machtypes.h
-@@ -18,6 +18,7 @@ enum ath79_mach_type {
- 	ATH79_MACH_GENERIC = 0,
- 	ATH79_MACH_AP121,		/* Atheros AP121 reference board */
- 	ATH79_MACH_AP81,		/* Atheros AP81 reference board */
-+	ATH79_MACH_DB120,		/* Atheros DB120 reference board */
- 	ATH79_MACH_PB44,		/* Atheros PB44 reference board */
- 	ATH79_MACH_UBNT_XM,		/* Ubiquiti Networks XM board rev 1.0 */
- };
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch b/bsp/routerstationpro/MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch
deleted file mode 100644
index 2b7d54c511b84cc6eae833f2dd45c0179a6c73b8..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch
+++ /dev/null
@@ -1,452 +0,0 @@
-From c24ea8439eef5b7e0f7c74d76472e0f7025fa0a9 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:10 +0100
-Subject: [PATCH 046/123] MIPS: ath79: add support for the PCI host controller
- of the AR71XX SoCs
-
-commit f8365ec4e1b945f70a86e9514dd67ba5f9f2915b upstream.
-
-The Atheros AR71XX SoCs have a built-in PCI Host Controller.
-This patch adds a driver for that, and modifies the relevant
-files in order to allow to register the PCI controller from
-board specific setup.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3498/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Kconfig                |    1 +
- arch/mips/include/asm/mach-ath79/pci.h |    6 +
- arch/mips/pci/Makefile                 |    1 +
- arch/mips/pci/pci-ar71xx.c             |  375 ++++++++++++++++++++++++++++++++
- 4 files changed, 383 insertions(+)
- create mode 100644 arch/mips/pci/pci-ar71xx.c
-
-diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
-index e0fae8f..bc6edad 100644
---- a/arch/mips/ath79/Kconfig
-+++ b/arch/mips/ath79/Kconfig
-@@ -52,6 +52,7 @@ endmenu
- config SOC_AR71XX
- 	select USB_ARCH_HAS_EHCI
- 	select USB_ARCH_HAS_OHCI
-+	select HW_HAS_PCI
- 	def_bool n
- 
- config SOC_AR724X
-diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
-index 2eb0181..b12b087 100644
---- a/arch/mips/include/asm/mach-ath79/pci.h
-+++ b/arch/mips/include/asm/mach-ath79/pci.h
-@@ -11,6 +11,12 @@
- #ifndef __ASM_MACH_ATH79_PCI_H
- #define __ASM_MACH_ATH79_PCI_H
- 
-+#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX)
-+int ar71xx_pcibios_init(void);
-+#else
-+static inline int ar71xx_pcibios_init(void) { return 0; }
-+#endif
-+
- #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X)
- int ar724x_pcibios_init(int irq);
- #else
-diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
-index 172277c..b1c0a1c 100644
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX)		+= pci-bcm47xx.o
- obj-$(CONFIG_BCM63XX)		+= pci-bcm63xx.o fixup-bcm63xx.o \
- 					ops-bcm63xx.o
- obj-$(CONFIG_MIPS_ALCHEMY)	+= pci-alchemy.o
-+obj-$(CONFIG_SOC_AR71XX)	+= pci-ar71xx.o
- obj-$(CONFIG_SOC_AR724X)	+= pci-ar724x.o
- 
- #
-diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c
-new file mode 100644
-index 0000000..1552522
---- /dev/null
-+++ b/arch/mips/pci/pci-ar71xx.c
-@@ -0,0 +1,375 @@
-+/*
-+ *  Atheros AR71xx PCI host controller driver
-+ *
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-+ *
-+ *  Parts of this file are based on Atheros' 2.6.15 BSP
-+ *
-+ *  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/resource.h>
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+#include <linux/bitops.h>
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/mach-ath79/ar71xx_regs.h>
-+#include <asm/mach-ath79/ath79.h>
-+#include <asm/mach-ath79/pci.h>
-+
-+#define AR71XX_PCI_MEM_BASE	0x10000000
-+#define AR71XX_PCI_MEM_SIZE	0x08000000
-+
-+#define AR71XX_PCI_WIN0_OFFS		0x10000000
-+#define AR71XX_PCI_WIN1_OFFS		0x11000000
-+#define AR71XX_PCI_WIN2_OFFS		0x12000000
-+#define AR71XX_PCI_WIN3_OFFS		0x13000000
-+#define AR71XX_PCI_WIN4_OFFS		0x14000000
-+#define AR71XX_PCI_WIN5_OFFS		0x15000000
-+#define AR71XX_PCI_WIN6_OFFS		0x16000000
-+#define AR71XX_PCI_WIN7_OFFS		0x07000000
-+
-+#define AR71XX_PCI_CFG_BASE		\
-+	(AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000)
-+#define AR71XX_PCI_CFG_SIZE		0x100
-+
-+#define AR71XX_PCI_REG_CRP_AD_CBE	0x00
-+#define AR71XX_PCI_REG_CRP_WRDATA	0x04
-+#define AR71XX_PCI_REG_CRP_RDDATA	0x08
-+#define AR71XX_PCI_REG_CFG_AD		0x0c
-+#define AR71XX_PCI_REG_CFG_CBE		0x10
-+#define AR71XX_PCI_REG_CFG_WRDATA	0x14
-+#define AR71XX_PCI_REG_CFG_RDDATA	0x18
-+#define AR71XX_PCI_REG_PCI_ERR		0x1c
-+#define AR71XX_PCI_REG_PCI_ERR_ADDR	0x20
-+#define AR71XX_PCI_REG_AHB_ERR		0x24
-+#define AR71XX_PCI_REG_AHB_ERR_ADDR	0x28
-+
-+#define AR71XX_PCI_CRP_CMD_WRITE	0x00010000
-+#define AR71XX_PCI_CRP_CMD_READ		0x00000000
-+#define AR71XX_PCI_CFG_CMD_READ		0x0000000a
-+#define AR71XX_PCI_CFG_CMD_WRITE	0x0000000b
-+
-+#define AR71XX_PCI_INT_CORE		BIT(4)
-+#define AR71XX_PCI_INT_DEV2		BIT(2)
-+#define AR71XX_PCI_INT_DEV1		BIT(1)
-+#define AR71XX_PCI_INT_DEV0		BIT(0)
-+
-+#define AR71XX_PCI_IRQ_COUNT		5
-+
-+static DEFINE_SPINLOCK(ar71xx_pci_lock);
-+static void __iomem *ar71xx_pcicfg_base;
-+
-+/* Byte lane enable bits */
-+static const u8 ar71xx_pci_ble_table[4][4] = {
-+	{0x0, 0xf, 0xf, 0xf},
-+	{0xe, 0xd, 0xb, 0x7},
-+	{0xc, 0xf, 0x3, 0xf},
-+	{0xf, 0xf, 0xf, 0xf},
-+};
-+
-+static const u32 ar71xx_pci_read_mask[8] = {
-+	0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0
-+};
-+
-+static inline u32 ar71xx_pci_get_ble(int where, int size, int local)
-+{
-+	u32 t;
-+
-+	t = ar71xx_pci_ble_table[size & 3][where & 3];
-+	BUG_ON(t == 0xf);
-+	t <<= (local) ? 20 : 4;
-+
-+	return t;
-+}
-+
-+static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn,
-+				      int where)
-+{
-+	u32 ret;
-+
-+	if (!bus->number) {
-+		/* type 0 */
-+		ret = (1 << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) |
-+		      (where & ~3);
-+	} else {
-+		/* type 1 */
-+		ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) |
-+		      (PCI_FUNC(devfn) << 8) | (where & ~3) | 1;
-+	}
-+
-+	return ret;
-+}
-+
-+static int ar71xx_pci_check_error(int quiet)
-+{
-+	void __iomem *base = ar71xx_pcicfg_base;
-+	u32 pci_err;
-+	u32 ahb_err;
-+
-+	pci_err = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR) & 3;
-+	if (pci_err) {
-+		if (!quiet) {
-+			u32 addr;
-+
-+			addr = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR_ADDR);
-+			pr_crit("ar71xx: %s bus error %d at addr 0x%x\n",
-+				"PCI", pci_err, addr);
-+		}
-+
-+		/* clear PCI error status */
-+		__raw_writel(pci_err, base + AR71XX_PCI_REG_PCI_ERR);
-+	}
-+
-+	ahb_err = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR) & 1;
-+	if (ahb_err) {
-+		if (!quiet) {
-+			u32 addr;
-+
-+			addr = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR_ADDR);
-+			pr_crit("ar71xx: %s bus error %d at addr 0x%x\n",
-+				"AHB", ahb_err, addr);
-+		}
-+
-+		/* clear AHB error status */
-+		__raw_writel(ahb_err, base + AR71XX_PCI_REG_AHB_ERR);
-+	}
-+
-+	return !!(ahb_err | pci_err);
-+}
-+
-+static inline void ar71xx_pci_local_write(int where, int size, u32 value)
-+{
-+	void __iomem *base = ar71xx_pcicfg_base;
-+	u32 ad_cbe;
-+
-+	value = value << (8 * (where & 3));
-+
-+	ad_cbe = AR71XX_PCI_CRP_CMD_WRITE | (where & ~3);
-+	ad_cbe |= ar71xx_pci_get_ble(where, size, 1);
-+
-+	__raw_writel(ad_cbe, base + AR71XX_PCI_REG_CRP_AD_CBE);
-+	__raw_writel(value, base + AR71XX_PCI_REG_CRP_WRDATA);
-+}
-+
-+static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus,
-+					 unsigned int devfn,
-+					 int where, int size, u32 cmd)
-+{
-+	void __iomem *base = ar71xx_pcicfg_base;
-+	u32 addr;
-+
-+	addr = ar71xx_pci_bus_addr(bus, devfn, where);
-+
-+	__raw_writel(addr, base + AR71XX_PCI_REG_CFG_AD);
-+	__raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0),
-+		     base + AR71XX_PCI_REG_CFG_CBE);
-+
-+	return ar71xx_pci_check_error(1);
-+}
-+
-+static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
-+				  int where, int size, u32 *value)
-+{
-+	void __iomem *base = ar71xx_pcicfg_base;
-+	unsigned long flags;
-+	u32 data;
-+	int err;
-+	int ret;
-+
-+	ret = PCIBIOS_SUCCESSFUL;
-+	data = ~0;
-+
-+	spin_lock_irqsave(&ar71xx_pci_lock, flags);
-+
-+	err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
-+				     AR71XX_PCI_CFG_CMD_READ);
-+	if (err)
-+		ret = PCIBIOS_DEVICE_NOT_FOUND;
-+	else
-+		data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA);
-+
-+	spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
-+
-+	*value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7];
-+
-+	return ret;
-+}
-+
-+static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
-+				   int where, int size, u32 value)
-+{
-+	void __iomem *base = ar71xx_pcicfg_base;
-+	unsigned long flags;
-+	int err;
-+	int ret;
-+
-+	value = value << (8 * (where & 3));
-+	ret = PCIBIOS_SUCCESSFUL;
-+
-+	spin_lock_irqsave(&ar71xx_pci_lock, flags);
-+
-+	err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size,
-+				     AR71XX_PCI_CFG_CMD_WRITE);
-+	if (err)
-+		ret = PCIBIOS_DEVICE_NOT_FOUND;
-+	else
-+		__raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA);
-+
-+	spin_unlock_irqrestore(&ar71xx_pci_lock, flags);
-+
-+	return ret;
-+}
-+
-+static struct pci_ops ar71xx_pci_ops = {
-+	.read	= ar71xx_pci_read_config,
-+	.write	= ar71xx_pci_write_config,
-+};
-+
-+static struct resource ar71xx_pci_io_resource = {
-+	.name		= "PCI IO space",
-+	.start		= 0,
-+	.end		= 0,
-+	.flags		= IORESOURCE_IO,
-+};
-+
-+static struct resource ar71xx_pci_mem_resource = {
-+	.name		= "PCI memory space",
-+	.start		= AR71XX_PCI_MEM_BASE,
-+	.end		= AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1,
-+	.flags		= IORESOURCE_MEM
-+};
-+
-+static struct pci_controller ar71xx_pci_controller = {
-+	.pci_ops	= &ar71xx_pci_ops,
-+	.mem_resource	= &ar71xx_pci_mem_resource,
-+	.io_resource	= &ar71xx_pci_io_resource,
-+};
-+
-+static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc)
-+{
-+	void __iomem *base = ath79_reset_base;
-+	u32 pending;
-+
-+	pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) &
-+		  __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+
-+	if (pending & AR71XX_PCI_INT_DEV0)
-+		generic_handle_irq(ATH79_PCI_IRQ(0));
-+
-+	else if (pending & AR71XX_PCI_INT_DEV1)
-+		generic_handle_irq(ATH79_PCI_IRQ(1));
-+
-+	else if (pending & AR71XX_PCI_INT_DEV2)
-+		generic_handle_irq(ATH79_PCI_IRQ(2));
-+
-+	else if (pending & AR71XX_PCI_INT_CORE)
-+		generic_handle_irq(ATH79_PCI_IRQ(4));
-+
-+	else
-+		spurious_interrupt();
-+}
-+
-+static void ar71xx_pci_irq_unmask(struct irq_data *d)
-+{
-+	unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE;
-+	void __iomem *base = ath79_reset_base;
-+	u32 t;
-+
-+	t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+	__raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+
-+	/* flush write */
-+	__raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+}
-+
-+static void ar71xx_pci_irq_mask(struct irq_data *d)
-+{
-+	unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE;
-+	void __iomem *base = ath79_reset_base;
-+	u32 t;
-+
-+	t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+	__raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+
-+	/* flush write */
-+	__raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+}
-+
-+static struct irq_chip ar71xx_pci_irq_chip = {
-+	.name		= "AR71XX PCI",
-+	.irq_mask	= ar71xx_pci_irq_mask,
-+	.irq_unmask	= ar71xx_pci_irq_unmask,
-+	.irq_mask_ack	= ar71xx_pci_irq_mask,
-+};
-+
-+static __init void ar71xx_pci_irq_init(void)
-+{
-+	void __iomem *base = ath79_reset_base;
-+	int i;
-+
-+	__raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE);
-+	__raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS);
-+
-+	BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT);
-+
-+	for (i = ATH79_PCI_IRQ_BASE;
-+	     i < ATH79_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++)
-+		irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip,
-+					 handle_level_irq);
-+
-+	irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler);
-+}
-+
-+static __init void ar71xx_pci_reset(void)
-+{
-+	void __iomem *ddr_base = ath79_ddr_base;
-+
-+	ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
-+	mdelay(100);
-+
-+	ath79_device_reset_clear(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE);
-+	mdelay(100);
-+
-+	__raw_writel(AR71XX_PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0);
-+	__raw_writel(AR71XX_PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1);
-+	__raw_writel(AR71XX_PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2);
-+	__raw_writel(AR71XX_PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3);
-+	__raw_writel(AR71XX_PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4);
-+	__raw_writel(AR71XX_PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5);
-+	__raw_writel(AR71XX_PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6);
-+	__raw_writel(AR71XX_PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7);
-+
-+	mdelay(100);
-+}
-+
-+__init int ar71xx_pcibios_init(void)
-+{
-+	u32 t;
-+
-+	ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE);
-+	if (ar71xx_pcicfg_base == NULL)
-+		return -ENOMEM;
-+
-+	ar71xx_pci_reset();
-+
-+	/* setup COMMAND register */
-+	t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE
-+	  | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
-+	ar71xx_pci_local_write(PCI_COMMAND, 4, t);
-+
-+	/* clear bus errors */
-+	ar71xx_pci_check_error(1);
-+
-+	ar71xx_pci_irq_init();
-+
-+	register_pci_controller(&ar71xx_pci_controller);
-+
-+	return 0;
-+}
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch b/bsp/routerstationpro/MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch
deleted file mode 100644
index 07c595685c94f2bc885d2fa122514156dd60f56a..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From b68f1f900f397be079c2d6c3c0b42595d7b2c8c5 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:11 +0100
-Subject: [PATCH 047/123] MIPS: ath79: allow to use SoC specific PCI IRQ maps
-
-commit d22ce25f870dff2521d352e20d0fd2a7598fbf87 upstream.
-
-The PCI controllers in the AR71XX and in the
-AR724X SoCs are different, and both of them
-uses different IRQ wiring.
-
-The patch modifies the 'pcibios_map_irq' function
-in order to allow to use different IRQ maps for
-the different SoCs. The patch also adds a function,
-which lets the board setup code to override the
-default IRQ map.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3500/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/pci.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++---
- arch/mips/ath79/pci.h |    9 +++++++
- 2 files changed, 77 insertions(+), 4 deletions(-)
-
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 2b4c730..365a8b6 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -8,6 +8,7 @@
-  *  by the Free Software Foundation.
-  */
- 
-+#include <linux/init.h>
- #include <linux/pci.h>
- #include <asm/mach-ath79/ath79.h>
- #include <asm/mach-ath79/irq.h>
-@@ -15,9 +16,35 @@
- #include "pci.h"
- 
- static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
-+static const struct ath79_pci_irq *ath79_pci_irq_map __initdata;
-+static unsigned ath79_pci_nr_irqs __initdata;
- static struct ar724x_pci_data *pci_data;
- static int pci_data_size;
- 
-+static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = {
-+	{
-+		.slot	= 17,
-+		.pin	= 1,
-+		.irq	= ATH79_PCI_IRQ(0),
-+	}, {
-+		.slot	= 18,
-+		.pin	= 1,
-+		.irq	= ATH79_PCI_IRQ(1),
-+	}, {
-+		.slot	= 19,
-+		.pin	= 1,
-+		.irq	= ATH79_PCI_IRQ(2),
-+	}
-+};
-+
-+static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = {
-+	{
-+		.slot	= 0,
-+		.pin	= 1,
-+		.irq	= ATH79_PCI_IRQ(0),
-+	}
-+};
-+
- void ar724x_pci_add_data(struct ar724x_pci_data *data, int size)
- {
- 	pci_data	= data;
-@@ -26,13 +53,40 @@ void ar724x_pci_add_data(struct ar724x_pci_data *data, int size)
- 
- int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
- {
--	unsigned int devfn = dev->devfn;
- 	int irq = -1;
-+	int i;
-+
-+	if (ath79_pci_nr_irqs == 0 ||
-+	    ath79_pci_irq_map == NULL) {
-+		if (soc_is_ar71xx()) {
-+			ath79_pci_irq_map = ar71xx_pci_irq_map;
-+			ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map);
-+		} else if (soc_is_ar724x()) {
-+			ath79_pci_irq_map = ar724x_pci_irq_map;
-+			ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map);
-+		} else {
-+			pr_crit("pci %s: invalid irq map\n",
-+				pci_name((struct pci_dev *) dev));
-+			return irq;
-+		}
-+	}
-+
-+	for (i = 0; i < ath79_pci_nr_irqs; i++) {
-+		const struct ath79_pci_irq *entry;
- 
--	if (devfn > pci_data_size - 1)
--		return irq;
-+		entry = &ath79_pci_irq_map[i];
-+		if (entry->slot == slot && entry->pin == pin) {
-+			irq = entry->irq;
-+			break;
-+		}
-+	}
- 
--	irq = pci_data[devfn].irq;
-+	if (irq < 0)
-+		pr_crit("pci %s: no irq found for pin %u\n",
-+			pci_name((struct pci_dev *) dev), pin);
-+	else
-+		pr_info("pci %s: using irq %d for pin %u\n",
-+			pci_name((struct pci_dev *) dev), irq, pin);
- 
- 	return irq;
- }
-@@ -45,6 +99,13 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
- 	return 0;
- }
- 
-+void __init ath79_pci_set_irq_map(unsigned nr_irqs,
-+				  const struct ath79_pci_irq *map)
-+{
-+	ath79_pci_nr_irqs = nr_irqs;
-+	ath79_pci_irq_map = map;
-+}
-+
- void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
- {
- 	ath79_pci_plat_dev_init = func;
-@@ -52,6 +113,9 @@ void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
- 
- int __init ath79_register_pci(void)
- {
-+	if (soc_is_ar71xx())
-+		return ar71xx_pcibios_init();
-+
- 	if (soc_is_ar724x())
- 		return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2);
- 
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-index de30e15..a5c4e58 100644
---- a/arch/mips/ath79/pci.h
-+++ b/arch/mips/ath79/pci.h
-@@ -15,13 +15,22 @@ struct ar724x_pci_data {
- 	int irq;
- };
- 
-+struct ath79_pci_irq {
-+	u8	slot;
-+	u8	pin;
-+	int	irq;
-+};
-+
- void ar724x_pci_add_data(struct ar724x_pci_data *data, int size);
- 
- #ifdef CONFIG_PCI
-+void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
- void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
- int ath79_register_pci(void);
- #else
- static inline void
-+ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {}
-+static inline void
- ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
- static inline int ath79_register_pci(void) { return 0; }
- #endif
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch b/bsp/routerstationpro/MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch
deleted file mode 100644
index dee885cdbb5ab4584dc7136c561147e905c0aa15..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch
+++ /dev/null
@@ -1,154 +0,0 @@
-From 9b85ac356af33b18d70fc7417e94178b77a744cb Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:09 +0100
-Subject: [PATCH 045/123] MIPS: ath79: allow to use board specific
- pci_plat_dev_init functions
-
-commit f8365ec4e1b945f70a86e9514dd67ba5f9f2915b upstream.
-
-Th current implementation causes NULL pointer dereference
-if 'pci_data' is not set:
-
-pci 0000:00:00.0: BAR 0: assigned [mem 0x10000000-0x1000ffff 64bit]
-pci 0000:00:00.0: BAR 0: set to [mem 0x10000000-0x1000ffff 64bit] (PCI
-address [0x10000000-0x1000ffff])
-CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 802daca0, ra == 802e78a4
-Oops[#1]:
-Cpu 0
-$ 0   : 00000000 80420000 00000000 00000000
-$ 4   : 00000000 00000000 00000001 00000001
-$ 8   : 00000001 0000032c 81c54700 00000001
-$12   : 0000032d 0000000f 00000000 ffffffff
-$16   : 81c14c00 00000001 802dac74 80195f98
-$20   : 802ea050 00000000 00000000 00000000
-$24   : 00000003 800617f0
-$28   : 81c20000 81c21e70 00000000 802e78a4
-Hi    : 00000000
-Lo    : 4190ab00
-epc   : 802daca0 0x802daca0
-    Not tainted
-ra    : 802e78a4 0x802e78a4
-Status: 1000c003    KERNEL EXL IE
-Cause : 00800008
-BadVA : 00000000
-PrId  : 00019374 (MIPS 24Kc)
-Modules linked in:
-Process swapper (pid: 1, threadinfo=81c20000, task=81c18000, tls=00000000)
-Stack : 00000000 8027d5d8 802e8ae0 00000000 01000000 802e8b5c 81c50600 00000000
-        802ff290 00000000 80420000 802ea0bc 00000000 00000000 80420000 802ff290
-        80420000 80060930 33390000 00000000 00002308 80140a80 00000028 802d0000
-        00000000 800ba024 802ff004 802ff0c8 802ff290 00000000 00000000 00000000
-        00000000 802d897c 01234567 7f827068 00000000 0045f798 00460000 00000000
-
-This can be avoided by calling the 'ar724x_pci_add_data'
-function from the board specific setup code. However it
-makes no sense to use that function for every board,
-especially when the board does not needs to set the
-platform_data field of any PCI device.
-
-The patch allows the board setup code to specify a board
-specific function if that is required.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3499/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c |   13 ++++++++++++-
- arch/mips/ath79/pci.c          |   14 ++++++++------
- arch/mips/ath79/pci.h          |    4 +++-
- 3 files changed, 23 insertions(+), 8 deletions(-)
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index 1e6b986..ca47ba5 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -85,16 +85,27 @@ static struct ath9k_platform_data ubnt_xm_eeprom_data;
- static struct ar724x_pci_data ubnt_xm_pci_data[] = {
- 	{
- 		.irq	= ATH79_PCI_IRQ(0),
--		.pdata	= &ubnt_xm_eeprom_data,
- 	},
- };
- 
-+static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
-+{
-+	switch (PCI_SLOT(dev->devfn)) {
-+	case 0:
-+		dev->dev.platform_data = &ubnt_xm_eeprom_data;
-+		break;
-+	}
-+
-+	return 0;
-+}
-+
- static void __init ubnt_xm_pci_init(void)
- {
- 	memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
- 	       sizeof(ubnt_xm_eeprom_data.eeprom_data));
- 
- 	ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
-+	ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
- 	ath79_register_pci();
- }
- #else
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 14f981c2..2b4c730 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -14,6 +14,7 @@
- #include <asm/mach-ath79/pci.h>
- #include "pci.h"
- 
-+static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
- static struct ar724x_pci_data *pci_data;
- static int pci_data_size;
- 
-@@ -38,14 +39,15 @@ int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
- 
- int pcibios_plat_dev_init(struct pci_dev *dev)
- {
--	unsigned int devfn = dev->devfn;
--
--	if (devfn > pci_data_size - 1)
--		return PCIBIOS_DEVICE_NOT_FOUND;
-+	if (ath79_pci_plat_dev_init)
-+		return ath79_pci_plat_dev_init(dev);
- 
--	dev->dev.platform_data = pci_data[devfn].pdata;
-+	return 0;
-+}
- 
--	return PCIBIOS_SUCCESSFUL;
-+void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
-+{
-+	ath79_pci_plat_dev_init = func;
- }
- 
- int __init ath79_register_pci(void)
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-index e0601c4..de30e15 100644
---- a/arch/mips/ath79/pci.h
-+++ b/arch/mips/ath79/pci.h
-@@ -13,14 +13,16 @@
- 
- struct ar724x_pci_data {
- 	int irq;
--	void *pdata;
- };
- 
- void ar724x_pci_add_data(struct ar724x_pci_data *data, int size);
- 
- #ifdef CONFIG_PCI
-+void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
- int ath79_register_pci(void);
- #else
-+static inline void
-+ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
- static inline int ath79_register_pci(void) { return 0; }
- #endif
- 
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-fix-a-wrong-IRQ-number.patch b/bsp/routerstationpro/MIPS-ath79-fix-a-wrong-IRQ-number.patch
deleted file mode 100644
index e6e9b64518c26a3f6f5e3c7fecc443c5b56086b0..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-fix-a-wrong-IRQ-number.patch
+++ /dev/null
@@ -1,83 +0,0 @@
-From 17f083f3d3500e02010b9168ed842936a70c9ad9 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:06 +0100
-Subject: [PATCH 042/123] MIPS: ath79: fix a wrong IRQ number
-
-commit 93ef85b5598ad2cc23f38d97ed565027b969c0aa upstream
-
-The Ubiquiti XM board setup code uses an invalid
-IRQ number, because it if above of NR_IRQS. This
-leads to failed 'request_irq' calls:
-
-  ath9k 0000:00:00.0: request_irq failed
-  ath9k: probe of 0000:00:00.0 failed with error -22
-
-Preserve some IRQ numbers for the built-in IRQ
-controller of PCI host controllers in the
-AR71XX/AR724X SoCs, and use the correct IRQ
-number in the board setup code.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3495/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c         |    5 +++--
- arch/mips/include/asm/mach-ath79/irq.h |    6 +++++-
- 2 files changed, 8 insertions(+), 3 deletions(-)
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index 3266ee0..0d95b67 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -17,6 +17,8 @@
- #include <linux/ath9k_platform.h>
- #endif /* CONFIG_PCI */
- 
-+#include <asm/mach-ath79/irq.h>
-+
- #include "machtypes.h"
- #include "dev-gpio-buttons.h"
- #include "dev-leds-gpio.h"
-@@ -33,7 +35,6 @@
- #define UBNT_XM_KEYS_POLL_INTERVAL	20
- #define UBNT_XM_KEYS_DEBOUNCE_INTERVAL	(3 * UBNT_XM_KEYS_POLL_INTERVAL)
- 
--#define UBNT_XM_PCI_IRQ			48
- #define UBNT_XM_EEPROM_ADDR		(u8 *) KSEG1ADDR(0x1fff1000)
- 
- static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
-@@ -86,7 +87,7 @@ static struct ath9k_platform_data ubnt_xm_eeprom_data;
- 
- static struct ar724x_pci_data ubnt_xm_pci_data[] = {
- 	{
--		.irq	= UBNT_XM_PCI_IRQ,
-+		.irq	= ATH79_PCI_IRQ(0),
- 		.pdata	= &ubnt_xm_eeprom_data,
- 	},
- };
-diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
-index 519958f..6ae2646 100644
---- a/arch/mips/include/asm/mach-ath79/irq.h
-+++ b/arch/mips/include/asm/mach-ath79/irq.h
-@@ -10,11 +10,15 @@
- #define __ASM_MACH_ATH79_IRQ_H
- 
- #define MIPS_CPU_IRQ_BASE	0
--#define NR_IRQS			40
-+#define NR_IRQS			46
- 
- #define ATH79_MISC_IRQ_BASE	8
- #define ATH79_MISC_IRQ_COUNT	32
- 
-+#define ATH79_PCI_IRQ_BASE	(ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT)
-+#define ATH79_PCI_IRQ_COUNT	6
-+#define ATH79_PCI_IRQ(_x)	(ATH79_PCI_IRQ_BASE + (_x))
-+
- #define ATH79_CPU_IRQ_IP2	(MIPS_CPU_IRQ_BASE + 2)
- #define ATH79_CPU_IRQ_USB	(MIPS_CPU_IRQ_BASE + 3)
- #define ATH79_CPU_IRQ_GE0	(MIPS_CPU_IRQ_BASE + 4)
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch b/bsp/routerstationpro/MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch
deleted file mode 100644
index cbe9da22354d2dd5f26521f49fbbc0b5f000a729..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch
+++ /dev/null
@@ -1,143 +0,0 @@
-From 73aeacbca50ec49cdc3581eb43731763fc82b7e1 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:04 +0100
-Subject: [PATCH 040/123] MIPS: ath79: fix broken ar724x_pci_{read,write}
- functions
-
-commit 64adb6bb62bee11ad04c2f9c3c797799e329c351 upstream.
-
-The current ar724x_pci_{read,write} functions are
-broken. Due to that, pci_read_config_byte returns
-with bogus values, and pci_write_config_{byte,word}
-unconditionally clears the accessed PCI configuration
-registers instead of changing the value of them.
-
-The patch fixes the broken functions, thus the PCI
-configuration space can be accessed correctly.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3493/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/pci/pci-ar724x.c |   52 ++++++++++++++++++++++----------------------
- 1 file changed, 26 insertions(+), 26 deletions(-)
-
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index 342bf4a..bb4f216 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -22,8 +22,9 @@ static void __iomem *ar724x_pci_devcfg_base;
- static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 			    int size, uint32_t *value)
- {
--	unsigned long flags, addr, tval, mask;
-+	unsigned long flags;
- 	void __iomem *base;
-+	u32 data;
- 
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
-@@ -31,24 +32,22 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 	base = ar724x_pci_devcfg_base;
- 
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
-+	data = __raw_readl(base + (where & ~3));
- 
- 	switch (size) {
- 	case 1:
--		addr = where & ~3;
--		mask = 0xff000000 >> ((where % 4) * 8);
--		tval = __raw_readl(base + addr);
--		tval = tval & ~mask;
--		*value = (tval >> ((4 - (where % 4))*8));
-+		if (where & 1)
-+			data >>= 8;
-+		if (where & 2)
-+			data >>= 16;
-+		data &= 0xff;
- 		break;
- 	case 2:
--		addr = where & ~3;
--		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = __raw_readl(base + addr);
--		tval = tval & ~mask;
--		*value = (tval >> ((4 - (where % 4))*8));
-+		if (where & 2)
-+			data >>= 16;
-+		data &= 0xffff;
- 		break;
- 	case 4:
--		*value = __raw_readl(base + where);
- 		break;
- 	default:
- 		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
-@@ -57,6 +56,7 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 	}
- 
- 	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
-+	*value = data;
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
-@@ -64,8 +64,10 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 			     int size, uint32_t value)
- {
--	unsigned long flags, tval, addr, mask;
-+	unsigned long flags;
- 	void __iomem *base;
-+	u32 data;
-+	int s;
- 
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
-@@ -73,26 +75,21 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 	base = ar724x_pci_devcfg_base;
- 
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
-+	data = __raw_readl(base + (where & ~3));
- 
- 	switch (size) {
- 	case 1:
--		addr = where & ~3;
--		mask = 0xff000000 >> ((where % 4)*8);
--		tval = __raw_readl(base + addr);
--		tval = tval & ~mask;
--		tval |= (value << ((4 - (where % 4))*8)) & mask;
--		__raw_writel(tval, base + addr);
-+		s = ((where & 3) * 8);
-+		data &= ~(0xff << s);
-+		data |= ((value & 0xff) << s);
- 		break;
- 	case 2:
--		addr = where & ~3;
--		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = __raw_readl(base + addr);
--		tval = tval & ~mask;
--		tval |= (value << ((4 - (where % 4))*8)) & mask;
--		__raw_writel(tval, base + addr);
-+		s = ((where & 2) * 8);
-+		data &= ~(0xffff << s);
-+		data |= ((value & 0xffff) << s);
- 		break;
- 	case 4:
--		__raw_writel(value, (base + where));
-+		data = value;
- 		break;
- 	default:
- 		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
-@@ -100,6 +97,9 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 	}
- 
-+	__raw_writel(data, base + (where & ~3));
-+	/* flush write */
-+	__raw_readl(base + (where & ~3));
- 	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
- 
- 	return PCIBIOS_SUCCESSFUL;
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch b/bsp/routerstationpro/MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch
deleted file mode 100644
index 42f99b0351b4f3e0fa496b63adb8ba9285fc4cc4..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 0916c892f3d85ad70f4b11bfd2de2f60392b8cbb Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:08 +0100
-Subject: [PATCH 044/123] MIPS: ath79: get rid of some ifdefs in
- mach-ubnt-xm.c
-
-commit 881b6ef0cca3395ac0171472a1ce768fede7535b upstream
-
-Remove a superfluous ifdef around an include. Also
-reorganize the board setup code a bit, so another
-ifdef can be removed.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3497/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c |   23 ++++++++++++-----------
- 1 file changed, 12 insertions(+), 11 deletions(-)
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index 0d95b67..1e6b986 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -12,10 +12,7 @@
- 
- #include <linux/init.h>
- #include <linux/pci.h>
--
--#ifdef CONFIG_PCI
- #include <linux/ath9k_platform.h>
--#endif /* CONFIG_PCI */
- 
- #include <asm/mach-ath79/irq.h>
- 
-@@ -91,6 +88,17 @@ static struct ar724x_pci_data ubnt_xm_pci_data[] = {
- 		.pdata	= &ubnt_xm_eeprom_data,
- 	},
- };
-+
-+static void __init ubnt_xm_pci_init(void)
-+{
-+	memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
-+	       sizeof(ubnt_xm_eeprom_data.eeprom_data));
-+
-+	ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
-+	ath79_register_pci();
-+}
-+#else
-+static inline void ubnt_xm_pci_init(void) {}
- #endif /* CONFIG_PCI */
- 
- static void __init ubnt_xm_init(void)
-@@ -105,14 +113,7 @@ static void __init ubnt_xm_init(void)
- 	ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
- 			   ARRAY_SIZE(ubnt_xm_spi_info));
- 
--#ifdef CONFIG_PCI
--	memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
--	       sizeof(ubnt_xm_eeprom_data.eeprom_data));
--
--	ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
--#endif /* CONFIG_PCI */
--
--	ath79_register_pci();
-+	ubnt_xm_pci_init();
- }
- 
- MIPS_MACHINE(ATH79_MACH_UBNT_XM,
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch b/bsp/routerstationpro/MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch
deleted file mode 100644
index 8af42f47b85ebc9843b39358b54447b46f827d65..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 5e82fcc92b5b4e6386e429cce08e1e1c04c80d9a Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:23 +0100
-Subject: [PATCH 034/123] MIPS: ath79: make ath724x_pcibios_init visible for
- external code
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-commit 659243ccaf296ae122c159d4c573f93561e1b8d6 upstream
-
-Signed-off-by: René Bolldorf <xsecute@googlemail.com>
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3487/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/include/asm/mach-ath79/pci.h |   20 ++++++++++++++++++++
- arch/mips/pci/pci-ath724x.c            |    3 ++-
- 2 files changed, 22 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-ath79/pci.h
-
-diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
-new file mode 100644
-index 0000000..e0c4b53
---- /dev/null
-+++ b/arch/mips/include/asm/mach-ath79/pci.h
-@@ -0,0 +1,20 @@
-+/*
-+ *  Atheros 724x PCI support
-+ *
-+ *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.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.
-+ */
-+
-+#ifndef __ASM_MACH_ATH79_PCI_H
-+#define __ASM_MACH_ATH79_PCI_H
-+
-+#if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X)
-+int ath724x_pcibios_init(void);
-+#else
-+static inline int ath724x_pcibios_init(void) { return 0; }
-+#endif
-+
-+#endif /* __ASM_MACH_ATH79_PCI_H */
-diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c
-index 1e810be..be01b7f 100644
---- a/arch/mips/pci/pci-ath724x.c
-+++ b/arch/mips/pci/pci-ath724x.c
-@@ -9,6 +9,7 @@
-  */
- 
- #include <linux/pci.h>
-+#include <asm/mach-ath79/pci.h>
- 
- #define reg_read(_phys)		(*(unsigned int *) KSEG1ADDR(_phys))
- #define reg_write(_phys, _val)	((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
-@@ -130,7 +131,7 @@ static struct pci_controller ath724x_pci_controller = {
- 	.mem_resource	= &ath724x_mem_resource,
- };
- 
--static int __init ath724x_pcibios_init(void)
-+int __init ath724x_pcibios_init(void)
- {
- 	register_pci_controller(&ath724x_pci_controller);
- 
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch b/bsp/routerstationpro/MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch
deleted file mode 100644
index db5e11befbcd392ef719144911036a777a5a670c..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 4a98ff40ecc3899a537cc6cf5ac356abb90ed0c7 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:13 +0100
-Subject: [PATCH 049/123] MIPS: ath79: register PCI controller on the PB44
- board
-
-commit 1f3a92de2a5081077799a51f39b1010ed0492264 upstream.
-
-The PB44 reference board has two miniPCI slots. Register
-the PCI controller to make those usable.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3502/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-pb44.c |    2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
-index fe9701a..c5f0ea5 100644
---- a/arch/mips/ath79/mach-pb44.c
-+++ b/arch/mips/ath79/mach-pb44.c
-@@ -19,6 +19,7 @@
- #include "dev-leds-gpio.h"
- #include "dev-spi.h"
- #include "dev-usb.h"
-+#include "pci.h"
- 
- #define PB44_GPIO_I2C_SCL	0
- #define PB44_GPIO_I2C_SDA	1
-@@ -114,6 +115,7 @@ static void __init pb44_init(void)
- 	ath79_register_spi(&pb44_spi_data, pb44_spi_info,
- 			   ARRAY_SIZE(pb44_spi_info));
- 	ath79_register_usb();
-+	ath79_register_pci();
- }
- 
- MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch b/bsp/routerstationpro/MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch
deleted file mode 100644
index e2302dd452c9093cbe2e2dda7478094d72cb0376..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From 0a6aac16cbc02c0f8c6ce6504e87d43718a39909 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:27 +0100
-Subject: [PATCH 059/123] MIPS: ath79: register UART device for AR934X SoCs
-
-commit 9800bdc797b12835e1e36ebe8b82874c606bc11d upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3512/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/dev-common.c |    3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
-index f4956f8..45efc63 100644
---- a/arch/mips/ath79/dev-common.c
-+++ b/arch/mips/ath79/dev-common.c
-@@ -89,7 +89,8 @@ void __init ath79_register_uart(void)
- 
- 	if (soc_is_ar71xx() ||
- 	    soc_is_ar724x() ||
--	    soc_is_ar913x()) {
-+	    soc_is_ar913x() ||
-+	    soc_is_ar934x()) {
- 		ath79_uart_data[0].uartclk = clk_get_rate(clk);
- 		platform_device_register(&ath79_uart_device);
- 	} else if (soc_is_ar933x()) {
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-remove-ar724x_pci_add_data-function.patch b/bsp/routerstationpro/MIPS-ath79-remove-ar724x_pci_add_data-function.patch
deleted file mode 100644
index 9035a061af09c84eac86478e1868f30e3dba9a37..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-remove-ar724x_pci_add_data-function.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From 95d7f2ee27ea6170fc307f857f11daab39ca7b3e Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:12 +0100
-Subject: [PATCH 048/123] MIPS: ath79: remove ar724x_pci_add_data function
-
-commit 52c28be371e33b99700811dbed009913b854c44d upstream.
-
-The variables set by this function are not used anymore.
-Remove the function and the relevant variables as well.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3501/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c |    7 -------
- arch/mips/ath79/pci.c          |    8 --------
- arch/mips/ath79/pci.h          |    6 ------
- 3 files changed, 21 deletions(-)
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index ca47ba5..4a3c606 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -82,12 +82,6 @@ static struct ath79_spi_platform_data ubnt_xm_spi_data = {
- #ifdef CONFIG_PCI
- static struct ath9k_platform_data ubnt_xm_eeprom_data;
- 
--static struct ar724x_pci_data ubnt_xm_pci_data[] = {
--	{
--		.irq	= ATH79_PCI_IRQ(0),
--	},
--};
--
- static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
- {
- 	switch (PCI_SLOT(dev->devfn)) {
-@@ -104,7 +98,6 @@ static void __init ubnt_xm_pci_init(void)
- 	memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
- 	       sizeof(ubnt_xm_eeprom_data.eeprom_data));
- 
--	ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
- 	ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
- 	ath79_register_pci();
- }
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 365a8b6..253a382 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -18,8 +18,6 @@
- static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
- static const struct ath79_pci_irq *ath79_pci_irq_map __initdata;
- static unsigned ath79_pci_nr_irqs __initdata;
--static struct ar724x_pci_data *pci_data;
--static int pci_data_size;
- 
- static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = {
- 	{
-@@ -45,12 +43,6 @@ static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = {
- 	}
- };
- 
--void ar724x_pci_add_data(struct ar724x_pci_data *data, int size)
--{
--	pci_data	= data;
--	pci_data_size	= size;
--}
--
- int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
- {
- 	int irq = -1;
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-index a5c4e58..5ebed21 100644
---- a/arch/mips/ath79/pci.h
-+++ b/arch/mips/ath79/pci.h
-@@ -11,18 +11,12 @@
- #ifndef _ATH79_PCI_H
- #define _ATH79_PCI_H
- 
--struct ar724x_pci_data {
--	int irq;
--};
--
- struct ath79_pci_irq {
- 	u8	slot;
- 	u8	pin;
- 	int	irq;
- };
- 
--void ar724x_pci_add_data(struct ar724x_pci_data *data, int size);
--
- #ifdef CONFIG_PCI
- void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
- void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-remove-superfluous-alignment-checks-from-.patch b/bsp/routerstationpro/MIPS-ath79-remove-superfluous-alignment-checks-from-.patch
deleted file mode 100644
index 2a9f0ef628bbd0dc765ab0ca9482d5acb721a0ae..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-remove-superfluous-alignment-checks-from-.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From 7218e77665e26bb90d733b30766554b7519a94c8 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:03 +0100
-Subject: [PATCH 039/123] MIPS: ath79: remove superfluous alignment checks
- from pci-ar724x.c
-
-commit ffdce4668234a113e767edd27aa1331903959106 upstream.
-
-The alignment of the 'where' parameters are checked
-in the core PCI code already.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3492/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/pci/pci-ar724x.c |    6 ------
- 1 file changed, 6 deletions(-)
-
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index 22f5e5b..342bf4a 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -28,9 +28,6 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
- 
--	if (where & (size - 1))
--		return PCIBIOS_BAD_REGISTER_NUMBER;
--
- 	base = ar724x_pci_devcfg_base;
- 
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
-@@ -73,9 +70,6 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
- 
--	if (where & (size - 1))
--		return PCIBIOS_BAD_REGISTER_NUMBER;
--
- 	base = ar724x_pci_devcfg_base;
- 
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch b/bsp/routerstationpro/MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch
deleted file mode 100644
index 5599ebd129173f80a2e6e7bc06ca247c109cc4b6..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch
+++ /dev/null
@@ -1,331 +0,0 @@
-From 1e1dbfcfa5315bf21f08c9d712f6ccf9feb0078b Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:25 +0100
-Subject: [PATCH 036/123] MIPS: ath79: rename pci-ath724x.c to make it reflect
- the real SoC name
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-commit 692183ef12c4ba9dcdc9a54065ca92072cd79493 upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: René Bolldorf <xsecute@googlemail.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3489/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/pci/Makefile      |    2 +-
- arch/mips/pci/pci-ar724x.c  |  139 +++++++++++++++++++++++++++++++++++++++++++
- arch/mips/pci/pci-ath724x.c |  139 -------------------------------------------
- 3 files changed, 140 insertions(+), 140 deletions(-)
- create mode 100644 arch/mips/pci/pci-ar724x.c
- delete mode 100644 arch/mips/pci/pci-ath724x.c
-
-diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
-index c3ac4b0..172277c 100644
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -19,7 +19,7 @@ obj-$(CONFIG_BCM47XX)		+= pci-bcm47xx.o
- obj-$(CONFIG_BCM63XX)		+= pci-bcm63xx.o fixup-bcm63xx.o \
- 					ops-bcm63xx.o
- obj-$(CONFIG_MIPS_ALCHEMY)	+= pci-alchemy.o
--obj-$(CONFIG_SOC_AR724X)	+= pci-ath724x.o
-+obj-$(CONFIG_SOC_AR724X)	+= pci-ar724x.o
- 
- #
- # These are still pretty much in the old state, watch, go blind.
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-new file mode 100644
-index 0000000..ebefc16
---- /dev/null
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -0,0 +1,139 @@
-+/*
-+ *  Atheros 724x PCI support
-+ *
-+ *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.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/pci.h>
-+#include <asm/mach-ath79/pci.h>
-+
-+#define reg_read(_phys)		(*(unsigned int *) KSEG1ADDR(_phys))
-+#define reg_write(_phys, _val)	((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
-+
-+#define ATH724X_PCI_DEV_BASE	0x14000000
-+#define ATH724X_PCI_MEM_BASE	0x10000000
-+#define ATH724X_PCI_MEM_SIZE	0x08000000
-+
-+static DEFINE_SPINLOCK(ath724x_pci_lock);
-+
-+static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
-+			    int size, uint32_t *value)
-+{
-+	unsigned long flags, addr, tval, mask;
-+
-+	if (devfn)
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+
-+	if (where & (size - 1))
-+		return PCIBIOS_BAD_REGISTER_NUMBER;
-+
-+	spin_lock_irqsave(&ath724x_pci_lock, flags);
-+
-+	switch (size) {
-+	case 1:
-+		addr = where & ~3;
-+		mask = 0xff000000 >> ((where % 4) * 8);
-+		tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
-+		tval = tval & ~mask;
-+		*value = (tval >> ((4 - (where % 4))*8));
-+		break;
-+	case 2:
-+		addr = where & ~3;
-+		mask = 0xffff0000 >> ((where % 4)*8);
-+		tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
-+		tval = tval & ~mask;
-+		*value = (tval >> ((4 - (where % 4))*8));
-+		break;
-+	case 4:
-+		*value = reg_read(ATH724X_PCI_DEV_BASE + where);
-+		break;
-+	default:
-+		spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+
-+		return PCIBIOS_BAD_REGISTER_NUMBER;
-+	}
-+
-+	spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+
-+	return PCIBIOS_SUCCESSFUL;
-+}
-+
-+static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
-+			     int size, uint32_t value)
-+{
-+	unsigned long flags, tval, addr, mask;
-+
-+	if (devfn)
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+
-+	if (where & (size - 1))
-+		return PCIBIOS_BAD_REGISTER_NUMBER;
-+
-+	spin_lock_irqsave(&ath724x_pci_lock, flags);
-+
-+	switch (size) {
-+	case 1:
-+		addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
-+		mask = 0xff000000 >> ((where % 4)*8);
-+		tval = reg_read(addr);
-+		tval = tval & ~mask;
-+		tval |= (value << ((4 - (where % 4))*8)) & mask;
-+		reg_write(addr, tval);
-+		break;
-+	case 2:
-+		addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
-+		mask = 0xffff0000 >> ((where % 4)*8);
-+		tval = reg_read(addr);
-+		tval = tval & ~mask;
-+		tval |= (value << ((4 - (where % 4))*8)) & mask;
-+		reg_write(addr, tval);
-+		break;
-+	case 4:
-+		reg_write((ATH724X_PCI_DEV_BASE + where), value);
-+		break;
-+	default:
-+		spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+
-+		return PCIBIOS_BAD_REGISTER_NUMBER;
-+	}
-+
-+	spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+
-+	return PCIBIOS_SUCCESSFUL;
-+}
-+
-+static struct pci_ops ath724x_pci_ops = {
-+	.read	= ath724x_pci_read,
-+	.write	= ath724x_pci_write,
-+};
-+
-+static struct resource ath724x_io_resource = {
-+	.name   = "PCI IO space",
-+	.start  = 0,
-+	.end    = 0,
-+	.flags  = IORESOURCE_IO,
-+};
-+
-+static struct resource ath724x_mem_resource = {
-+	.name   = "PCI memory space",
-+	.start  = ATH724X_PCI_MEM_BASE,
-+	.end    = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1,
-+	.flags  = IORESOURCE_MEM,
-+};
-+
-+static struct pci_controller ath724x_pci_controller = {
-+	.pci_ops        = &ath724x_pci_ops,
-+	.io_resource    = &ath724x_io_resource,
-+	.mem_resource	= &ath724x_mem_resource,
-+};
-+
-+int __init ath724x_pcibios_init(void)
-+{
-+	register_pci_controller(&ath724x_pci_controller);
-+
-+	return PCIBIOS_SUCCESSFUL;
-+}
-diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c
-deleted file mode 100644
-index ebefc16..0000000
---- a/arch/mips/pci/pci-ath724x.c
-+++ /dev/null
-@@ -1,139 +0,0 @@
--/*
-- *  Atheros 724x PCI support
-- *
-- *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.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/pci.h>
--#include <asm/mach-ath79/pci.h>
--
--#define reg_read(_phys)		(*(unsigned int *) KSEG1ADDR(_phys))
--#define reg_write(_phys, _val)	((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
--
--#define ATH724X_PCI_DEV_BASE	0x14000000
--#define ATH724X_PCI_MEM_BASE	0x10000000
--#define ATH724X_PCI_MEM_SIZE	0x08000000
--
--static DEFINE_SPINLOCK(ath724x_pci_lock);
--
--static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
--			    int size, uint32_t *value)
--{
--	unsigned long flags, addr, tval, mask;
--
--	if (devfn)
--		return PCIBIOS_DEVICE_NOT_FOUND;
--
--	if (where & (size - 1))
--		return PCIBIOS_BAD_REGISTER_NUMBER;
--
--	spin_lock_irqsave(&ath724x_pci_lock, flags);
--
--	switch (size) {
--	case 1:
--		addr = where & ~3;
--		mask = 0xff000000 >> ((where % 4) * 8);
--		tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
--		tval = tval & ~mask;
--		*value = (tval >> ((4 - (where % 4))*8));
--		break;
--	case 2:
--		addr = where & ~3;
--		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
--		tval = tval & ~mask;
--		*value = (tval >> ((4 - (where % 4))*8));
--		break;
--	case 4:
--		*value = reg_read(ATH724X_PCI_DEV_BASE + where);
--		break;
--	default:
--		spin_unlock_irqrestore(&ath724x_pci_lock, flags);
--
--		return PCIBIOS_BAD_REGISTER_NUMBER;
--	}
--
--	spin_unlock_irqrestore(&ath724x_pci_lock, flags);
--
--	return PCIBIOS_SUCCESSFUL;
--}
--
--static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
--			     int size, uint32_t value)
--{
--	unsigned long flags, tval, addr, mask;
--
--	if (devfn)
--		return PCIBIOS_DEVICE_NOT_FOUND;
--
--	if (where & (size - 1))
--		return PCIBIOS_BAD_REGISTER_NUMBER;
--
--	spin_lock_irqsave(&ath724x_pci_lock, flags);
--
--	switch (size) {
--	case 1:
--		addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
--		mask = 0xff000000 >> ((where % 4)*8);
--		tval = reg_read(addr);
--		tval = tval & ~mask;
--		tval |= (value << ((4 - (where % 4))*8)) & mask;
--		reg_write(addr, tval);
--		break;
--	case 2:
--		addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
--		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = reg_read(addr);
--		tval = tval & ~mask;
--		tval |= (value << ((4 - (where % 4))*8)) & mask;
--		reg_write(addr, tval);
--		break;
--	case 4:
--		reg_write((ATH724X_PCI_DEV_BASE + where), value);
--		break;
--	default:
--		spin_unlock_irqrestore(&ath724x_pci_lock, flags);
--
--		return PCIBIOS_BAD_REGISTER_NUMBER;
--	}
--
--	spin_unlock_irqrestore(&ath724x_pci_lock, flags);
--
--	return PCIBIOS_SUCCESSFUL;
--}
--
--static struct pci_ops ath724x_pci_ops = {
--	.read	= ath724x_pci_read,
--	.write	= ath724x_pci_write,
--};
--
--static struct resource ath724x_io_resource = {
--	.name   = "PCI IO space",
--	.start  = 0,
--	.end    = 0,
--	.flags  = IORESOURCE_IO,
--};
--
--static struct resource ath724x_mem_resource = {
--	.name   = "PCI memory space",
--	.start  = ATH724X_PCI_MEM_BASE,
--	.end    = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1,
--	.flags  = IORESOURCE_MEM,
--};
--
--static struct pci_controller ath724x_pci_controller = {
--	.pci_ops        = &ath724x_pci_ops,
--	.io_resource    = &ath724x_io_resource,
--	.mem_resource	= &ath724x_mem_resource,
--};
--
--int __init ath724x_pcibios_init(void)
--{
--	register_pci_controller(&ath724x_pci_controller);
--
--	return PCIBIOS_SUCCESSFUL;
--}
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-rename-pci-ath724x.h.patch b/bsp/routerstationpro/MIPS-ath79-rename-pci-ath724x.h.patch
deleted file mode 100644
index 0559d35b5ec46531342218a4167e5f76e5f18fe5..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-rename-pci-ath724x.h.patch
+++ /dev/null
@@ -1,118 +0,0 @@
-From 29d44ff45b876963f723cfc4bf4d3773b9e54a72 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:22 +0100
-Subject: [PATCH 033/123] MIPS: ath79: rename pci-ath724x.h
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-commit 3a6208df8eb97e01fd8510762dd59dce375dd14d upstream.
-
-The declared function in this header file is used by the
-ath79 platform code only. Move the header to the platform
-directory.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: René Bolldorf <xsecute@googlemail.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3486/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c                 |    2 +-
- arch/mips/ath79/pci.c                          |    2 +-
- arch/mips/ath79/pci.h                          |   21 +++++++++++++++++++++
- arch/mips/include/asm/mach-ath79/pci-ath724x.h |   21 ---------------------
- 4 files changed, 23 insertions(+), 23 deletions(-)
- create mode 100644 arch/mips/ath79/pci.h
- delete mode 100644 arch/mips/include/asm/mach-ath79/pci-ath724x.h
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index 3c311a5..a043500 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -15,13 +15,13 @@
- 
- #ifdef CONFIG_PCI
- #include <linux/ath9k_platform.h>
--#include <asm/mach-ath79/pci-ath724x.h>
- #endif /* CONFIG_PCI */
- 
- #include "machtypes.h"
- #include "dev-gpio-buttons.h"
- #include "dev-leds-gpio.h"
- #include "dev-spi.h"
-+#include "pci.h"
- 
- #define UBNT_XM_GPIO_LED_L1		0
- #define UBNT_XM_GPIO_LED_L2		1
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 8db076e..4957428 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -9,7 +9,7 @@
-  */
- 
- #include <linux/pci.h>
--#include <asm/mach-ath79/pci-ath724x.h>
-+#include "pci.h"
- 
- static struct ath724x_pci_data *pci_data;
- static int pci_data_size;
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-new file mode 100644
-index 0000000..454885f
---- /dev/null
-+++ b/arch/mips/ath79/pci.h
-@@ -0,0 +1,21 @@
-+/*
-+ *  Atheros 724x PCI support
-+ *
-+ *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.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.
-+ */
-+
-+#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H
-+#define __ASM_MACH_ATH79_PCI_ATH724X_H
-+
-+struct ath724x_pci_data {
-+	int irq;
-+	void *pdata;
-+};
-+
-+void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
-+
-+#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
-diff --git a/arch/mips/include/asm/mach-ath79/pci-ath724x.h b/arch/mips/include/asm/mach-ath79/pci-ath724x.h
-deleted file mode 100644
-index 454885f..0000000
---- a/arch/mips/include/asm/mach-ath79/pci-ath724x.h
-+++ /dev/null
-@@ -1,21 +0,0 @@
--/*
-- *  Atheros 724x PCI support
-- *
-- *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.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.
-- */
--
--#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H
--#define __ASM_MACH_ATH79_PCI_ATH724X_H
--
--struct ath724x_pci_data {
--	int irq;
--	void *pdata;
--};
--
--void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
--
--#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-replace-ath724x-to-ar724x.patch b/bsp/routerstationpro/MIPS-ath79-replace-ath724x-to-ar724x.patch
deleted file mode 100644
index f1c0661955d51ed36aa1a30110ad265112146695..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-replace-ath724x-to-ar724x.patch
+++ /dev/null
@@ -1,280 +0,0 @@
-From 0e30985c2e8b99e434ff69cedef85ee013402a90 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:26 +0100
-Subject: [PATCH 037/123] MIPS: ath79: replace ath724x to ar724x
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-commit d624bd3cf7835612b25b9ec8db4002624c2dbb32 upstream
-
-Replace the 'ath724x' to 'ar724x' in function, variable and
-structure names to reflect the name of the real SoC.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: René Bolldorf <xsecute@googlemail.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3490/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/mach-ubnt-xm.c         |    4 +--
- arch/mips/ath79/pci.c                  |    6 ++--
- arch/mips/ath79/pci.h                  |   10 +++---
- arch/mips/include/asm/mach-ath79/pci.h |    4 +--
- arch/mips/pci/pci-ar724x.c             |   62 ++++++++++++++++----------------
- 5 files changed, 43 insertions(+), 43 deletions(-)
-
-diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
-index edbc093..3266ee0 100644
---- a/arch/mips/ath79/mach-ubnt-xm.c
-+++ b/arch/mips/ath79/mach-ubnt-xm.c
-@@ -84,7 +84,7 @@ static struct ath79_spi_platform_data ubnt_xm_spi_data = {
- #ifdef CONFIG_PCI
- static struct ath9k_platform_data ubnt_xm_eeprom_data;
- 
--static struct ath724x_pci_data ubnt_xm_pci_data[] = {
-+static struct ar724x_pci_data ubnt_xm_pci_data[] = {
- 	{
- 		.irq	= UBNT_XM_PCI_IRQ,
- 		.pdata	= &ubnt_xm_eeprom_data,
-@@ -108,7 +108,7 @@ static void __init ubnt_xm_init(void)
- 	memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
- 	       sizeof(ubnt_xm_eeprom_data.eeprom_data));
- 
--	ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
-+	ar724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
- #endif /* CONFIG_PCI */
- 
- 	ath79_register_pci();
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 855a69d..72281fb 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -13,10 +13,10 @@
- #include <asm/mach-ath79/pci.h>
- #include "pci.h"
- 
--static struct ath724x_pci_data *pci_data;
-+static struct ar724x_pci_data *pci_data;
- static int pci_data_size;
- 
--void ath724x_pci_add_data(struct ath724x_pci_data *data, int size)
-+void ar724x_pci_add_data(struct ar724x_pci_data *data, int size)
- {
- 	pci_data	= data;
- 	pci_data_size	= size;
-@@ -50,7 +50,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
- int __init ath79_register_pci(void)
- {
- 	if (soc_is_ar724x())
--		return ath724x_pcibios_init();
-+		return ar724x_pcibios_init();
- 
- 	return -ENODEV;
- }
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-index 787fac2..e0601c4 100644
---- a/arch/mips/ath79/pci.h
-+++ b/arch/mips/ath79/pci.h
-@@ -8,15 +8,15 @@
-  *  by the Free Software Foundation.
-  */
- 
--#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H
--#define __ASM_MACH_ATH79_PCI_ATH724X_H
-+#ifndef _ATH79_PCI_H
-+#define _ATH79_PCI_H
- 
--struct ath724x_pci_data {
-+struct ar724x_pci_data {
- 	int irq;
- 	void *pdata;
- };
- 
--void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
-+void ar724x_pci_add_data(struct ar724x_pci_data *data, int size);
- 
- #ifdef CONFIG_PCI
- int ath79_register_pci(void);
-@@ -24,4 +24,4 @@ int ath79_register_pci(void);
- static inline int ath79_register_pci(void) { return 0; }
- #endif
- 
--#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
-+#endif /* _ATH79_PCI_H */
-diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
-index e0c4b53..6d7a837 100644
---- a/arch/mips/include/asm/mach-ath79/pci.h
-+++ b/arch/mips/include/asm/mach-ath79/pci.h
-@@ -12,9 +12,9 @@
- #define __ASM_MACH_ATH79_PCI_H
- 
- #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR724X)
--int ath724x_pcibios_init(void);
-+int ar724x_pcibios_init(void);
- #else
--static inline int ath724x_pcibios_init(void) { return 0; }
-+static inline int ar724x_pcibios_init(void) { return 0; }
- #endif
- 
- #endif /* __ASM_MACH_ATH79_PCI_H */
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index ebefc16..772d12c 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -14,13 +14,13 @@
- #define reg_read(_phys)		(*(unsigned int *) KSEG1ADDR(_phys))
- #define reg_write(_phys, _val)	((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
- 
--#define ATH724X_PCI_DEV_BASE	0x14000000
--#define ATH724X_PCI_MEM_BASE	0x10000000
--#define ATH724X_PCI_MEM_SIZE	0x08000000
-+#define AR724X_PCI_DEV_BASE	0x14000000
-+#define AR724X_PCI_MEM_BASE	0x10000000
-+#define AR724X_PCI_MEM_SIZE	0x08000000
- 
--static DEFINE_SPINLOCK(ath724x_pci_lock);
-+static DEFINE_SPINLOCK(ar724x_pci_lock);
- 
--static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
-+static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 			    int size, uint32_t *value)
- {
- 	unsigned long flags, addr, tval, mask;
-@@ -31,38 +31,38 @@ static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (where & (size - 1))
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 
--	spin_lock_irqsave(&ath724x_pci_lock, flags);
-+	spin_lock_irqsave(&ar724x_pci_lock, flags);
- 
- 	switch (size) {
- 	case 1:
- 		addr = where & ~3;
- 		mask = 0xff000000 >> ((where % 4) * 8);
--		tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
-+		tval = reg_read(AR724X_PCI_DEV_BASE + addr);
- 		tval = tval & ~mask;
- 		*value = (tval >> ((4 - (where % 4))*8));
- 		break;
- 	case 2:
- 		addr = where & ~3;
- 		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
-+		tval = reg_read(AR724X_PCI_DEV_BASE + addr);
- 		tval = tval & ~mask;
- 		*value = (tval >> ((4 - (where % 4))*8));
- 		break;
- 	case 4:
--		*value = reg_read(ATH724X_PCI_DEV_BASE + where);
-+		*value = reg_read(AR724X_PCI_DEV_BASE + where);
- 		break;
- 	default:
--		spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
- 
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 	}
- 
--	spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
- 
--static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
-+static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 			     int size, uint32_t value)
- {
- 	unsigned long flags, tval, addr, mask;
-@@ -73,11 +73,11 @@ static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (where & (size - 1))
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 
--	spin_lock_irqsave(&ath724x_pci_lock, flags);
-+	spin_lock_irqsave(&ar724x_pci_lock, flags);
- 
- 	switch (size) {
- 	case 1:
--		addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
-+		addr = (AR724X_PCI_DEV_BASE + where) & ~3;
- 		mask = 0xff000000 >> ((where % 4)*8);
- 		tval = reg_read(addr);
- 		tval = tval & ~mask;
-@@ -85,7 +85,7 @@ static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 		reg_write(addr, tval);
- 		break;
- 	case 2:
--		addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
-+		addr = (AR724X_PCI_DEV_BASE + where) & ~3;
- 		mask = 0xffff0000 >> ((where % 4)*8);
- 		tval = reg_read(addr);
- 		tval = tval & ~mask;
-@@ -93,47 +93,47 @@ static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 		reg_write(addr, tval);
- 		break;
- 	case 4:
--		reg_write((ATH724X_PCI_DEV_BASE + where), value);
-+		reg_write((AR724X_PCI_DEV_BASE + where), value);
- 		break;
- 	default:
--		spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
- 
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 	}
- 
--	spin_unlock_irqrestore(&ath724x_pci_lock, flags);
-+	spin_unlock_irqrestore(&ar724x_pci_lock, flags);
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
- 
--static struct pci_ops ath724x_pci_ops = {
--	.read	= ath724x_pci_read,
--	.write	= ath724x_pci_write,
-+static struct pci_ops ar724x_pci_ops = {
-+	.read	= ar724x_pci_read,
-+	.write	= ar724x_pci_write,
- };
- 
--static struct resource ath724x_io_resource = {
-+static struct resource ar724x_io_resource = {
- 	.name   = "PCI IO space",
- 	.start  = 0,
- 	.end    = 0,
- 	.flags  = IORESOURCE_IO,
- };
- 
--static struct resource ath724x_mem_resource = {
-+static struct resource ar724x_mem_resource = {
- 	.name   = "PCI memory space",
--	.start  = ATH724X_PCI_MEM_BASE,
--	.end    = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1,
-+	.start  = AR724X_PCI_MEM_BASE,
-+	.end    = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1,
- 	.flags  = IORESOURCE_MEM,
- };
- 
--static struct pci_controller ath724x_pci_controller = {
--	.pci_ops        = &ath724x_pci_ops,
--	.io_resource    = &ath724x_io_resource,
--	.mem_resource	= &ath724x_mem_resource,
-+static struct pci_controller ar724x_pci_controller = {
-+	.pci_ops        = &ar724x_pci_ops,
-+	.io_resource    = &ar724x_io_resource,
-+	.mem_resource	= &ar724x_mem_resource,
- };
- 
--int __init ath724x_pcibios_init(void)
-+int __init ar724x_pcibios_init(void)
- {
--	register_pci_controller(&ath724x_pci_controller);
-+	register_pci_controller(&ar724x_pci_controller);
- 
- 	return PCIBIOS_SUCCESSFUL;
- }
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch b/bsp/routerstationpro/MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch
deleted file mode 100644
index fe63380b2f69cfca47e5af7c890f603310b8ad1d..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch
+++ /dev/null
@@ -1,166 +0,0 @@
-From fafb3babde6029242baae7b63f25c6064d9c8159 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:24 +0100
-Subject: [PATCH 056/123] MIPS: ath79: rework IP2/IP3 interrupt handling
-
-commit 4dbcbdf8135def8f704b130305721bdd42a8078b upstream
-
-The current implementation assumes that flushing the
-DDR writeback buffer is required for IP2/IP3 interrupts,
-however this is not true for all SoCs.
-
-Use SoC specific IP2/IP3 handlers instead of flushing
-the buffers in the dispatcher code.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3509/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/irq.c |   92 ++++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 72 insertions(+), 20 deletions(-)
-
-diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
-index 1b073de..9f87ade 100644
---- a/arch/mips/ath79/irq.c
-+++ b/arch/mips/ath79/irq.c
-@@ -1,7 +1,7 @@
- /*
-  *  Atheros AR71xx/AR724x/AR913x specific interrupt handling
-  *
-- *  Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-  *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-  *  Parts of this file are based on Atheros' 2.6.15 BSP
-@@ -23,8 +23,8 @@
- #include <asm/mach-ath79/ar71xx_regs.h>
- #include "common.h"
- 
--static unsigned int ath79_ip2_flush_reg;
--static unsigned int ath79_ip3_flush_reg;
-+static void (*ath79_ip2_handler)(void);
-+static void (*ath79_ip3_handler)(void);
- 
- static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
- {
-@@ -152,10 +152,8 @@ asmlinkage void plat_irq_dispatch(void)
- 	if (pending & STATUSF_IP7)
- 		do_IRQ(ATH79_CPU_IRQ_TIMER);
- 
--	else if (pending & STATUSF_IP2) {
--		ath79_ddr_wb_flush(ath79_ip2_flush_reg);
--		do_IRQ(ATH79_CPU_IRQ_IP2);
--	}
-+	else if (pending & STATUSF_IP2)
-+		ath79_ip2_handler();
- 
- 	else if (pending & STATUSF_IP4)
- 		do_IRQ(ATH79_CPU_IRQ_GE0);
-@@ -163,10 +161,8 @@ asmlinkage void plat_irq_dispatch(void)
- 	else if (pending & STATUSF_IP5)
- 		do_IRQ(ATH79_CPU_IRQ_GE1);
- 
--	else if (pending & STATUSF_IP3) {
--		ath79_ddr_wb_flush(ath79_ip3_flush_reg);
--		do_IRQ(ATH79_CPU_IRQ_USB);
--	}
-+	else if (pending & STATUSF_IP3)
-+		ath79_ip3_handler();
- 
- 	else if (pending & STATUSF_IP6)
- 		do_IRQ(ATH79_CPU_IRQ_MISC);
-@@ -175,22 +171,78 @@ asmlinkage void plat_irq_dispatch(void)
- 		spurious_interrupt();
- }
- 
-+/*
-+ * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for
-+ * these devices typically allocate coherent DMA memory, however the
-+ * DMA controller may still have some unsynchronized data in the FIFO.
-+ * Issue a flush in the handlers to ensure that the driver sees
-+ * the update.
-+ */
-+static void ar71xx_ip2_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI);
-+	do_IRQ(ATH79_CPU_IRQ_IP2);
-+}
-+
-+static void ar724x_ip2_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE);
-+	do_IRQ(ATH79_CPU_IRQ_IP2);
-+}
-+
-+static void ar913x_ip2_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC);
-+	do_IRQ(ATH79_CPU_IRQ_IP2);
-+}
-+
-+static void ar933x_ip2_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC);
-+	do_IRQ(ATH79_CPU_IRQ_IP2);
-+}
-+
-+static void ar71xx_ip3_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB);
-+	do_IRQ(ATH79_CPU_IRQ_USB);
-+}
-+
-+static void ar724x_ip3_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB);
-+	do_IRQ(ATH79_CPU_IRQ_USB);
-+}
-+
-+static void ar913x_ip3_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB);
-+	do_IRQ(ATH79_CPU_IRQ_USB);
-+}
-+
-+static void ar933x_ip3_handler(void)
-+{
-+	ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB);
-+	do_IRQ(ATH79_CPU_IRQ_USB);
-+}
-+
- void __init arch_init_irq(void)
- {
- 	if (soc_is_ar71xx()) {
--		ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
--		ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
-+		ath79_ip2_handler = ar71xx_ip2_handler;
-+		ath79_ip3_handler = ar71xx_ip3_handler;
- 	} else if (soc_is_ar724x()) {
--		ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
--		ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
-+		ath79_ip2_handler = ar724x_ip2_handler;
-+		ath79_ip3_handler = ar724x_ip3_handler;
- 	} else if (soc_is_ar913x()) {
--		ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
--		ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
-+		ath79_ip2_handler = ar913x_ip2_handler;
-+		ath79_ip3_handler = ar913x_ip3_handler;
- 	} else if (soc_is_ar933x()) {
--		ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC;
--		ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB;
--	} else
-+		ath79_ip2_handler = ar933x_ip2_handler;
-+		ath79_ip3_handler = ar933x_ip3_handler;
-+	} else {
- 		BUG();
-+	}
- 
- 	cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
- 	mips_cpu_irq_init();
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-separate-common-PCI-code.patch b/bsp/routerstationpro/MIPS-ath79-separate-common-PCI-code.patch
deleted file mode 100644
index 727332525deecd966b98a02f553f09dd79e35c8b..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-separate-common-PCI-code.patch
+++ /dev/null
@@ -1,163 +0,0 @@
-From 2c65709cc98296282031deed473d83db2d8cf55a Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:21 +0100
-Subject: [PATCH 032/123] MIPS: ath79: separate common PCI code
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-commit e2dbdc436b46250c8682ea57151a7afb45f271e1 upstream.
-
-The 'pcibios_map_irq' and 'pcibios_plat_dev_init'
-are common functions and only instance one of them
-can be present in a single kernel.
-
-Currently these functions can be built only if the
-CONFIG_SOC_AR724X option is selected. However the
-ath79 platform contain support for the AR71XX SoCs,.
-The AR71XX SoCs have a differnet PCI controller,
-and those will require a different code.
-
-Move the common PCI code into a separeate file in
-order to be able to use that with other SoCs as
-well.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: René Bolldorf <xsecute@googlemail.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3485/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/Makefile    |    1 +
- arch/mips/ath79/pci.c       |   46 +++++++++++++++++++++++++++++++++++++++++++
- arch/mips/pci/pci-ath724x.c |   34 --------------------------------
- 3 files changed, 47 insertions(+), 34 deletions(-)
- create mode 100644 arch/mips/ath79/pci.c
-
-diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
-index 3b911e09..221a76a 100644
---- a/arch/mips/ath79/Makefile
-+++ b/arch/mips/ath79/Makefile
-@@ -11,6 +11,7 @@
- obj-y	:= prom.o setup.o irq.o common.o clock.o gpio.o
- 
- obj-$(CONFIG_EARLY_PRINTK)		+= early_printk.o
-+obj-$(CONFIG_PCI)			+= pci.o
- 
- #
- # Devices
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-new file mode 100644
-index 0000000..8db076e
---- /dev/null
-+++ b/arch/mips/ath79/pci.c
-@@ -0,0 +1,46 @@
-+/*
-+ *  Atheros AR71XX/AR724X specific PCI setup code
-+ *
-+ *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.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/pci.h>
-+#include <asm/mach-ath79/pci-ath724x.h>
-+
-+static struct ath724x_pci_data *pci_data;
-+static int pci_data_size;
-+
-+void ath724x_pci_add_data(struct ath724x_pci_data *data, int size)
-+{
-+	pci_data	= data;
-+	pci_data_size	= size;
-+}
-+
-+int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
-+{
-+	unsigned int devfn = dev->devfn;
-+	int irq = -1;
-+
-+	if (devfn > pci_data_size - 1)
-+		return irq;
-+
-+	irq = pci_data[devfn].irq;
-+
-+	return irq;
-+}
-+
-+int pcibios_plat_dev_init(struct pci_dev *dev)
-+{
-+	unsigned int devfn = dev->devfn;
-+
-+	if (devfn > pci_data_size - 1)
-+		return PCIBIOS_DEVICE_NOT_FOUND;
-+
-+	dev->dev.platform_data = pci_data[devfn].pdata;
-+
-+	return PCIBIOS_SUCCESSFUL;
-+}
-diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c
-index a4dd24a..1e810be 100644
---- a/arch/mips/pci/pci-ath724x.c
-+++ b/arch/mips/pci/pci-ath724x.c
-@@ -9,7 +9,6 @@
-  */
- 
- #include <linux/pci.h>
--#include <asm/mach-ath79/pci-ath724x.h>
- 
- #define reg_read(_phys)		(*(unsigned int *) KSEG1ADDR(_phys))
- #define reg_write(_phys, _val)	((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
-@@ -19,8 +18,6 @@
- #define ATH724X_PCI_MEM_SIZE	0x08000000
- 
- static DEFINE_SPINLOCK(ath724x_pci_lock);
--static struct ath724x_pci_data *pci_data;
--static int pci_data_size;
- 
- static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 			    int size, uint32_t *value)
-@@ -133,37 +130,6 @@ static struct pci_controller ath724x_pci_controller = {
- 	.mem_resource	= &ath724x_mem_resource,
- };
- 
--void ath724x_pci_add_data(struct ath724x_pci_data *data, int size)
--{
--	pci_data	= data;
--	pci_data_size	= size;
--}
--
--int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
--{
--	unsigned int devfn = dev->devfn;
--	int irq = -1;
--
--	if (devfn > pci_data_size - 1)
--		return irq;
--
--	irq = pci_data[devfn].irq;
--
--	return irq;
--}
--
--int pcibios_plat_dev_init(struct pci_dev *dev)
--{
--	unsigned int devfn = dev->devfn;
--
--	if (devfn > pci_data_size - 1)
--		return PCIBIOS_DEVICE_NOT_FOUND;
--
--	dev->dev.platform_data = pci_data[devfn].pdata;
--
--	return PCIBIOS_SUCCESSFUL;
--}
--
- static int __init ath724x_pcibios_init(void)
- {
- 	register_pci_controller(&ath724x_pci_controller);
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch b/bsp/routerstationpro/MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch
deleted file mode 100644
index 1cd86fe9f528dc83e31920736241a76fe37cafee..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From c36c1920448695bfaccf2879ec4ad3b4e2f4585d Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:45:20 +0100
-Subject: [PATCH 052/123] MIPS: ath79: sort case statements in
- ath79_detect_sys_type
-
-commit 80a7ed81a840aee97f7650cbeaabb3c2c1765e70 upstream.
-
-Sort the case statements alphabetically in order to improve
-readability.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
-Cc: linux-mips@linux-mips.org
-Cc: mcgrof@infradead.org
-Patchwork: https://patchwork.linux-mips.org/patch/3505/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/setup.c |   24 ++++++++++++------------
- 1 file changed, 12 insertions(+), 12 deletions(-)
-
-diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
-index 80a7d40..24dfedf 100644
---- a/arch/mips/ath79/setup.c
-+++ b/arch/mips/ath79/setup.c
-@@ -116,18 +116,6 @@ static void __init ath79_detect_sys_type(void)
- 		rev = id & AR724X_REV_ID_REVISION_MASK;
- 		break;
- 
--	case REV_ID_MAJOR_AR9330:
--		ath79_soc = ATH79_SOC_AR9330;
--		chip = "9330";
--		rev = id & AR933X_REV_ID_REVISION_MASK;
--		break;
--
--	case REV_ID_MAJOR_AR9331:
--		ath79_soc = ATH79_SOC_AR9331;
--		chip = "9331";
--		rev = id & AR933X_REV_ID_REVISION_MASK;
--		break;
--
- 	case REV_ID_MAJOR_AR913X:
- 		minor = id & AR913X_REV_ID_MINOR_MASK;
- 		rev = id >> AR913X_REV_ID_REVISION_SHIFT;
-@@ -145,6 +133,18 @@ static void __init ath79_detect_sys_type(void)
- 		}
- 		break;
- 
-+	case REV_ID_MAJOR_AR9330:
-+		ath79_soc = ATH79_SOC_AR9330;
-+		chip = "9330";
-+		rev = id & AR933X_REV_ID_REVISION_MASK;
-+		break;
-+
-+	case REV_ID_MAJOR_AR9331:
-+		ath79_soc = ATH79_SOC_AR9331;
-+		chip = "9331";
-+		rev = id & AR933X_REV_ID_REVISION_MASK;
-+		break;
-+
- 	default:
- 		panic("ath79: unknown SoC, id:0x%08x", id);
- 	}
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch b/bsp/routerstationpro/MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch
deleted file mode 100644
index 883cafb57bbfe2a86235609050015df5b2be6f27..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch
+++ /dev/null
@@ -1,86 +0,0 @@
-From 7fcf1022dfdc6e6864f6e6e7d4accd3782b651c7 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:36:14 +0100
-Subject: [PATCH 050/123] MIPS: ath79: update copyright headers of PCI related
- files
-
-commit e9b62e8ef9d71ed977797529fc0dfc352448d50b upstream.
-
-Add copyright records according to the recent changes in
-the PCI code. Also fix up the descriptions.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3503/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/pci.c                  |    4 ++++
- arch/mips/ath79/pci.h                  |    4 +++-
- arch/mips/include/asm/mach-ath79/pci.h |    4 +++-
- arch/mips/pci/pci-ar724x.c             |    3 ++-
- 4 files changed, 12 insertions(+), 3 deletions(-)
-
-diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c
-index 253a382..bc40070 100644
---- a/arch/mips/ath79/pci.c
-+++ b/arch/mips/ath79/pci.c
-@@ -2,6 +2,10 @@
-  *  Atheros AR71XX/AR724X specific PCI setup code
-  *
-  *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-+ *
-+ *  Parts of this file are based on Atheros' 2.6.15 BSP
-  *
-  *  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
-diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h
-index 5ebed21..51c6625 100644
---- a/arch/mips/ath79/pci.h
-+++ b/arch/mips/ath79/pci.h
-@@ -1,7 +1,9 @@
- /*
-- *  Atheros 724x PCI support
-+ *  Atheros AR71XX/AR724X PCI support
-  *
-  *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-  *  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
-diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h
-index b12b087..4f2222d 100644
---- a/arch/mips/include/asm/mach-ath79/pci.h
-+++ b/arch/mips/include/asm/mach-ath79/pci.h
-@@ -1,7 +1,9 @@
- /*
-- *  Atheros 724x PCI support
-+ *  Atheros AR71XX/AR724X PCI support
-  *
-  *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
-+ *  Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
-+ *  Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
-  *
-  *  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
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index 04f433a..414a745 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -1,7 +1,8 @@
- /*
-- *  Atheros 724x PCI support
-+ *  Atheros AR724X PCI host controller driver
-  *
-  *  Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
-+ *  Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org>
-  *
-  *  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
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch b/bsp/routerstationpro/MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch
deleted file mode 100644
index 53056e657fc605c492fea46c3eebfc27b4a7dd3d..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-From ac0e95ade1684835d4e98be2897d02b266fc5076 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 28 Mar 2012 11:00:19 +0200
-Subject: [PATCH 064/123] MIPS: ath79: use correct IRQ number for the OHCI
- controller on AR7240
-
-The currently assigned IRQ number to the OHCI
-controller is incorrect for the AR7240 SoC, and
-that leads to the following error message from
-the OHCI driver:
-
-ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
-ath79-ohci ath79-ohci: Atheros built-in OHCI controller
-ath79-ohci ath79-ohci: new USB bus registered, assigned bus number 1
-ath79-ohci ath79-ohci: irq 14, io mem 0x1b000000
-hub 1-0:1.0: USB hub found
-hub 1-0:1.0: 1 port detected
-usb 1-1: new full-speed USB device number 2 using ath79-ohci
-ath79-ohci ath79-ohci: Unlink after no-IRQ?  Controller is probably using the wrong IRQ.
-
-Fix this by using the correct IRQ number.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/ath79/dev-usb.c |    2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
-index 36e9570..b2a2311 100644
---- a/arch/mips/ath79/dev-usb.c
-+++ b/arch/mips/ath79/dev-usb.c
-@@ -145,6 +145,8 @@ static void __init ar7240_usb_setup(void)
- 
- 	ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
- 	ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
-+	ath79_ohci_resources[1].start = ATH79_CPU_IRQ_USB;
-+	ath79_ohci_resources[1].end = ATH79_CPU_IRQ_USB;
- 	platform_device_register(&ath79_ohci_device);
- }
- 
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch b/bsp/routerstationpro/MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch
deleted file mode 100644
index 5b96926d16e2c98a4864d9766635f725e8e20a1b..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-From 4ad8cc29bd428fffc4003ffaa2a1b60dbb02675d Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Wed, 14 Mar 2012 10:29:27 +0100
-Subject: [PATCH 038/123] MIPS: ath79: use io-accessor macros in pci-ar724x.c
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-commit c198441a3f3007752c551a32d5c426f48ae8712d upstream.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Acked-by: René Bolldorf <xsecute@googlemail.com>
-Cc: linux-mips@linux-mips.org
-Patchwork: https://patchwork.linux-mips.org/patch/3491/
-Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- arch/mips/pci/pci-ar724x.c |   38 ++++++++++++++++++++++++--------------
- 1 file changed, 24 insertions(+), 14 deletions(-)
-
-diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c
-index 772d12c..22f5e5b 100644
---- a/arch/mips/pci/pci-ar724x.c
-+++ b/arch/mips/pci/pci-ar724x.c
-@@ -11,19 +11,19 @@
- #include <linux/pci.h>
- #include <asm/mach-ath79/pci.h>
- 
--#define reg_read(_phys)		(*(unsigned int *) KSEG1ADDR(_phys))
--#define reg_write(_phys, _val)	((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
--
--#define AR724X_PCI_DEV_BASE	0x14000000
-+#define AR724X_PCI_CFG_BASE	0x14000000
-+#define AR724X_PCI_CFG_SIZE	0x1000
- #define AR724X_PCI_MEM_BASE	0x10000000
- #define AR724X_PCI_MEM_SIZE	0x08000000
- 
- static DEFINE_SPINLOCK(ar724x_pci_lock);
-+static void __iomem *ar724x_pci_devcfg_base;
- 
- static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 			    int size, uint32_t *value)
- {
- 	unsigned long flags, addr, tval, mask;
-+	void __iomem *base;
- 
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
-@@ -31,25 +31,27 @@ static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (where & (size - 1))
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 
-+	base = ar724x_pci_devcfg_base;
-+
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
- 
- 	switch (size) {
- 	case 1:
- 		addr = where & ~3;
- 		mask = 0xff000000 >> ((where % 4) * 8);
--		tval = reg_read(AR724X_PCI_DEV_BASE + addr);
-+		tval = __raw_readl(base + addr);
- 		tval = tval & ~mask;
- 		*value = (tval >> ((4 - (where % 4))*8));
- 		break;
- 	case 2:
- 		addr = where & ~3;
- 		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = reg_read(AR724X_PCI_DEV_BASE + addr);
-+		tval = __raw_readl(base + addr);
- 		tval = tval & ~mask;
- 		*value = (tval >> ((4 - (where % 4))*8));
- 		break;
- 	case 4:
--		*value = reg_read(AR724X_PCI_DEV_BASE + where);
-+		*value = __raw_readl(base + where);
- 		break;
- 	default:
- 		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
-@@ -66,6 +68,7 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 			     int size, uint32_t value)
- {
- 	unsigned long flags, tval, addr, mask;
-+	void __iomem *base;
- 
- 	if (devfn)
- 		return PCIBIOS_DEVICE_NOT_FOUND;
-@@ -73,27 +76,29 @@ static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- 	if (where & (size - 1))
- 		return PCIBIOS_BAD_REGISTER_NUMBER;
- 
-+	base = ar724x_pci_devcfg_base;
-+
- 	spin_lock_irqsave(&ar724x_pci_lock, flags);
- 
- 	switch (size) {
- 	case 1:
--		addr = (AR724X_PCI_DEV_BASE + where) & ~3;
-+		addr = where & ~3;
- 		mask = 0xff000000 >> ((where % 4)*8);
--		tval = reg_read(addr);
-+		tval = __raw_readl(base + addr);
- 		tval = tval & ~mask;
- 		tval |= (value << ((4 - (where % 4))*8)) & mask;
--		reg_write(addr, tval);
-+		__raw_writel(tval, base + addr);
- 		break;
- 	case 2:
--		addr = (AR724X_PCI_DEV_BASE + where) & ~3;
-+		addr = where & ~3;
- 		mask = 0xffff0000 >> ((where % 4)*8);
--		tval = reg_read(addr);
-+		tval = __raw_readl(base + addr);
- 		tval = tval & ~mask;
- 		tval |= (value << ((4 - (where % 4))*8)) & mask;
--		reg_write(addr, tval);
-+		__raw_writel(tval, base + addr);
- 		break;
- 	case 4:
--		reg_write((AR724X_PCI_DEV_BASE + where), value);
-+		__raw_writel(value, (base + where));
- 		break;
- 	default:
- 		spin_unlock_irqrestore(&ar724x_pci_lock, flags);
-@@ -133,6 +138,11 @@ static struct pci_controller ar724x_pci_controller = {
- 
- int __init ar724x_pcibios_init(void)
- {
-+	ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE,
-+					 AR724X_PCI_CFG_SIZE);
-+	if (ar724x_pci_devcfg_base == NULL)
-+		return -ENOMEM;
-+
- 	register_pci_controller(&ar724x_pci_controller);
- 
- 	return PCIBIOS_SUCCESSFUL;
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/generic-openwrt-phy-files.patch b/bsp/routerstationpro/generic-openwrt-phy-files.patch
index 26894fc7590884407b3147be55fc455a9bd7fba6..33e8d45cc6d8c82a27bc08c5694dc033a7167291 100644
--- a/bsp/routerstationpro/generic-openwrt-phy-files.patch
+++ b/bsp/routerstationpro/generic-openwrt-phy-files.patch
@@ -24,42 +24,6 @@ Path to files in the repo is: target/linux/generic/files
 Repo is: git://nbd.name/openwrt.git
 
 Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- drivers/net/phy/adm6996.c       |  737 ++++++++++++++++
- drivers/net/phy/adm6996.h       |  162 ++++
- drivers/net/phy/ar8216.c        | 1535 +++++++++++++++++++++++++++++++++
- drivers/net/phy/ar8216.h        |  341 ++++++++
- drivers/net/phy/ip17xx.c        | 1410 +++++++++++++++++++++++++++++++
- drivers/net/phy/micrel.c        |  270 ++----
- drivers/net/phy/mvswitch.c      |  422 ++++++++++
- drivers/net/phy/mvswitch.h      |  145 ++++
- drivers/net/phy/psb6970.c       |  438 ++++++++++
- drivers/net/phy/rtl8306.c       | 1055 +++++++++++++++++++++++
- drivers/net/phy/rtl8366_smi.c   | 1350 +++++++++++++++++++++++++++++
- drivers/net/phy/rtl8366_smi.h   |  148 ++++
- drivers/net/phy/rtl8366rb.c     | 1269 ++++++++++++++++++++++++++++
- drivers/net/phy/rtl8366s.c      | 1148 +++++++++++++++++++++++++
- drivers/net/phy/rtl8367.c       | 1773 +++++++++++++++++++++++++++++++++++++++
- drivers/net/phy/swconfig.c      | 1042 +++++++++++++++++++++++
- drivers/net/phy/swconfig_leds.c |  354 ++++++++
- 17 files changed, 13380 insertions(+), 219 deletions(-)
- create mode 100644 drivers/net/phy/adm6996.c
- create mode 100644 drivers/net/phy/adm6996.h
- create mode 100644 drivers/net/phy/ar8216.c
- create mode 100644 drivers/net/phy/ar8216.h
- create mode 100644 drivers/net/phy/ip17xx.c
- create mode 100644 drivers/net/phy/mvswitch.c
- create mode 100644 drivers/net/phy/mvswitch.h
- create mode 100644 drivers/net/phy/psb6970.c
- create mode 100644 drivers/net/phy/rtl8306.c
- create mode 100644 drivers/net/phy/rtl8366_smi.c
- create mode 100644 drivers/net/phy/rtl8366_smi.h
- create mode 100644 drivers/net/phy/rtl8366rb.c
- create mode 100644 drivers/net/phy/rtl8366s.c
- create mode 100644 drivers/net/phy/rtl8367.c
- create mode 100644 drivers/net/phy/swconfig.c
- create mode 100644 drivers/net/phy/swconfig_leds.c
-
 diff --git a/drivers/net/phy/adm6996.c b/drivers/net/phy/adm6996.c
 new file mode 100644
 index 0000000..d4fe553
@@ -4276,10 +4240,10 @@ index 0000000..c82c39e
 +module_init(ip17xx_init);
 +module_exit(ip17xx_exit);
 diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
-index 590f902..1499d4a 100644
+index cf287e0..c34bbad 100644
 --- a/drivers/net/phy/micrel.c
 +++ b/drivers/net/phy/micrel.c
-@@ -1,251 +1,83 @@
+@@ -1,145 +1,62 @@
  /*
 - * drivers/net/phy/micrel.c
 + *  Driver for Micrel/Kendin PHYs
@@ -4349,11 +4313,11 @@ index 590f902..1499d4a 100644
 -		KSZPHY_INTCS_ALL : 0;
 -	return phy_write(phydev, MII_KSZPHY_INTCS, temp);
 -}
--
+ 
 -static int kszphy_config_intr(struct phy_device *phydev)
 -{
 -	int temp, rc;
- 
+-
 -	/* set the interrupt pin active low */
 -	temp = phy_read(phydev, MII_KSZPHY_CTRL);
 -	temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH;
@@ -4421,21 +4385,26 @@ index 590f902..1499d4a 100644
 +	return err;
  }
  
--static struct phy_driver ks8737_driver = {
+-static struct phy_driver ksphy_driver[] = {
++static struct phy_driver ksz8041_phy_driver[] = {
+ {
 -	.phy_id		= PHY_ID_KS8737,
 -	.phy_id_mask	= 0x00fffff0,
 -	.name		= "Micrel KS8737",
 -	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
 -	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
 -	.config_init	= kszphy_config_init,
--	.config_aneg	= genphy_config_aneg,
--	.read_status	= genphy_read_status,
++	.phy_id		= 0x00221512,
++	.name		= "Micrel KSZ8041",
++	.phy_id_mask	= 0x001fffff,
++	.features	= PHY_BASIC_FEATURES,
++	.flags		= PHY_HAS_INTERRUPT,
+ 	.config_aneg	= genphy_config_aneg,
+ 	.read_status	= genphy_read_status,
 -	.ack_interrupt	= kszphy_ack_interrupt,
 -	.config_intr	= ks8737_config_intr,
 -	.driver		= { .owner = THIS_MODULE,},
--};
--
--static struct phy_driver ks8041_driver = {
+-}, {
 -	.phy_id		= PHY_ID_KS8041,
 -	.phy_id_mask	= 0x00fffff0,
 -	.name		= "Micrel KS8041",
@@ -4448,110 +4417,31 @@ index 590f902..1499d4a 100644
 -	.ack_interrupt	= kszphy_ack_interrupt,
 -	.config_intr	= kszphy_config_intr,
 -	.driver		= { .owner = THIS_MODULE,},
--};
--
--static struct phy_driver ks8051_driver = {
--	.phy_id		= PHY_ID_KS8051,
--	.phy_id_mask	= 0x00fffff0,
--	.name		= "Micrel KS8051",
--	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause
--				| SUPPORTED_Asym_Pause),
--	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
--	.config_init	= ks8051_config_init,
--	.config_aneg	= genphy_config_aneg,
--	.read_status	= genphy_read_status,
--	.ack_interrupt	= kszphy_ack_interrupt,
--	.config_intr	= kszphy_config_intr,
--	.driver		= { .owner = THIS_MODULE,},
--};
--
--static struct phy_driver ks8001_driver = {
--	.phy_id		= PHY_ID_KS8001,
--	.name		= "Micrel KS8001 or KS8721",
--	.phy_id_mask	= 0x00fffff0,
--	.features	= (PHY_BASIC_FEATURES | SUPPORTED_Pause),
--	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
--	.config_init	= kszphy_config_init,
--	.config_aneg	= genphy_config_aneg,
--	.read_status	= genphy_read_status,
--	.ack_interrupt	= kszphy_ack_interrupt,
--	.config_intr	= kszphy_config_intr,
--	.driver		= { .owner = THIS_MODULE,},
--};
--
--static struct phy_driver ksz9021_driver = {
--	.phy_id		= PHY_ID_KSZ9021,
--	.phy_id_mask	= 0x000fff10,
--	.name		= "Micrel KSZ9021 Gigabit PHY",
--	.features	= (PHY_GBIT_FEATURES | SUPPORTED_Pause
--				| SUPPORTED_Asym_Pause),
--	.flags		= PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
--	.config_init	= kszphy_config_init,
-+static struct phy_driver ksz8041_phy_driver = {
-+	.phy_id		= 0x00221512,
-+	.name		= "Micrel KSZ8041",
-+	.phy_id_mask	= 0x001fffff,
-+	.features	= PHY_BASIC_FEATURES,
-+	.flags		= PHY_HAS_INTERRUPT,
- 	.config_aneg	= genphy_config_aneg,
- 	.read_status	= genphy_read_status,
--	.ack_interrupt	= kszphy_ack_interrupt,
--	.config_intr	= ksz9021_config_intr,
--	.driver		= { .owner = THIS_MODULE, },
 +	.ack_interrupt	= ksz8041_ack_interrupt,
 +	.config_intr	= ksz8041_config_intr,
-+	.driver	= {
-+		.owner	= THIS_MODULE,
-+	},
- };
++	.driver	= { .owner	= THIS_MODULE, },
+ }, {
+ 	.phy_id		= PHY_ID_KS8051,
+ 	.phy_id_mask	= 0x00fffff0,
+@@ -180,32 +97,25 @@ static struct phy_driver ksphy_driver[] = {
+ 	.driver		= { .owner = THIS_MODULE, },
+ } };
  
 -static int __init ksphy_init(void)
 +static int __init micrel_phy_init(void)
  {
--	int ret;
--
--	ret = phy_driver_register(&ks8001_driver);
--	if (ret)
--		goto err1;
--
--	ret = phy_driver_register(&ksz9021_driver);
--	if (ret)
--		goto err2;
--
--	ret = phy_driver_register(&ks8737_driver);
--	if (ret)
--		goto err3;
--	ret = phy_driver_register(&ks8041_driver);
--	if (ret)
--		goto err4;
--	ret = phy_driver_register(&ks8051_driver);
--	if (ret)
--		goto err5;
--
--	return 0;
--
--err5:
--	phy_driver_unregister(&ks8041_driver);
--err4:
--	phy_driver_unregister(&ks8737_driver);
--err3:
--	phy_driver_unregister(&ksz9021_driver);
--err2:
--	phy_driver_unregister(&ks8001_driver);
--err1:
--	return ret;
-+	return phy_driver_register(&ksz8041_phy_driver);
+-	return phy_drivers_register(ksphy_driver,
+-		ARRAY_SIZE(ksphy_driver));
++    return phy_driver_register(ksz8041_phy_driver,
++			       ARRAY_SIZE(ksz8041_phy_driver));
  }
  
 -static void __exit ksphy_exit(void)
 +static void __exit micrel_phy_exit(void)
  {
--	phy_driver_unregister(&ks8001_driver);
--	phy_driver_unregister(&ks8737_driver);
--	phy_driver_unregister(&ksz9021_driver);
--	phy_driver_unregister(&ks8041_driver);
--	phy_driver_unregister(&ks8051_driver);
-+	phy_driver_unregister(&ksz8041_phy_driver);
+-	phy_drivers_unregister(ksphy_driver,
+-		ARRAY_SIZE(ksphy_driver));
++    phy_driver_unregister(ksz8041_phy_driver,ARRAY_SIZE(ksz8041_phy_driver) );
  }
  
 -module_init(ksphy_init);
@@ -4562,8 +4452,8 @@ index 590f902..1499d4a 100644
 -MODULE_LICENSE("GPL");
 -
 -static struct mdio_device_id __maybe_unused micrel_tbl[] = {
--	{ PHY_ID_KSZ9021, 0x000fff10 },
--	{ PHY_ID_KS8001, 0x00fffff0 },
+-	{ PHY_ID_KSZ9021, 0x000ffffe },
+-	{ PHY_ID_KS8001, 0x00ffffff },
 -	{ PHY_ID_KS8737, 0x00fffff0 },
 -	{ PHY_ID_KS8041, 0x00fffff0 },
 -	{ PHY_ID_KS8051, 0x00fffff0 },
@@ -13792,6 +13682,3 @@ index 0000000..6f54cc1
 +static inline void
 +swconfig_destroy_led_trigger(struct switch_dev *swdev) { }
 +#endif /* CONFIG_SWCONFIG_LEDS */
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/remaining-generic-openwrt-files.patch b/bsp/routerstationpro/remaining-generic-openwrt-files.patch
index b00d1434b3e77be4e302f87eaead8fbfed14ddcb..db386531398b6d287af2b91a556ba87cc31c2b29 100644
--- a/bsp/routerstationpro/remaining-generic-openwrt-files.patch
+++ b/bsp/routerstationpro/remaining-generic-openwrt-files.patch
@@ -24,39 +24,6 @@ Path to files in the repo is: target/linux/generic/files
 Repo is: git://nbd.name/openwrt.git
 
 Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- Documentation/networking/adm6996.txt |  110 ++++++
- Documentation/pwm.txt                |  259 ++++++++++++++
- arch/mips/fw/myloader/Makefile       |    5 +
- arch/mips/fw/myloader/myloader.c     |   63 ++++
- drivers/char/gpio_dev.c              |  179 ++++++++++
- drivers/input/misc/gpio_buttons.c    |  232 ++++++++++++
- drivers/leds/ledtrig-morse.c         |  366 +++++++++++++++++++
- drivers/leds/ledtrig-netdev.c        |  451 ++++++++++++++++++++++++
- drivers/leds/ledtrig-usbdev.c        |  348 ++++++++++++++++++
- drivers/mtd/myloader.c               |  186 ++++++++++
- drivers/pwm/Kconfig                  |   31 ++
- drivers/pwm/Makefile                 |    6 +
- drivers/pwm/atmel-pwm.c              |  592 +++++++++++++++++++++++++++++++
- drivers/pwm/gpio-pwm.c               |  298 ++++++++++++++++
- drivers/pwm/pwm.c                    |  643 ++++++++++++++++++++++++++++++++++
- 15 files changed, 3769 insertions(+)
- create mode 100644 Documentation/networking/adm6996.txt
- create mode 100644 Documentation/pwm.txt
- create mode 100644 arch/mips/fw/myloader/Makefile
- create mode 100644 arch/mips/fw/myloader/myloader.c
- create mode 100644 drivers/char/gpio_dev.c
- create mode 100644 drivers/input/misc/gpio_buttons.c
- create mode 100644 drivers/leds/ledtrig-morse.c
- create mode 100644 drivers/leds/ledtrig-netdev.c
- create mode 100644 drivers/leds/ledtrig-usbdev.c
- create mode 100644 drivers/mtd/myloader.c
- create mode 100644 drivers/pwm/Kconfig
- create mode 100644 drivers/pwm/Makefile
- create mode 100644 drivers/pwm/atmel-pwm.c
- create mode 100644 drivers/pwm/gpio-pwm.c
- create mode 100644 drivers/pwm/pwm.c
-
 diff --git a/Documentation/networking/adm6996.txt b/Documentation/networking/adm6996.txt
 new file mode 100644
 index 0000000..0fca549
@@ -173,271 +140,6 @@ index 0000000..0fca549
 +
 +  Controlling the mapping between MACs and PHYs is usually done in platform- or
 +  board-specific fixup code. The ADM6996 driver has no influence over this.
-diff --git a/Documentation/pwm.txt b/Documentation/pwm.txt
-new file mode 100644
-index 0000000..7112e66
---- /dev/null
-+++ b/Documentation/pwm.txt
-@@ -0,0 +1,259 @@
-+                       Generic PWM Device API
-+
-+                          February 1, 2010
-+                            Bill Gatliff
-+                        <bgat@billgatliff.com>
-+
-+
-+
-+The code in drivers/pwm and include/linux/pwm/ implements an API for
-+applications involving pulse-width-modulation signals.  This document
-+describes how the API implementation facilitates both PWM-generating
-+devices, and users of those devices.
-+
-+
-+
-+Motivation
-+
-+The primary goals for implementing the "generic PWM API" are to
-+consolidate the various PWM implementations within a consistent and
-+redundancy-reducing framework, and to facilitate the use of
-+hotpluggable PWM devices.
-+
-+Previous PWM-related implementations within the Linux kernel achieved
-+their consistency via cut-and-paste, but did not need to (and didn't)
-+facilitate more than one PWM-generating device within the system---
-+hotplug or otherwise.  The Generic PWM Device API might be most
-+appropriately viewed as an update to those implementations, rather
-+than a complete rewrite.
-+
-+
-+
-+Challenges
-+
-+One of the difficulties in implementing a generic PWM framework is the
-+fact that pulse-width-modulation applications involve real-world
-+signals, which often must be carefully managed to prevent destruction
-+of hardware that is linked to those signals.  A DC motor that
-+experiences a brief interruption in the PWM signal controlling it
-+might destructively overheat; it could suddenly change speed, losing
-+synchronization with a sensor; it could even suddenly change direction
-+or torque, breaking the mechanical device connected to it.
-+
-+(A generic PWM device framework is not directly responsible for
-+preventing the above scenarios: that responsibility lies with the
-+hardware designer, and the application and driver authors.  But it
-+must to the greatest extent possible make it easy to avoid such
-+problems).
-+
-+A generic PWM device framework must accommodate the substantial
-+differences between available PWM-generating hardware devices, without
-+becoming sub-optimal for any of them.
-+
-+Finally, a generic PWM device framework must be relatively
-+lightweight, computationally speaking.  Some PWM users demand
-+high-speed outputs, plus the ability to regulate those outputs
-+quickly.  A device framework must be able to "keep up" with such
-+hardware, while still leaving time to do real work.
-+
-+The Generic PWM Device API is an attempt to meet all of the above
-+requirements.  At its initial publication, the API was already in use
-+managing small DC motors, sensors and solenoids through a
-+custom-designed, optically-isolated H-bridge driver.
-+
-+
-+
-+Functional Overview
-+
-+The Generic PWM Device API framework is implemented in
-+include/linux/pwm/pwm.h and drivers/pwm/pwm.c.  The functions therein
-+use information from pwm_device, pwm_channel and pwm_channel_config
-+structures to invoke services in PWM peripheral device drivers.
-+Consult drivers/pwm/atmel-pwm.c for an example driver.
-+
-+There are two classes of adopters of the PWM framework:
-+
-+  "Users" -- those wishing to employ the API merely to produce PWM
-+  signals; once they have identified the appropriate physical output
-+  on the platform in question, they don't care about the details of
-+  the underlying hardware
-+
-+  "Driver authors" -- those wishing to bind devices that can generate
-+  PWM signals to the Generic PWM Device API, so that the services of
-+  those devices become available to users. Assuming the hardware can
-+  support the needs of a user, driver authors don't care about the
-+  details of the user's application
-+
-+Generally speaking, users will first invoke pwm_request() to obtain a
-+handle to a PWM device.  They will then pass that handle to functions
-+like pwm_duty_ns() and pwm_period_ns() to set the duty cycle and
-+period of the PWM signal, respectively.  They will also invoke
-+pwm_start() and pwm_stop() to turn the signal on and off.
-+
-+The Generic PWM API framework also provides a sysfs interface to PWM
-+devices, which is adequate for basic application needs and testing.
-+
-+Driver authors fill out a pwm_device structure, which describes the
-+capabilities of the PWM hardware being constructed--- including the
-+number of distinct output "channels" the peripheral offers.  They then
-+invoke pwm_register() (usually from within their device's probe()
-+handler) to make the PWM API aware of their device.  The framework
-+will call back to the methods described in the pwm_device structure as
-+users begin to configure and utilize the hardware.
-+
-+Note that PWM signals can be produced by a variety of peripherals,
-+beyond the true "PWM hardware" offered by many system-on-chip devices.
-+Other possibilities include timer/counters with compare-match
-+capabilities, carefully-programmed synchronous serial ports
-+(e.g. SPI), and GPIO pins driven by kernel interval timers.  With a
-+proper pwm_device structure, these devices and pseudo-devices can all
-+be accommodated by the Generic PWM Device API framework.
-+
-+
-+
-+Using the API to Generate PWM Signals -- Basic Functions for Users
-+
-+
-+pwm_request() -- Returns a pwm_channel pointer, which is subsequently
-+passed to the other user-related PWM functions.  Once requested, a PWM
-+channel is marked as in-use and subsequent requests prior to
-+pwm_free() will fail.
-+
-+The names used to refer to PWM devices are defined by driver authors.
-+Typically they are platform device bus identifiers, and this
-+convention is encouraged for consistency.
-+
-+
-+pwm_free() -- Marks a PWM channel as no longer in use.  The PWM device
-+is stopped before it is released by the API.
-+
-+
-+pwm_period_ns() -- Specifies the PWM signal's period, in nanoseconds.
-+
-+
-+pwm_duty_ns() -- Specifies the PWM signal's active duration, in nanoseconds.
-+
-+
-+pwm_duty_percent() -- Specifies the PWM signal's active duration, as a
-+percentage of the current period of the signal.  NOTE: this value is
-+not recalculated if the period of the signal is subsequently changed.
-+
-+
-+pwm_start(), pwm_stop() -- Turns the PWM signal on and off.  Except
-+where stated otherwise by a driver author, signals are stopped at the
-+end of the current period, at which time the output is set to its
-+inactive state.
-+
-+
-+pwm_polarity() -- Defines whether the PWM signal output's active
-+region is "1" or "0".  A 10% duty-cycle, polarity=1 signal will
-+conventionally be at 5V (or 3.3V, or 1000V, or whatever the platform
-+hardware does) for 10% of the period.  The same configuration of a
-+polarity=0 signal will be at 5V (or 3.3V, or ...) for 90% of the
-+period.
-+
-+
-+
-+Using the API to Generate PWM Signals -- Advanced Functions
-+
-+
-+pwm_config() -- Passes a pwm_channel_config structure to the
-+associated device driver.  This function is invoked by pwm_start(),
-+pwm_duty_ns(), etc. and is one of two main entry points to the PWM
-+driver for the hardware being used.  The configuration change is
-+guaranteed atomic if multiple configuration changes are specified.
-+This function might sleep, depending on what the device driver has to
-+do to satisfy the request.  All PWM device drivers must support this
-+entry point.
-+
-+
-+pwm_config_nosleep() -- Passes a pwm_channel_config structure to the
-+associated device driver.  If the driver must sleep in order to
-+implement the requested configuration change, -EWOULDBLOCK is
-+returned.  Users may call this function from interrupt handlers, for
-+example.  This is the other main entry point into the PWM hardware
-+driver, but not all device drivers support this entry point.
-+
-+
-+pwm_synchronize(), pwm_unsynchronize() -- "Synchronizes" two or more
-+PWM channels, if the underlying hardware permits.  (If it doesn't, the
-+framework facilitates emulating this capability but it is not yet
-+implemented).  Synchronized channels will start and stop
-+simultaneously when any single channel in the group is started or
-+stopped.  Use pwm_unsynchronize(..., NULL) to completely detach a
-+channel from any other synchronized channels.  By default, all PWM
-+channels are unsynchronized.
-+
-+
-+pwm_set_handler() -- Defines an end-of-period callback.  The indicated
-+function will be invoked in a worker thread at the end of each PWM
-+period, and can subsequently invoke pwm_config(), etc.  Must be used
-+with extreme care for high-speed PWM outputs.  Set the handler
-+function to NULL to un-set the handler.
-+
-+
-+
-+Implementing a PWM Device API Driver -- Functions for Driver Authors
-+
-+
-+Fill out the appropriate fields in a pwm_device structure, and submit
-+to pwm_register():
-+
-+
-+bus_id -- the plain-text name of the device.  Users will bind to a
-+channel on the device using this name plus the channel number.  For
-+example, the Atmel PWMC's bus_id is "atmel_pwmc", the same as used by
-+the platform device driver (recommended).  The first device registered
-+thereby receives bus_id "atmel_pwmc.0", which is what you put in
-+pwm_device.bus_id.  Channels are then named "atmel_pwmc.0:[0-3]".
-+(Hint: just use pdev->dev.bus_id in your probe() method).
-+
-+
-+nchan -- the number of distinct output channels provided by the device.
-+
-+
-+request -- (optional) Invoked each time a user requests a channel.
-+Use to turn on clocks, clean up register states, etc.  The framework
-+takes care of device locking/unlocking; you will see only successful
-+requests.
-+
-+
-+free -- (optional) Callback for each time a user relinquishes a
-+channel.  The framework will have already stopped, unsynchronized and
-+un-handled the channel.  Use to turn off clocks, etc. as necessary.
-+
-+
-+synchronize, unsynchronize -- (optional) Callbacks to
-+synchronize/unsynchronize channels.  Some devices provide this
-+capability in hardware; for others, it can be emulated (see
-+atmel_pwmc.c's sync_mask for an example).
-+
-+
-+set_callback -- (optional) Invoked when a user requests a handler.  If
-+the hardware supports an end-of-period interrupt, invoke the function
-+indicated during your interrupt handler.  The callback function itself
-+is always internal to the API, and does not map directly to the user's
-+callback function.
-+
-+
-+config -- Invoked to change the device configuration, always from a
-+sleep-capable context.  All the changes indicated must be performed
-+atomically, ideally synchronized to an end-of-period event (so that
-+you avoid short or long output pulses).  You may sleep, etc. as
-+necessary within this function.
-+
-+
-+config_nosleep -- (optional) Invoked to change device configuration
-+from within a context that is not allowed to sleep.  If you cannot
-+perform the requested configuration changes without sleeping, return
-+-EWOULDBLOCK.
-+
-+
-+
-+Acknowledgements
-+
-+
-+The author expresses his gratitude to the countless developers who
-+have reviewed and submitted feedback on the various versions of the
-+Generic PWM Device API code, and those who have submitted drivers and
-+applications that use the framework.  You know who you are.  ;)
 diff --git a/arch/mips/fw/myloader/Makefile b/arch/mips/fw/myloader/Makefile
 new file mode 100644
 index 0000000..34acfd0
@@ -2316,55 +2018,6 @@ index 0000000..a13752d
 +MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
 +MODULE_DESCRIPTION("Parsing code for MyLoader partition tables");
 +MODULE_LICENSE("GPL v2");
-diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
-new file mode 100644
-index 0000000..1c24e11
---- /dev/null
-+++ b/drivers/pwm/Kconfig
-@@ -0,0 +1,31 @@
-+#
-+# PWM infrastructure and devices
-+#
-+
-+menuconfig GENERIC_PWM
-+	tristate "PWM Support"
-+	depends on SYSFS
-+	help
-+	  This enables PWM support through the generic PWM library.
-+	  If unsure, say N.
-+
-+if GENERIC_PWM
-+
-+config ATMEL_PWM
-+	tristate "Atmel AT32/AT91 PWM support"
-+	depends on AVR32 || ARCH_AT91
-+	help
-+	  This option enables device driver support for the PWMC
-+	  peripheral channels found on certain Atmel processors.
-+	  Pulse Width Modulation is used many for purposes, including
-+	  software controlled power-efficient backlights on LCD
-+	  displays, motor control, and waveform generation.  If
-+	  unsure, say N.
-+
-+config GPIO_PWM
-+       tristate "PWM emulation using GPIO"
-+       help
-+         This option enables a single-channel PWM device using
-+	 a kernel interval timer and a GPIO pin.  If unsure, say N.
-+
-+endif
-diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
-new file mode 100644
-index 0000000..af22041
---- /dev/null
-+++ b/drivers/pwm/Makefile
-@@ -0,0 +1,6 @@
-+#
-+# Makefile for pwm devices
-+#
-+obj-$(CONFIG_GENERIC_PWM) := pwm.o
-+obj-$(CONFIG_ATMEL_PWM)		+= atmel-pwm.o
-+obj-$(CONFIG_GPIO_PWM)		+= gpio-pwm.o
 diff --git a/drivers/pwm/atmel-pwm.c b/drivers/pwm/atmel-pwm.c
 new file mode 100644
 index 0000000..158bb92
@@ -3916,6 +3569,3 @@ index 0000000..c1596e9
 +	return 0;
 +}
 +postcore_initcall(pwm_init);
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/routerstationpro.scc b/bsp/routerstationpro/routerstationpro.scc
index f37a4f2fd0911485b1e11d6dca433abcf008787f..356de125a36ac63af097a0ee8a643f07abab985d 100644
--- a/bsp/routerstationpro/routerstationpro.scc
+++ b/bsp/routerstationpro/routerstationpro.scc
@@ -10,7 +10,6 @@ patch remaining-generic-openwrt-files.patch
 patch openwrt-ar71xx-driver-files.patch
 patch openwrt-ar71xx-arch-mips-files.patch
 patch openwrt-include.patch
-patch spi-Dont-call-prepare-unprepare-transfer-if-not-popu.patch
 patch 102-ehci_hcd_ignore_oc.patch
 patch 309-mips_fuse_workaround.patch
 patch 400-rootfs_split.patch
@@ -35,95 +34,64 @@ patch 861-04_spi_gpio_implement_spi_delay.patch
 patch 862-gpio_spi_driver.patch
 patch 863-gpiommc.patch
 patch 864-gpiommc_configfs_locking.patch
-patch MIPS-ath79-separate-common-PCI-code.patch
-patch MIPS-ath79-rename-pci-ath724x.h.patch
-patch MIPS-ath79-make-ath724x_pcibios_init-visible-for-ext.patch
-patch MIPS-ath79-add-a-common-PCI-registration-function.patch
-patch MIPS-ath79-rename-pci-ath724x.c-to-make-it-reflect-t.patch
-patch MIPS-ath79-replace-ath724x-to-ar724x.patch
-patch MIPS-ath79-use-io-accessor-macros-in-pci-ar724x.c.patch
-patch MIPS-ath79-remove-superfluous-alignment-checks-from-.patch
-patch MIPS-ath79-fix-broken-ar724x_pci_-read-write-functio.patch
-patch MIPS-ath79-add-a-workaround-for-a-PCI-controller-bug.patch
-patch MIPS-ath79-fix-a-wrong-IRQ-number.patch
-patch MIPS-ath79-add-PCI-IRQ-handling-code-for-AR724X-SoCs.patch
-patch MIPS-ath79-get-rid-of-some-ifdefs-in-mach-ubnt-xm.c.patch
-patch MIPS-ath79-allow-to-use-board-specific-pci_plat_dev_.patch
-patch MIPS-ath79-add-support-for-the-PCI-host-controller-o.patch
-patch MIPS-ath79-allow-to-use-SoC-specific-PCI-IRQ-maps.patch
-patch MIPS-ath79-remove-ar724x_pci_add_data-function.patch
-patch MIPS-ath79-register-PCI-controller-on-the-PB44-board.patch
-patch MIPS-ath79-update-copyright-headers-of-PCI-related-f.patch
-patch MIPS-ath79-add-early_printk-support-for-AR934X.patch
-patch MIPS-ath79-sort-case-statements-in-ath79_detect_sys_.patch
-patch MIPS-ath79-add-SoC-detection-code-for-AR934X.patch
-patch MIPS-ath79-add-clock-initialization-code-for-AR934X.patch
-patch MIPS-ath79-add-GPIO-support-code-for-AR934X.patch
-patch MIPS-ath79-rework-IP2-IP3-interrupt-handling.patch
-patch MIPS-ath79-add-IRQ-handling-code-for-AR934X.patch
-patch MIPS-ath79-add-AR934X-specific-glue-to-ath79_device_.patch
-patch MIPS-ath79-register-UART-device-for-AR934X-SoCs.patch
-patch MIPS-ath79-add-WMAC-registration-code-for-AR934X.patch
-patch MIPS-ath79-add-PCI_AR724X-Kconfig-symbol.patch
-patch MIPS-ath79-add-PCI-registration-code-for-AR934X.patch
-patch MIPS-ath79-add-initial-support-for-the-Atheros-DB120.patch
-patch MIPS-ath79-use-correct-IRQ-number-for-the-OHCI-contr.patch
-patch MIPS-ath79-use-a-helper-function-for-USB-resource-in.patch
-patch MIPS-pci-ar724x-avoid-data-bus-error-due-to-a-missin.patch
-patch MIPS-pci-ar724x-use-correct-value-for-AR724X_PCI_MEM.patch
-patch MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch
-patch MIPS-pci-ar724x-convert-to-a-platform-driver.patch
-patch MIPS-pci-ar71xx-convert-to-a-platform-driver.patch
-patch MIPS-ath79-move-global-PCI-defines-into-a-common-hea.patch
-patch MIPS-ath79-register-platform-devices-for-the-PCI-con.patch
-patch MIPS-ath79-remove-unused-ar7-1x-24-x_pcibios_init-fu.patch
-patch MIPS-avoid-possible-resource-conflict-in-register_pc.patch
-patch MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch
-patch MIPS-pci-ar724x-remove-static-PCI-resources.patch
-patch MIPS-pci-ar724x-use-per-controller-IRQ-base.patch
-patch MIPS-pci-ar724x-setup-command-register-of-the-PCI-co.patch
-patch MIPS-pci-ar71xx-use-dynamically-allocated-PCI-contro.patch
-patch MIPS-pci-ar71xx-remove-static-PCI-controller-resourc.patch
-patch MIPS-ath79-allow-to-specify-bus-number-in-PCI-IRQ-ma.patch
-patch spi-ath79-add-delay-between-SCK-changes.patch
-patch spi-ath79-add-missing-HIGH-LOW-SCK-transition.patch
-patch spi-ath79-remove-superfluous-chip-select-code.patch
-patch spi-ath79-use-gpio_request_one.patch
-patch spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch
-patch spi-ath79-add-shutdown-handler.patch
-patch spi-ath79-make-chipselect-logic-more-flexible.patch
-patch 401-mtd-physmap-add-lock-unlock.patch
-patch 403-mtd_fix_cfi_cmdset_0002_status_check.patch
-patch 406-mtd-m25p80-allow-to-specify-max-read-size.patch
-patch 407-mtd-m25p80-allow-to-pass-probe-types-via-platfor.patch
-patch 408-mtd-redboot_partition_scan.patch
-patch 412-mtd-m25p80-zero-partition-parser-data.patch
-patch 420-net-ar71xx_mac_driver.patch
-patch 430-drivers-link-spi-before-mtd.patch
-patch 431-spi-add-various-flags.patch
-patch 434-spi-ap83_spi_controller.patch
-patch 460-spi-bitbang-export-spi_bitbang_bufs.patch
-patch 461-spi-add-type-field-to-spi_transfer.patch
-patch 462-mtd-m25p80-set-spi-transfer-type.patch
-patch 463-spi-ath79-add-fast-flash-read.patch
-patch 470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch
-patch 501-MIPS-ath79-add-mac-argument-to-ath79_register_wm.patch
-patch 502-MIPS-ath79-export-ath79_gpio_base.patch
-patch 503-MIPS-ath79-add-flash-acquire-release.patch
-patch 504-MIPS-ath79-add-ath79_device_reset_get.patch
-patch 505-MIPS-ath79-add-ath79_gpio_function_select.patch
-patch 506-MIPS-ath79-prom-parse-redboot-args.patch
-patch 507-MIPS-ath79-prom-add-myloader-support.patch
-patch 508-MIPS-ath79-prom-image-command-line-hack.patch
-patch 509-MIPS-ath79-process-board-kernel-option.patch
-patch 510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch
-patch 511-MIPS-ath79-add-ath79_set_usb_power_gpio.patch
-patch 520-MIPS-ath79-enable-UART-function.patch
-patch 521-MIPS-ath79-enable-UART-for-early_serial.patch
-patch 601-MIPS-ath79-add-more-register-defines.patch
-patch 602-MIPS-ath79-add-openwrt-stuff.patch
-patch 607-MIPS-ath79-ubnt-xm-fixes.patch
-patch 608-MIPS-ath79-ubnt-xm-add-more-boards.patch
-patch 610-MIPS-ath79-openwrt-machines.patch
-patch ar71xx-fixups-for-not-carrying-QCA-platform.patch
-patch ath79-fixup-for-not-carrying-Ubiquiti-LSX-LSS.patch
+
+# The following patches are pending uprev:
+
+# patch MIPS-ath79-use-a-helper-function-for-USB-resource-in.patch
+# patch MIPS-pci-ar724x-avoid-data-bus-error-due-to-a-missin.patch
+# patch MIPS-pci-ar724x-use-correct-value-for-AR724X_PCI_MEM.patch
+# patch MIPS-pci-ar71xx-fix-AR71XX_PCI_MEM_SIZE.patch
+# patch MIPS-pci-ar724x-convert-to-a-platform-driver.patch
+# patch MIPS-pci-ar71xx-convert-to-a-platform-driver.patch
+# patch MIPS-ath79-move-global-PCI-defines-into-a-common-hea.patch
+# patch MIPS-ath79-register-platform-devices-for-the-PCI-con.patch
+# patch MIPS-ath79-remove-unused-ar7-1x-24-x_pcibios_init-fu.patch
+# patch MIPS-avoid-possible-resource-conflict-in-register_pc.patch
+# patch MIPS-pci-ar724x-use-dynamically-allocated-PCI-contro.patch
+# patch MIPS-pci-ar724x-remove-static-PCI-resources.patch
+# patch MIPS-pci-ar724x-use-per-controller-IRQ-base.patch
+# patch MIPS-pci-ar724x-setup-command-register-of-the-PCI-co.patch
+# patch MIPS-pci-ar71xx-use-dynamically-allocated-PCI-contro.patch
+# patch MIPS-pci-ar71xx-remove-static-PCI-controller-resourc.patch
+# patch MIPS-ath79-allow-to-specify-bus-number-in-PCI-IRQ-ma.patch
+# patch spi-ath79-add-delay-between-SCK-changes.patch
+# patch spi-ath79-add-missing-HIGH-LOW-SCK-transition.patch
+# patch spi-ath79-use-gpio_request_one.patch
+# patch spi-ath79-avoid-multiple-initialization-of-the-SPI-c.patch
+# patch spi-ath79-add-shutdown-handler.patch
+# patch spi-ath79-make-chipselect-logic-more-flexible.patch
+# patch 401-mtd-physmap-add-lock-unlock.patch
+# patch 403-mtd_fix_cfi_cmdset_0002_status_check.patch
+# patch 406-mtd-m25p80-allow-to-specify-max-read-size.patch
+# patch 407-mtd-m25p80-allow-to-pass-probe-types-via-platfor.patch
+# patch 408-mtd-redboot_partition_scan.patch
+# patch 412-mtd-m25p80-zero-partition-parser-data.patch
+# patch 420-net-ar71xx_mac_driver.patch
+# patch 430-drivers-link-spi-before-mtd.patch
+# patch 431-spi-add-various-flags.patch
+# patch 434-spi-ap83_spi_controller.patch
+# patch 460-spi-bitbang-export-spi_bitbang_bufs.patch
+# patch 461-spi-add-type-field-to-spi_transfer.patch
+# patch 462-mtd-m25p80-set-spi-transfer-type.patch
+# patch 463-spi-ath79-add-fast-flash-read.patch
+# patch 470-MIPS-ath79-swizzle-pci-address-for-ar71xx.patch
+# patch 501-MIPS-ath79-add-mac-argument-to-ath79_register_wm.patch
+# patch 502-MIPS-ath79-export-ath79_gpio_base.patch
+# patch 503-MIPS-ath79-add-flash-acquire-release.patch
+# patch 504-MIPS-ath79-add-ath79_device_reset_get.patch
+# patch 505-MIPS-ath79-add-ath79_gpio_function_select.patch
+# patch 506-MIPS-ath79-prom-parse-redboot-args.patch
+# patch 507-MIPS-ath79-prom-add-myloader-support.patch
+# patch 508-MIPS-ath79-prom-image-command-line-hack.patch
+# patch 509-MIPS-ath79-process-board-kernel-option.patch
+# patch 510-MIPS-ath79-init-gpio-pin-of-wmac-device.patch
+# patch 511-MIPS-ath79-add-ath79_set_usb_power_gpio.patch
+# patch 520-MIPS-ath79-enable-UART-function.patch
+# patch 521-MIPS-ath79-enable-UART-for-early_serial.patch
+# patch 601-MIPS-ath79-add-more-register-defines.patch
+# patch 602-MIPS-ath79-add-openwrt-stuff.patch
+# patch 607-MIPS-ath79-ubnt-xm-fixes.patch
+# patch 608-MIPS-ath79-ubnt-xm-add-more-boards.patch
+# patch 610-MIPS-ath79-openwrt-machines.patch
+# patch ar71xx-fixups-for-not-carrying-QCA-platform.patch
+# patch ath79-fixup-for-not-carrying-Ubiquiti-LSX-LSS.patch
diff --git a/bsp/routerstationpro/spi-Dont-call-prepare-unprepare-transfer-if-not-popu.patch b/bsp/routerstationpro/spi-Dont-call-prepare-unprepare-transfer-if-not-popu.patch
deleted file mode 100644
index d303fd6326b0e2cf5b687b82e4d7f350facf08ee..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/spi-Dont-call-prepare-unprepare-transfer-if-not-popu.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 000e617c0f2ed18b4323a89a72a60f51f9a4ac43 Mon Sep 17 00:00:00 2001
-From: Shubhrajyoti D <shubhrajyoti@ti.com>
-Date: Thu, 10 May 2012 19:20:41 +0530
-Subject: [PATCH 007/123] spi: Dont call prepare/unprepare transfer if not
- populated
-
-Currently the prepare/unprepare transfer are called unconditionally.
-The assumption is that every driver using the spi core queue infrastructure
-has to populate the prepare and unprepare functions. This encourages
-drivers to populate empty functions to prevent crashing.
-This patch prevents the call to prepare/unprepare if not populated.
-
-Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
-Acked-by: Linus Walleij <linus.walleij@linaro.org>
-[grant.likely: fix whitespace defect]
-Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- drivers/spi/spi.c |    4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
-index 3d8f662..11e4d7f 100644
---- a/drivers/spi/spi.c
-+++ b/drivers/spi/spi.c
-@@ -530,7 +530,7 @@ static void spi_pump_messages(struct kthread_work *work)
- 	/* Lock queue and check for queue work */
- 	spin_lock_irqsave(&master->queue_lock, flags);
- 	if (list_empty(&master->queue) || !master->running) {
--		if (master->busy) {
-+		if (master->busy && master->unprepare_transfer_hardware) {
- 			ret = master->unprepare_transfer_hardware(master);
- 			if (ret) {
- 				spin_unlock_irqrestore(&master->queue_lock, flags);
-@@ -560,7 +560,7 @@ static void spi_pump_messages(struct kthread_work *work)
- 		master->busy = true;
- 	spin_unlock_irqrestore(&master->queue_lock, flags);
- 
--	if (!was_busy) {
-+	if (!was_busy && master->prepare_transfer_hardware) {
- 		ret = master->prepare_transfer_hardware(master);
- 		if (ret) {
- 			dev_err(&master->dev,
--- 
-1.7.9.7
-
diff --git a/bsp/routerstationpro/spi-ath79-remove-superfluous-chip-select-code.patch b/bsp/routerstationpro/spi-ath79-remove-superfluous-chip-select-code.patch
deleted file mode 100644
index ac054f1c2589faa797b16683c0d4e7a629ddb4c4..0000000000000000000000000000000000000000
--- a/bsp/routerstationpro/spi-ath79-remove-superfluous-chip-select-code.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 8bccd4f5a2394ac1312ba5be0a2e84fd8aa2195a Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Mon, 9 Jan 2012 15:03:28 +0100
-Subject: [PATCH 084/123] spi/ath79: remove superfluous chip select code
-
-The spi_bitbang driver calls the chipselect function
-of the driver from spi_bitbang_setup in order to
-deselect the given SPI chip, so we don't have to
-initialize the CS line here.
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
-Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
----
- drivers/spi/spi-ath79.c |    6 ------
- 1 file changed, 6 deletions(-)
-
-diff --git a/drivers/spi/spi-ath79.c b/drivers/spi/spi-ath79.c
-index 2478cc2..864c40d 100644
---- a/drivers/spi/spi-ath79.c
-+++ b/drivers/spi/spi-ath79.c
-@@ -128,12 +128,6 @@ static int ath79_spi_setup_cs(struct spi_device *spi)
- 			gpio_free(cdata->gpio);
- 			return status;
- 		}
--	} else {
--		if (spi->mode & SPI_CS_HIGH)
--			sp->ioc_base |= AR71XX_SPI_IOC_CS0;
--		else
--			sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
--		ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
- 	}
- 
- 	return 0;
--- 
-1.7.9.7
-
diff --git a/features/unionfs/unionfs-introduce-unionfs-2.5.10-core-support.patch b/features/unionfs/unionfs-introduce-unionfs-2.5.10-core-support.patch
index 895357f348a0928dcae496fff3615c4b670c7bae..c2bf188bf4290364bc93aec1f5183b4e4dd0f088 100644
--- a/features/unionfs/unionfs-introduce-unionfs-2.5.10-core-support.patch
+++ b/features/unionfs/unionfs-introduce-unionfs-2.5.10-core-support.patch
@@ -540,12 +540,12 @@ index 0000000..1adde69
 +
 +For more information, see <http://unionfs.filesystems.org/>.
 diff --git a/MAINTAINERS b/MAINTAINERS
-index 3d11fa5..45b08c4 100644
+index fdc0119..91cc98a 100644
 --- a/MAINTAINERS
 +++ b/MAINTAINERS
-@@ -6868,6 +6868,14 @@ F:	Documentation/cdrom/
- F:	drivers/cdrom/cdrom.c
- F:	include/linux/cdrom.h
+@@ -7065,6 +7065,14 @@ S:	Supported
+ F:	Documentation/scsi/ufs.txt
+ F:	drivers/scsi/ufs/
  
 +UNIONFS
 +P:	Erez Zadok
@@ -583,19 +583,19 @@ index 79b94eb..d094e94 100644
  obj-$(CONFIG_NFS_FS)		+= nfs/
  obj-$(CONFIG_EXPORTFS)		+= exportfs/
 diff --git a/fs/namei.c b/fs/namei.c
-index e615ff3..e27d250 100644
+index dd1ed1b..5e71f1b 100644
 --- a/fs/namei.c
 +++ b/fs/namei.c
-@@ -491,6 +491,7 @@ void release_open_intent(struct nameidata *nd)
- 			fput(file);
- 	}
+@@ -506,6 +506,7 @@ err_root:
+ 		spin_unlock(&fs->lock);
+ 	return -ECHILD;
  }
 +EXPORT_SYMBOL_GPL(release_open_intent);
  
- static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd)
+ static inline int d_revalidate(struct dentry *dentry, unsigned int flags)
  {
-@@ -1951,6 +1952,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
- 	return __lookup_hash(&this, base, NULL);
+@@ -2098,6 +2099,42 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
+ 	return __lookup_hash(&this, base, 0);
  }
  
 +/* pass nameidata from caller (useful for NFS) */
@@ -637,7 +637,7 @@ index e615ff3..e27d250 100644
  int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
  		 struct path *path, int *empty)
  {
-@@ -3544,6 +3581,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
+@@ -3975,6 +4012,7 @@ EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
  EXPORT_SYMBOL(getname);
  EXPORT_SYMBOL(lock_rename);
  EXPORT_SYMBOL(lookup_one_len);
@@ -646,10 +646,10 @@ index e615ff3..e27d250 100644
  EXPORT_SYMBOL(page_put_link);
  EXPORT_SYMBOL(page_readlink);
 diff --git a/fs/splice.c b/fs/splice.c
-index 5f883de..59972c8 100644
+index 41514dd..aae192a 100644
 --- a/fs/splice.c
 +++ b/fs/splice.c
-@@ -1081,8 +1081,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
+@@ -1093,8 +1093,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
  /*
   * Attempt to initiate a splice from pipe to file.
   */
@@ -660,7 +660,7 @@ index 5f883de..59972c8 100644
  {
  	ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,
  				loff_t *, size_t, unsigned int);
-@@ -1105,13 +1105,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+@@ -1117,13 +1117,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
  
  	return splice_write(pipe, out, ppos, len, flags);
  }
@@ -678,7 +678,7 @@ index 5f883de..59972c8 100644
  {
  	ssize_t (*splice_read)(struct file *, loff_t *,
  			       struct pipe_inode_info *, size_t, unsigned int);
-@@ -1131,6 +1132,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
+@@ -1143,6 +1144,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
  
  	return splice_read(in, ppos, pipe, len, flags);
  }
@@ -686,7 +686,7 @@ index 5f883de..59972c8 100644
  
  /**
   * splice_direct_to_actor - splices data directly between two non-pipes
-@@ -1200,7 +1202,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
+@@ -1212,7 +1214,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
  		size_t read_len;
  		loff_t pos = sd->pos, prev_pos = pos;
  
@@ -695,7 +695,7 @@ index 5f883de..59972c8 100644
  		if (unlikely(ret <= 0))
  			goto out_release;
  
-@@ -1259,8 +1261,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
+@@ -1271,8 +1273,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
  {
  	struct file *file = sd->u.file;
  
@@ -706,7 +706,7 @@ index 5f883de..59972c8 100644
  }
  
  /**
-@@ -1345,7 +1347,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+@@ -1357,7 +1359,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
  		} else
  			off = &out->f_pos;
  
@@ -715,7 +715,7 @@ index 5f883de..59972c8 100644
  
  		if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
  			ret = -EFAULT;
-@@ -1365,7 +1367,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
+@@ -1377,7 +1379,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
  		} else
  			off = &in->f_pos;
  
@@ -11337,13 +11337,13 @@ index e15192c..1d7370b 100644
  #define CGROUP_SUPER_MAGIC	0x27e0eb
  
 diff --git a/include/linux/namei.h b/include/linux/namei.h
-index ffc0213..99802c3 100644
+index 4bf19d8..d9d775c 100644
 --- a/include/linux/namei.h
 +++ b/include/linux/namei.h
-@@ -84,8 +84,11 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
- 
- extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
- 		int (*open)(struct inode *, struct file *));
+@@ -71,8 +71,11 @@ extern void done_path_create(struct path *, struct dentry *);
+ extern struct dentry *kern_path_locked(const char *, struct path *);
+ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
+ 			   const char *, unsigned int, struct path *);
 +extern void release_open_intent(struct nameidata *);
  
  extern struct dentry *lookup_one_len(const char *, struct dentry *, int);
@@ -11353,10 +11353,10 @@ index ffc0213..99802c3 100644
  extern int follow_down_one(struct path *);
  extern int follow_down(struct path *);
 diff --git a/include/linux/splice.h b/include/linux/splice.h
-index 26e5b61..28213e6 100644
+index 09a545a..ebe231a 100644
 --- a/include/linux/splice.h
 +++ b/include/linux/splice.h
-@@ -81,6 +81,11 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
+@@ -82,6 +82,11 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
  			      struct splice_pipe_desc *);
  extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
  				      splice_direct_actor *);
@@ -11397,10 +11397,10 @@ index 0000000..c84d97e
 +#endif /* _LINUX_UNIONFS_H */
 +
 diff --git a/security/security.c b/security/security.c
-index bf619ff..57742c6 100644
+index 860aeb3..efe2b05 100644
 --- a/security/security.c
 +++ b/security/security.c
-@@ -526,6 +526,7 @@ int security_inode_permission(struct inode *inode, int mask)
+@@ -530,6 +530,7 @@ int security_inode_permission(struct inode *inode, int mask)
  		return 0;
  	return security_ops->inode_permission(inode, mask);
  }
diff --git a/features/uprobe/On-RISC-architectures-like-powerpc-instructions-are-.patch b/features/uprobe/On-RISC-architectures-like-powerpc-instructions-are-.patch
deleted file mode 100644
index dc3c97a679961f2c9fb89a6bfaa378f83d4b1469..0000000000000000000000000000000000000000
--- a/features/uprobe/On-RISC-architectures-like-powerpc-instructions-are-.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 2bc4597fbf93953222c5e9445472113e7b4bba03 Mon Sep 17 00:00:00 2001
-From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Date: Wed, 13 Jun 2012 10:43:40 -0400
-Subject: [PATCH 22/24] On RISC architectures like powerpc, instructions are
- fixed size. Instruction analysis on such platforms is
- just a matter of (insn % 4). Pass the vaddr at which
- the uprobe is to be inserted so that
- arch_uprobe_analyze_insn() can flag misaligned
- registration requests.
-
-Changes in V2:
-Pass (unsigned long)addr instead of (loff_t)vaddr to
-arch_uprobe_analyze_insn(). We need the loff_t vaddr to take care of
-the offset of inode:offset pair for large file sizes on 32bit.
-
-Link: https://lkml.org/lkml/2012/6/6/139
-
-Signed-off-by: Ananth N Mavinakaynahalli <ananth@in.ibm.com>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/include/asm/uprobes.h |    2 +-
- arch/x86/kernel/uprobes.c      |    3 ++-
- kernel/events/uprobes.c        |    2 +-
- 3 files changed, 4 insertions(+), 3 deletions(-)
-
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index 1e9bed1..f3971bb 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -48,7 +48,7 @@ struct arch_uprobe_task {
- #endif
- };
- 
--extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm);
-+extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
- extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
- extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
- extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index dc4e910..36fd420 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -409,9 +409,10 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm,
-  * arch_uprobe_analyze_insn - instruction analysis including validity and fixups.
-  * @mm: the probed address space.
-  * @arch_uprobe: the probepoint information.
-+ * @addr: virtual address at which to install the probepoint
-  * Return 0 on success or a -ve number on error.
-  */
--int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm)
-+int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr)
- {
- 	int ret;
- 	struct insn insn;
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 985be4d..577f717 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -697,7 +697,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- 		if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
- 			return -EEXIST;
- 
--		ret = arch_uprobe_analyze_insn(&uprobe->arch, mm);
-+		ret = arch_uprobe_analyze_insn(&uprobe->arch, mm, addr);
- 		if (ret)
- 			return ret;
- 
--- 
-1.7.5.4
-
diff --git a/features/uprobe/genirq-reimplement-exit_irq_thread-hook-via-task_wor.patch b/features/uprobe/genirq-reimplement-exit_irq_thread-hook-via-task_wor.patch
deleted file mode 100644
index a11d0bfaa9a0449bfc828113fcf58791cc2a867d..0000000000000000000000000000000000000000
--- a/features/uprobe/genirq-reimplement-exit_irq_thread-hook-via-task_wor.patch
+++ /dev/null
@@ -1,228 +0,0 @@
-From 61bc7a87e8aa5b5651c21e8d9f76dea814fe5313 Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Fri, 11 May 2012 10:59:08 +1000
-Subject: [PATCH 3/6] genirq: reimplement exit_irq_thread() hook via
- task_work_add()
-
-commit 4d1d61a6b203d957777d73fcebf19d90b038b5b2 upstream.
-
-exit_irq_thread() and task->irq_thread are needed to handle the unexpected
-(and unlikely) exit of irq-thread.
-
-We can use task_work instead and make this all private to
-kernel/irq/manage.c, cleanup plus micro-optimization.
-
-1. rename exit_irq_thread() to irq_thread_dtor(), make it
-   static, and move it up before irq_thread().
-
-2. change irq_thread() to do task_work_add(irq_thread_dtor)
-   at the start and task_work_cancel() before return.
-
-   tracehook_notify_resume() can never play with kthreads,
-   only do_exit()->exit_task_work() can call the callback
-   and this is what we want.
-
-3. remove task_struct->irq_thread and the special hook
-   in do_exit().
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
-Cc: David Howells <dhowells@redhat.com>
-Cc: Richard Kuo <rkuo@codeaurora.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Alexander Gordeev <agordeev@redhat.com>
-Cc: Chris Zankel <chris@zankel.net>
-Cc: David Smith <dsmith@redhat.com>
-Cc: "Frank Ch. Eigler" <fche@redhat.com>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: Larry Woodman <lwoodman@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/interrupt.h |    4 --
- include/linux/sched.h     |   10 +-----
- kernel/exit.c             |    2 -
- kernel/irq/manage.c       |   69 +++++++++++++++++++++-----------------------
- 4 files changed, 35 insertions(+), 50 deletions(-)
-
-diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
-index 2aea5d2..1cdd4d0 100644
---- a/include/linux/interrupt.h
-+++ b/include/linux/interrupt.h
-@@ -142,8 +142,6 @@ request_any_context_irq(unsigned int irq, irq_handler_t handler,
- extern int __must_check
- request_percpu_irq(unsigned int irq, irq_handler_t handler,
- 		   const char *devname, void __percpu *percpu_dev_id);
--
--extern void exit_irq_thread(void);
- #else
- 
- extern int __must_check
-@@ -177,8 +175,6 @@ request_percpu_irq(unsigned int irq, irq_handler_t handler,
- {
- 	return request_irq(irq, handler, 0, devname, percpu_dev_id);
- }
--
--static inline void exit_irq_thread(void) { }
- #endif
- 
- extern void free_irq(unsigned int, void *);
-diff --git a/include/linux/sched.h b/include/linux/sched.h
-index d62c928..3ea394c 100644
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -1348,11 +1348,6 @@ struct task_struct {
- 	unsigned sched_reset_on_fork:1;
- 	unsigned sched_contributes_to_load:1;
- 
--#ifdef CONFIG_GENERIC_HARDIRQS
--	/* IRQ handler threads */
--	unsigned irq_thread:1;
--#endif
--
- 	pid_t pid;
- 	pid_t tgid;
- 
-@@ -1360,10 +1355,9 @@ struct task_struct {
- 	/* Canary value for the -fstack-protector gcc feature */
- 	unsigned long stack_canary;
- #endif
--
--	/* 
-+	/*
- 	 * pointers to (original) parent process, youngest child, younger sibling,
--	 * older sibling, respectively.  (p->father can be replaced with 
-+	 * older sibling, respectively.  (p->father can be replaced with
- 	 * p->real_parent->pid)
- 	 */
- 	struct task_struct __rcu *real_parent; /* real parent process */
-diff --git a/kernel/exit.c b/kernel/exit.c
-index 36516fc..275013c 100644
---- a/kernel/exit.c
-+++ b/kernel/exit.c
-@@ -955,8 +955,6 @@ void do_exit(long code)
- 
- 	exit_task_work(tsk);
- 
--	exit_irq_thread();
--
- 	if (unlikely(in_atomic()))
- 		printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
- 				current->comm, task_pid_nr(current),
-diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
-index 89a3ea8..ac4dab7 100644
---- a/kernel/irq/manage.c
-+++ b/kernel/irq/manage.c
-@@ -14,6 +14,7 @@
- #include <linux/interrupt.h>
- #include <linux/slab.h>
- #include <linux/sched.h>
-+#include <linux/task_work.h>
- 
- #include "internals.h"
- 
-@@ -773,11 +774,39 @@ static void wake_threads_waitq(struct irq_desc *desc)
- 		wake_up(&desc->wait_for_threads);
- }
- 
-+static void irq_thread_dtor(struct task_work *unused)
-+{
-+	struct task_struct *tsk = current;
-+	struct irq_desc *desc;
-+	struct irqaction *action;
-+
-+	if (WARN_ON_ONCE(!(current->flags & PF_EXITING)))
-+		return;
-+
-+	action = kthread_data(tsk);
-+
-+	pr_err("genirq: exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n",
-+	       tsk->comm ? tsk->comm : "", tsk->pid, action->irq);
-+
-+
-+	desc = irq_to_desc(action->irq);
-+	/*
-+	 * If IRQTF_RUNTHREAD is set, we need to decrement
-+	 * desc->threads_active and wake possible waiters.
-+	 */
-+	if (test_and_clear_bit(IRQTF_RUNTHREAD, &action->thread_flags))
-+		wake_threads_waitq(desc);
-+
-+	/* Prevent a stale desc->threads_oneshot */
-+	irq_finalize_oneshot(desc, action);
-+}
-+
- /*
-  * Interrupt handler thread
-  */
- static int irq_thread(void *data)
- {
-+	struct task_work on_exit_work;
- 	static const struct sched_param param = {
- 		.sched_priority = MAX_USER_RT_PRIO/2,
- 	};
-@@ -793,7 +822,9 @@ static int irq_thread(void *data)
- 		handler_fn = irq_thread_fn;
- 
- 	sched_setscheduler(current, SCHED_FIFO, &param);
--	current->irq_thread = 1;
-+
-+	init_task_work(&on_exit_work, irq_thread_dtor, NULL);
-+	task_work_add(current, &on_exit_work, false);
- 
- 	while (!irq_wait_for_interrupt(action)) {
- 		irqreturn_t action_ret;
-@@ -815,45 +846,11 @@ static int irq_thread(void *data)
- 	 * cannot touch the oneshot mask at this point anymore as
- 	 * __setup_irq() might have given out currents thread_mask
- 	 * again.
--	 *
--	 * Clear irq_thread. Otherwise exit_irq_thread() would make
--	 * fuzz about an active irq thread going into nirvana.
- 	 */
--	current->irq_thread = 0;
-+	task_work_cancel(current, irq_thread_dtor);
- 	return 0;
- }
- 
--/*
-- * Called from do_exit()
-- */
--void exit_irq_thread(void)
--{
--	struct task_struct *tsk = current;
--	struct irq_desc *desc;
--	struct irqaction *action;
--
--	if (!tsk->irq_thread)
--		return;
--
--	action = kthread_data(tsk);
--
--	printk(KERN_ERR
--	       "exiting task \"%s\" (%d) is an active IRQ thread (irq %d)\n",
--	       tsk->comm ? tsk->comm : "", tsk->pid, action->irq);
--
--	desc = irq_to_desc(action->irq);
--
--	/*
--	 * If IRQTF_RUNTHREAD is set, we need to decrement
--	 * desc->threads_active and wake possible waiters.
--	 */
--	if (test_and_clear_bit(IRQTF_RUNTHREAD, &action->thread_flags))
--		wake_threads_waitq(desc);
--
--	/* Prevent a stale desc->threads_oneshot */
--	irq_finalize_oneshot(desc, action);
--}
--
- static void irq_setup_forced_threading(struct irqaction *new)
- {
- 	if (!force_irqthreads)
--- 
-1.7.5.4
-
diff --git a/features/uprobe/keys-change-keyctl_session_to_parent-to-use-task_wor.patch b/features/uprobe/keys-change-keyctl_session_to_parent-to-use-task_wor.patch
deleted file mode 100644
index a32e83855a883d6b4343e4edf1bc026f59b87218..0000000000000000000000000000000000000000
--- a/features/uprobe/keys-change-keyctl_session_to_parent-to-use-task_wor.patch
+++ /dev/null
@@ -1,264 +0,0 @@
-From 090ca453c4d5b4e1300c46daf1ac4f2a5f086ec1 Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Fri, 11 May 2012 10:59:08 +1000
-Subject: [PATCH 4/6] keys: change keyctl_session_to_parent() to use
- task_work_add()
-
-commit 413cd3d9abeaef590e5ce00564f7a443165db238 upstream.
-
-Change keyctl_session_to_parent() to use task_work_add() and move
-key_replace_session_keyring() logic into task_work->func().
-
-Note that we do task_work_cancel() before task_work_add() to ensure that
-only one work can be pending at any time.  This is important, we must not
-allow user-space to abuse the parent's ->task_works list.
-
-The callback, replace_session_keyring(), checks PF_EXITING.  I guess this
-is not really needed but looks better.
-
-As a side effect, this fixes the (unlikely) race.  The callers of
-key_replace_session_keyring() and keyctl_session_to_parent() lack the
-necessary barriers, the parent can miss the request.
-
-Now we can remove task_struct->replacement_session_keyring and related
-code.
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Acked-by: David Howells <dhowells@redhat.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Richard Kuo <rkuo@codeaurora.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Alexander Gordeev <agordeev@redhat.com>
-Cc: Chris Zankel <chris@zankel.net>
-Cc: David Smith <dsmith@redhat.com>
-Cc: "Frank Ch. Eigler" <fche@redhat.com>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: Larry Woodman <lwoodman@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/key.h          |    6 +--
- security/keys/internal.h     |    2 +
- security/keys/keyctl.c       |   63 +++++++++++++++++++++++------------------
- security/keys/process_keys.c |   20 ++++--------
- 4 files changed, 46 insertions(+), 45 deletions(-)
-
-diff --git a/include/linux/key.h b/include/linux/key.h
-index 96933b1..0c263d6 100644
---- a/include/linux/key.h
-+++ b/include/linux/key.h
-@@ -33,6 +33,8 @@ typedef uint32_t key_perm_t;
- 
- struct key;
- 
-+#define key_replace_session_keyring()	do { } while (0)
-+
- #ifdef CONFIG_KEYS
- 
- #undef KEY_DEBUGGING
-@@ -302,9 +304,6 @@ static inline bool key_is_instantiated(const struct key *key)
- #ifdef CONFIG_SYSCTL
- extern ctl_table key_sysctls[];
- #endif
--
--extern void key_replace_session_keyring(void);
--
- /*
-  * the userspace interface
-  */
-@@ -327,7 +326,6 @@ extern void key_init(void);
- #define key_fsuid_changed(t)		do { } while(0)
- #define key_fsgid_changed(t)		do { } while(0)
- #define key_init()			do { } while(0)
--#define key_replace_session_keyring()	do { } while(0)
- 
- #endif /* CONFIG_KEYS */
- #endif /* __KERNEL__ */
-diff --git a/security/keys/internal.h b/security/keys/internal.h
-index 65647f8..c2986da 100644
---- a/security/keys/internal.h
-+++ b/security/keys/internal.h
-@@ -14,6 +14,7 @@
- 
- #include <linux/sched.h>
- #include <linux/key-type.h>
-+#include <linux/task_work.h>
- 
- #ifdef __KDEBUG
- #define kenter(FMT, ...) \
-@@ -148,6 +149,7 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
- #define KEY_LOOKUP_FOR_UNLINK	0x04
- 
- extern long join_session_keyring(const char *name);
-+extern void key_change_session_keyring(struct task_work *twork);
- 
- extern struct work_struct key_gc_work;
- extern unsigned key_gc_delay;
-diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
-index fb767c6..a237e03 100644
---- a/security/keys/keyctl.c
-+++ b/security/keys/keyctl.c
-@@ -1426,47 +1426,55 @@ long keyctl_session_to_parent(void)
- #ifdef TIF_NOTIFY_RESUME
- 	struct task_struct *me, *parent;
- 	const struct cred *mycred, *pcred;
--	struct cred *cred, *oldcred;
-+	struct task_work *newwork, *oldwork;
- 	key_ref_t keyring_r;
-+	struct cred *cred;
- 	int ret;
- 
- 	keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK);
- 	if (IS_ERR(keyring_r))
- 		return PTR_ERR(keyring_r);
- 
-+	ret = -ENOMEM;
-+	newwork = kmalloc(sizeof(struct task_work), GFP_KERNEL);
-+	if (!newwork)
-+		goto error_keyring;
-+
- 	/* our parent is going to need a new cred struct, a new tgcred struct
- 	 * and new security data, so we allocate them here to prevent ENOMEM in
- 	 * our parent */
--	ret = -ENOMEM;
- 	cred = cred_alloc_blank();
- 	if (!cred)
--		goto error_keyring;
-+		goto error_newwork;
- 
- 	cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r);
--	keyring_r = NULL;
-+	init_task_work(newwork, key_change_session_keyring, cred);
- 
- 	me = current;
- 	rcu_read_lock();
- 	write_lock_irq(&tasklist_lock);
- 
--	parent = me->real_parent;
- 	ret = -EPERM;
-+	oldwork = NULL;
-+	parent = me->real_parent;
- 
- 	/* the parent mustn't be init and mustn't be a kernel thread */
- 	if (parent->pid <= 1 || !parent->mm)
--		goto not_permitted;
-+		goto unlock;
- 
- 	/* the parent must be single threaded */
- 	if (!thread_group_empty(parent))
--		goto not_permitted;
-+		goto unlock;
- 
- 	/* the parent and the child must have different session keyrings or
- 	 * there's no point */
- 	mycred = current_cred();
- 	pcred = __task_cred(parent);
- 	if (mycred == pcred ||
--	    mycred->tgcred->session_keyring == pcred->tgcred->session_keyring)
--		goto already_same;
-+	    mycred->tgcred->session_keyring == pcred->tgcred->session_keyring) {
-+		ret = 0;
-+		goto unlock;
-+	}
- 
- 	/* the parent must have the same effective ownership and mustn't be
- 	 * SUID/SGID */
-@@ -1476,38 +1484,37 @@ long keyctl_session_to_parent(void)
- 	    pcred->gid	!= mycred->egid	||
- 	    pcred->egid	!= mycred->egid	||
- 	    pcred->sgid	!= mycred->egid)
--		goto not_permitted;
-+		goto unlock;
- 
- 	/* the keyrings must have the same UID */
- 	if ((pcred->tgcred->session_keyring &&
- 	     pcred->tgcred->session_keyring->uid != mycred->euid) ||
- 	    mycred->tgcred->session_keyring->uid != mycred->euid)
--		goto not_permitted;
-+		goto unlock;
- 
--	/* if there's an already pending keyring replacement, then we replace
--	 * that */
--	oldcred = parent->replacement_session_keyring;
-+	/* cancel an already pending keyring replacement */
-+	oldwork = task_work_cancel(parent, key_change_session_keyring);
- 
- 	/* the replacement session keyring is applied just prior to userspace
- 	 * restarting */
--	parent->replacement_session_keyring = cred;
--	cred = NULL;
--	set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME);
--
--	write_unlock_irq(&tasklist_lock);
--	rcu_read_unlock();
--	if (oldcred)
--		put_cred(oldcred);
--	return 0;
--
--already_same:
--	ret = 0;
--not_permitted:
-+	ret = task_work_add(parent, newwork, true);
-+	if (!ret)
-+		newwork = NULL;
-+unlock:
- 	write_unlock_irq(&tasklist_lock);
- 	rcu_read_unlock();
--	put_cred(cred);
-+	if (oldwork) {
-+		put_cred(oldwork->data);
-+		kfree(oldwork);
-+	}
-+	if (newwork) {
-+		put_cred(newwork->data);
-+		kfree(newwork);
-+	}
- 	return ret;
- 
-+error_newwork:
-+	kfree(newwork);
- error_keyring:
- 	key_ref_put(keyring_r);
- 	return ret;
-diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
-index be7ecb2..7ab0d8b 100644
---- a/security/keys/process_keys.c
-+++ b/security/keys/process_keys.c
-@@ -832,23 +832,17 @@ error:
-  * Replace a process's session keyring on behalf of one of its children when
-  * the target  process is about to resume userspace execution.
-  */
--void key_replace_session_keyring(void)
-+void key_change_session_keyring(struct task_work *twork)
- {
--	const struct cred *old;
--	struct cred *new;
--
--	if (!current->replacement_session_keyring)
--		return;
-+	const struct cred *old = current_cred();
-+	struct cred *new = twork->data;
- 
--	write_lock_irq(&tasklist_lock);
--	new = current->replacement_session_keyring;
--	current->replacement_session_keyring = NULL;
--	write_unlock_irq(&tasklist_lock);
--
--	if (!new)
-+	kfree(twork);
-+	if (unlikely(current->flags & PF_EXITING)) {
-+		put_cred(new);
- 		return;
-+	}
- 
--	old = current_cred();
- 	new->  uid	= old->  uid;
- 	new-> euid	= old-> euid;
- 	new-> suid	= old-> suid;
--- 
-1.7.5.4
-
diff --git a/features/uprobe/keys-kill-task_struct-replacement_session_keyring.patch b/features/uprobe/keys-kill-task_struct-replacement_session_keyring.patch
deleted file mode 100644
index 215ff3b4f1bcd225f0d023afeaa7dbc93c879951..0000000000000000000000000000000000000000
--- a/features/uprobe/keys-kill-task_struct-replacement_session_keyring.patch
+++ /dev/null
@@ -1,75 +0,0 @@
-From d4ef82f00c0b2e2abe0934f0808b390d469a44f9 Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Fri, 11 May 2012 10:59:09 +1000
-Subject: [PATCH 6/6] keys: kill task_struct->replacement_session_keyring
-
-commit f23ca335462e3c84f13270b9e65f83936068ec2c upstream.
-
-Kill the no longer used task_struct->replacement_session_keyring, update
-copy_creds() and exit_creds().
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Acked-by: David Howells <dhowells@redhat.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Richard Kuo <rkuo@codeaurora.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Alexander Gordeev <agordeev@redhat.com>
-Cc: Chris Zankel <chris@zankel.net>
-Cc: David Smith <dsmith@redhat.com>
-Cc: "Frank Ch. Eigler" <fche@redhat.com>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: Larry Woodman <lwoodman@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/sched.h |    2 --
- kernel/cred.c         |    9 ---------
- 2 files changed, 0 insertions(+), 11 deletions(-)
-
-diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 3ea394c..3dd6575 100644
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -1404,8 +1404,6 @@ struct task_struct {
- 					 * credentials (COW) */
- 	const struct cred __rcu *cred;	/* effective (overridable) subjective task
- 					 * credentials (COW) */
--	struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
--
- 	char comm[TASK_COMM_LEN]; /* executable name excluding path
- 				     - access with [gs]et_task_comm (which lock
- 				       it with task_lock())
-diff --git a/kernel/cred.c b/kernel/cred.c
-index e70683d..9570736 100644
---- a/kernel/cred.c
-+++ b/kernel/cred.c
-@@ -198,13 +198,6 @@ void exit_creds(struct task_struct *tsk)
- 	validate_creds(cred);
- 	alter_cred_subscribers(cred, -1);
- 	put_cred(cred);
--
--	cred = (struct cred *) tsk->replacement_session_keyring;
--	if (cred) {
--		tsk->replacement_session_keyring = NULL;
--		validate_creds(cred);
--		put_cred(cred);
--	}
- }
- 
- /**
-@@ -386,8 +379,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
- 	struct cred *new;
- 	int ret;
- 
--	p->replacement_session_keyring = NULL;
--
- 	if (
- #ifdef CONFIG_KEYS
- 		!p->cred->thread_keyring &&
--- 
-1.7.5.4
-
diff --git a/features/uprobe/keys-kill-the-dummy-key_replace_session_keyring.patch b/features/uprobe/keys-kill-the-dummy-key_replace_session_keyring.patch
deleted file mode 100644
index 89dd5db575385c3bee63645d088804ff27b72d9d..0000000000000000000000000000000000000000
--- a/features/uprobe/keys-kill-the-dummy-key_replace_session_keyring.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From 1cc141e62623a487e42a6af977549c628bb8a4f7 Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Fri, 11 May 2012 10:59:09 +1000
-Subject: [PATCH 5/6] keys: kill the dummy key_replace_session_keyring()
-
-commit dea649b8ac1861107c5d91e1a71121434fc64193 upstream.
-
-After the previouse change key_replace_session_keyring() becomes a nop.
-Remove the dummy definition in key.h and update the callers in
-arch/*/kernel/signal.c.
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Acked-by: David Howells <dhowells@redhat.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Richard Kuo <rkuo@codeaurora.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Alexander Gordeev <agordeev@redhat.com>
-Cc: Chris Zankel <chris@zankel.net>
-Cc: David Smith <dsmith@redhat.com>
-Cc: "Frank Ch. Eigler" <fche@redhat.com>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: Larry Woodman <lwoodman@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/key.h       |    2 --
- include/linux/tracehook.h |    2 --
- 2 files changed, 0 insertions(+), 4 deletions(-)
-
-diff --git a/include/linux/key.h b/include/linux/key.h
-index 0c263d6..16cbdb0 100644
---- a/include/linux/key.h
-+++ b/include/linux/key.h
-@@ -33,8 +33,6 @@ typedef uint32_t key_perm_t;
- 
- struct key;
- 
--#define key_replace_session_keyring()	do { } while (0)
--
- #ifdef CONFIG_KEYS
- 
- #undef KEY_DEBUGGING
-diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index ea9558f..48c597d 100644
---- a/include/linux/tracehook.h
-+++ b/include/linux/tracehook.h
-@@ -187,8 +187,6 @@ static inline void set_notify_resume(struct task_struct *task)
-  */
- static inline void tracehook_notify_resume(struct pt_regs *regs)
- {
--	if (current->replacement_session_keyring)
--		key_replace_session_keyring();
- 	/*
- 	 * The caller just cleared TIF_NOTIFY_RESUME. This barrier
- 	 * pairs with task_work_add()->set_notify_resume() after
--- 
-1.7.5.4
-
diff --git a/features/uprobe/move-key_repace_session_keyring-into-tracehook_notif.patch b/features/uprobe/move-key_repace_session_keyring-into-tracehook_notif.patch
deleted file mode 100644
index ae51e06e875e0a2937182f980458be0de677eb45..0000000000000000000000000000000000000000
--- a/features/uprobe/move-key_repace_session_keyring-into-tracehook_notif.patch
+++ /dev/null
@@ -1,359 +0,0 @@
-From 70754ded9575da5dafcf389d827d8dbfbf596240 Mon Sep 17 00:00:00 2001
-From: Al Viro <viro@zeniv.linux.org.uk>
-Date: Wed, 23 May 2012 14:44:37 -0400
-Subject: [PATCH 1/6] move key_repace_session_keyring() into
- tracehook_notify_resume()
-
-commit a42c6ded827dbd396d2efde7530620be029a72d1 upstream.
-
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-[Pb: dropped changes to archs lacking TIF_NOTIFY_RESUME: microblaze,
-m68k, um, xtensa, score]
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/alpha/kernel/signal.c     |    2 --
- arch/arm/kernel/signal.c       |    2 --
- arch/avr32/kernel/signal.c     |    2 --
- arch/blackfin/kernel/signal.c  |    2 --
- arch/c6x/kernel/signal.c       |    2 --
- arch/cris/kernel/ptrace.c      |    2 --
- arch/frv/kernel/signal.c       |    2 --
- arch/h8300/kernel/signal.c     |    2 --
- arch/hexagon/kernel/signal.c   |    5 +----
- arch/ia64/kernel/process.c     |    2 --
- arch/m32r/kernel/signal.c      |    2 --
- arch/mips/kernel/signal.c      |    2 --
- arch/mn10300/kernel/signal.c   |    2 --
- arch/openrisc/kernel/signal.c  |    2 --
- arch/parisc/kernel/signal.c    |    2 --
- arch/powerpc/kernel/signal.c   |    2 --
- arch/s390/kernel/signal.c      |    2 --
- arch/sh/kernel/signal_32.c     |    2 --
- arch/sh/kernel/signal_64.c     |    2 --
- arch/sparc/kernel/signal_32.c  |    2 --
- arch/sparc/kernel/signal_64.c  |    2 --
- arch/tile/kernel/process.c     |    2 --
- arch/unicore32/kernel/signal.c |    2 --
- arch/x86/kernel/signal.c       |    2 --
- include/linux/tracehook.h      |    2 ++
- 25 files changed, 3 insertions(+), 50 deletions(-)
-
-diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
-index 35f2ef4..bb61c58 100644
---- a/arch/alpha/kernel/signal.c
-+++ b/arch/alpha/kernel/signal.c
-@@ -616,7 +616,5 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
-index d68d1b6..b2abc46 100644
---- a/arch/arm/kernel/signal.c
-+++ b/arch/arm/kernel/signal.c
-@@ -735,7 +735,5 @@ do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
- 	if (thread_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
-index 64f886f..0d512c5 100644
---- a/arch/avr32/kernel/signal.c
-+++ b/arch/avr32/kernel/signal.c
-@@ -327,7 +327,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti)
- 	if (ti->flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
-index d536f35..0af1a1b 100644
---- a/arch/blackfin/kernel/signal.c
-+++ b/arch/blackfin/kernel/signal.c
-@@ -347,8 +347,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs)
- 	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
- 
-diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
-index 3b5a050..ee7beae 100644
---- a/arch/c6x/kernel/signal.c
-+++ b/arch/c6x/kernel/signal.c
-@@ -361,7 +361,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags,
- 	if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
-index d114ad3..58d44ee 100644
---- a/arch/cris/kernel/ptrace.c
-+++ b/arch/cris/kernel/ptrace.c
-@@ -40,7 +40,5 @@ void do_notify_resume(int canrestart, struct pt_regs *regs,
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c
-index bab0129..151a3fd 100644
---- a/arch/frv/kernel/signal.c
-+++ b/arch/frv/kernel/signal.c
-@@ -583,8 +583,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(__frame);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- 
- } /* end do_notify_resume() */
-diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
-index af842c3..14c46e8 100644
---- a/arch/h8300/kernel/signal.c
-+++ b/arch/h8300/kernel/signal.c
-@@ -557,7 +557,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
-index ecbab34..6274022 100644
---- a/arch/hexagon/kernel/signal.c
-+++ b/arch/hexagon/kernel/signal.c
-@@ -270,11 +270,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
- 	if (thread_info_flags & _TIF_SIGPENDING)
- 		do_signal(regs);
- 
--	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
-+	if (thread_info_flags & _TIF_NOTIFY_RESUME)
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
--	}
- }
- 
- /*
-diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
-index ce74e14..99f34a8 100644
---- a/arch/ia64/kernel/process.c
-+++ b/arch/ia64/kernel/process.c
-@@ -199,8 +199,6 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
- 	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(&scr->pt);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- 
- 	/* copy user rbs to kernel rbs */
-diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c
-index a08697f..d0a24f4 100644
---- a/arch/m32r/kernel/signal.c
-+++ b/arch/m32r/kernel/signal.c
-@@ -391,8 +391,6 @@ void do_notify_resume(struct pt_regs *regs, __u32 thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- 
- 	clear_thread_flag(TIF_IRET);
-diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
-index d5a338a..3f0fe74 100644
---- a/arch/mips/kernel/signal.c
-+++ b/arch/mips/kernel/signal.c
-@@ -652,8 +652,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
- 
-diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
-index 690f4e9..909059e 100644
---- a/arch/mn10300/kernel/signal.c
-+++ b/arch/mn10300/kernel/signal.c
-@@ -575,7 +575,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(current_frame());
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c
-index e970743..9ae6115 100644
---- a/arch/openrisc/kernel/signal.c
-+++ b/arch/openrisc/kernel/signal.c
-@@ -376,7 +376,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs)
- 	if (current_thread_info()->flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
-index 12c1ed3..c3102c4 100644
---- a/arch/parisc/kernel/signal.c
-+++ b/arch/parisc/kernel/signal.c
-@@ -647,7 +647,5 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall)
- 	if (test_thread_flag(TIF_NOTIFY_RESUME)) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
-index f1d61f0..e72fb65 100644
---- a/arch/powerpc/kernel/signal.c
-+++ b/arch/powerpc/kernel/signal.c
-@@ -199,8 +199,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
- 
-diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
-index f7582b2..fbf2495 100644
---- a/arch/s390/kernel/signal.c
-+++ b/arch/s390/kernel/signal.c
-@@ -517,6 +517,4 @@ void do_notify_resume(struct pt_regs *regs)
- {
- 	clear_thread_flag(TIF_NOTIFY_RESUME);
- 	tracehook_notify_resume(regs);
--	if (current->replacement_session_keyring)
--		key_replace_session_keyring();
- }
-diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
-index 5901fba..a6b74c3 100644
---- a/arch/sh/kernel/signal_32.c
-+++ b/arch/sh/kernel/signal_32.c
-@@ -633,7 +633,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
-index 3c9a6f7..52bdfb0 100644
---- a/arch/sh/kernel/signal_64.c
-+++ b/arch/sh/kernel/signal_64.c
-@@ -737,7 +737,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
-diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
-index 1e750e41..72bd0f7 100644
---- a/arch/sparc/kernel/signal_32.c
-+++ b/arch/sparc/kernel/signal_32.c
-@@ -603,8 +603,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
- 
-diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
-index 48b0f57..f2dcaab 100644
---- a/arch/sparc/kernel/signal_64.c
-+++ b/arch/sparc/kernel/signal_64.c
-@@ -618,8 +618,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
- 
-diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
-index 54e6c64..4515c92 100644
---- a/arch/tile/kernel/process.c
-+++ b/arch/tile/kernel/process.c
-@@ -588,8 +588,6 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 		return 1;
- 	}
- 	if (thread_info_flags & _TIF_SINGLESTEP) {
-diff --git a/arch/unicore32/kernel/signal.c b/arch/unicore32/kernel/signal.c
-index 911b549..b1e5cd5 100644
---- a/arch/unicore32/kernel/signal.c
-+++ b/arch/unicore32/kernel/signal.c
-@@ -470,8 +470,6 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
- 	if (thread_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- }
- 
-diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
-index 041af2f..a0679ff 100644
---- a/arch/x86/kernel/signal.c
-+++ b/arch/x86/kernel/signal.c
-@@ -837,8 +837,6 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
- 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- 		clear_thread_flag(TIF_NOTIFY_RESUME);
- 		tracehook_notify_resume(regs);
--		if (current->replacement_session_keyring)
--			key_replace_session_keyring();
- 	}
- 	if (thread_info_flags & _TIF_USER_RETURN_NOTIFY)
- 		fire_user_return_notifiers();
-diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index 51bd91d..d28ceaf 100644
---- a/include/linux/tracehook.h
-+++ b/include/linux/tracehook.h
-@@ -184,6 +184,8 @@ static inline void set_notify_resume(struct task_struct *task)
-  */
- static inline void tracehook_notify_resume(struct pt_regs *regs)
- {
-+	if (current->replacement_session_keyring)
-+		key_replace_session_keyring();
- }
- #endif	/* TIF_NOTIFY_RESUME */
- 
--- 
-1.7.5.4
-
diff --git a/features/uprobe/perf-probe-Detect-probe-target-when-m-x-options-are-.patch b/features/uprobe/perf-probe-Detect-probe-target-when-m-x-options-are-.patch
deleted file mode 100644
index 98a2f0c0cb90ae8ce1e066df902b2679dd64e55d..0000000000000000000000000000000000000000
--- a/features/uprobe/perf-probe-Detect-probe-target-when-m-x-options-are-.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-From 8893371eedcf3baa234184e9156fdfe0ea69260d Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 16 Apr 2012 17:39:25 +0530
-Subject: [PATCH 21/24] perf probe: Detect probe target when m/x options are
- absent
-
-Options -m and -x explicitly allow tracing of modules / user space
-binaries. In absense of these options, check if the first argument can
-be used as a target.
-
-perf probe /bin/zsh zfree is equivalent to perf probe -x /bin/zsh zfree.
-
-commit 73eff9f56e15598c8399c0b86899fd889b97f085 upstream
-
-Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Link: http://lkml.kernel.org/r/20120416120925.30661.40409.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- tools/perf/Documentation/perf-probe.txt |    8 ++++-
- tools/perf/builtin-probe.c              |   43 ++++++++++++++++++++++++++++--
- 2 files changed, 46 insertions(+), 5 deletions(-)
-
-diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
-index fb673be..b715cb7 100644
---- a/tools/perf/Documentation/perf-probe.txt
-+++ b/tools/perf/Documentation/perf-probe.txt
-@@ -104,6 +104,10 @@ OPTIONS
- 	Specify path to the executable or shared library file for user
- 	space tracing. Can also be used with --funcs option.
- 
-+In absence of -m/-x options, perf probe checks if the first argument after
-+the options is an absolute path name. If its an absolute path, perf probe
-+uses it as a target module/target user space binary to probe.
-+
- PROBE SYNTAX
- ------------
- Probe points are defined by following syntax.
-@@ -190,11 +194,11 @@ Delete all probes on schedule().
- 
- Add probes at zfree() function on /bin/zsh
- 
-- ./perf probe -x /bin/zsh zfree
-+ ./perf probe -x /bin/zsh zfree or ./perf probe /bin/zsh zfree
- 
- Add probes at malloc() function on libc
- 
-- ./perf probe -x /lib/libc.so.6 malloc
-+ ./perf probe -x /lib/libc.so.6 malloc or ./perf probe /lib/libc.so.6 malloc
- 
- SEE ALSO
- --------
-diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
-index ee3d84a..e215ae6 100644
---- a/tools/perf/builtin-probe.c
-+++ b/tools/perf/builtin-probe.c
-@@ -85,21 +85,58 @@ static int parse_probe_event(const char *str)
- 	return ret;
- }
- 
-+static int set_target(const char *ptr)
-+{
-+	int found = 0;
-+	const char *buf;
-+
-+	/*
-+	 * The first argument after options can be an absolute path
-+	 * to an executable / library or kernel module.
-+	 *
-+	 * TODO: Support relative path, and $PATH, $LD_LIBRARY_PATH,
-+	 * short module name.
-+	 */
-+	if (!params.target && ptr && *ptr == '/') {
-+		params.target = ptr;
-+		found = 1;
-+		buf = ptr + (strlen(ptr) - 3);
-+
-+		if (strcmp(buf, ".ko"))
-+			params.uprobes = true;
-+
-+	}
-+
-+	return found;
-+}
-+
- static int parse_probe_event_argv(int argc, const char **argv)
- {
--	int i, len, ret;
-+	int i, len, ret, found_target;
- 	char *buf;
- 
-+	found_target = set_target(argv[0]);
-+	if (found_target && argc == 1)
-+		return 0;
-+
- 	/* Bind up rest arguments */
- 	len = 0;
--	for (i = 0; i < argc; i++)
-+	for (i = 0; i < argc; i++) {
-+		if (i == 0 && found_target)
-+			continue;
-+
- 		len += strlen(argv[i]) + 1;
-+	}
- 	buf = zalloc(len + 1);
- 	if (buf == NULL)
- 		return -ENOMEM;
- 	len = 0;
--	for (i = 0; i < argc; i++)
-+	for (i = 0; i < argc; i++) {
-+		if (i == 0 && found_target)
-+			continue;
-+
- 		len += sprintf(&buf[len], "%s ", argv[i]);
-+	}
- 	params.mod_events = true;
- 	ret = parse_probe_event(buf);
- 	free(buf);
--- 
-1.7.5.4
-
diff --git a/features/uprobe/perf-probe-Provide-perf-interface-for-uprobes.patch b/features/uprobe/perf-probe-Provide-perf-interface-for-uprobes.patch
deleted file mode 100644
index 0d2503d5f6437835de88282ebec03f670217c3e8..0000000000000000000000000000000000000000
--- a/features/uprobe/perf-probe-Provide-perf-interface-for-uprobes.patch
+++ /dev/null
@@ -1,944 +0,0 @@
-From 544d531a337d560bd89f44ec45b0f6f2658c8e7c Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 16 Apr 2012 17:39:09 +0530
-Subject: [PATCH 20/24] perf probe: Provide perf interface for uprobes
-
-- Enhances perf to probe user space executables and libraries.
-- Enhances -F/--funcs option of "perf probe" to list possible probe points in
-  an executable file or library.
-- Documents userspace probing support in perf.
-
-[ Probing a function in the executable using function name  ]
-perf probe -x /bin/zsh zfree
-
-[ Probing a library function using function name ]
-perf probe -x /lib64/libc.so.6 malloc
-
-[ list probe-able functions in an executable ]
-perf probe -F -x /bin/zsh
-
-[ list probe-able functions in an library]
-perf probe -F -x /lib/libc.so.6
-
-commit 225466f1c2d816c33b4341008f45dfdc83a9f0cb upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Link: http://lkml.kernel.org/r/20120416120909.30661.99781.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- tools/perf/Documentation/perf-probe.txt |   15 +-
- tools/perf/builtin-probe.c              |   43 +++-
- tools/perf/util/probe-event.c           |  422 ++++++++++++++++++++++++-------
- tools/perf/util/probe-event.h           |   12 +-
- tools/perf/util/symbol.c                |    8 +
- tools/perf/util/symbol.h                |    1 +
- 6 files changed, 403 insertions(+), 98 deletions(-)
-
-diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
-index 2780d9c..fb673be 100644
---- a/tools/perf/Documentation/perf-probe.txt
-+++ b/tools/perf/Documentation/perf-probe.txt
-@@ -77,7 +77,8 @@ OPTIONS
- 
- -F::
- --funcs::
--	Show available functions in given module or kernel.
-+	Show available functions in given module or kernel. With -x/--exec,
-+	can also list functions in a user space executable / shared library.
- 
- --filter=FILTER::
- 	(Only for --vars and --funcs) Set filter. FILTER is a combination of glob
-@@ -98,6 +99,11 @@ OPTIONS
- --max-probes::
- 	Set the maximum number of probe points for an event. Default is 128.
- 
-+-x::
-+--exec=PATH::
-+	Specify path to the executable or shared library file for user
-+	space tracing. Can also be used with --funcs option.
-+
- PROBE SYNTAX
- ------------
- Probe points are defined by following syntax.
-@@ -182,6 +188,13 @@ Delete all probes on schedule().
- 
-  ./perf probe --del='schedule*'
- 
-+Add probes at zfree() function on /bin/zsh
-+
-+ ./perf probe -x /bin/zsh zfree
-+
-+Add probes at malloc() function on libc
-+
-+ ./perf probe -x /lib/libc.so.6 malloc
- 
- SEE ALSO
- --------
-diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
-index 4935c09..ee3d84a 100644
---- a/tools/perf/builtin-probe.c
-+++ b/tools/perf/builtin-probe.c
-@@ -54,6 +54,7 @@ static struct {
- 	bool show_ext_vars;
- 	bool show_funcs;
- 	bool mod_events;
-+	bool uprobes;
- 	int nevents;
- 	struct perf_probe_event events[MAX_PROBES];
- 	struct strlist *dellist;
-@@ -75,6 +76,8 @@ static int parse_probe_event(const char *str)
- 		return -1;
- 	}
- 
-+	pev->uprobes = params.uprobes;
-+
- 	/* Parse a perf-probe command into event */
- 	ret = parse_perf_probe_command(str, pev);
- 	pr_debug("%d arguments\n", pev->nargs);
-@@ -125,6 +128,28 @@ static int opt_del_probe_event(const struct option *opt __used,
- 	return 0;
- }
- 
-+static int opt_set_target(const struct option *opt, const char *str,
-+			int unset __used)
-+{
-+	int ret = -ENOENT;
-+
-+	if  (str && !params.target) {
-+		if (!strcmp(opt->long_name, "exec"))
-+			params.uprobes = true;
-+#ifdef DWARF_SUPPORT
-+		else if (!strcmp(opt->long_name, "module"))
-+			params.uprobes = false;
-+#endif
-+		else
-+			return ret;
-+
-+		params.target = str;
-+		ret = 0;
-+	}
-+
-+	return ret;
-+}
-+
- #ifdef DWARF_SUPPORT
- static int opt_show_lines(const struct option *opt __used,
- 			  const char *str, int unset __used)
-@@ -246,9 +271,9 @@ static const struct option options[] = {
- 		   "file", "vmlinux pathname"),
- 	OPT_STRING('s', "source", &symbol_conf.source_prefix,
- 		   "directory", "path to kernel source"),
--	OPT_STRING('m', "module", &params.target,
--		   "modname|path",
--		   "target module name (for online) or path (for offline)"),
-+	OPT_CALLBACK('m', "module", NULL, "modname|path",
-+		"target module name (for online) or path (for offline)",
-+		opt_set_target),
- #endif
- 	OPT__DRY_RUN(&probe_event_dry_run),
- 	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
-@@ -260,6 +285,8 @@ static const struct option options[] = {
- 		     "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\" for --vars,\n"
- 		     "\t\t\t \"" DEFAULT_FUNC_FILTER "\" for --funcs)",
- 		     opt_set_filter),
-+	OPT_CALLBACK('x', "exec", NULL, "executable|path",
-+			"target executable name or path", opt_set_target),
- 	OPT_END()
- };
- 
-@@ -310,6 +337,10 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
- 			pr_err("  Error: Don't use --list with --funcs.\n");
- 			usage_with_options(probe_usage, options);
- 		}
-+		if (params.uprobes) {
-+			pr_warning("  Error: Don't use --list with --exec.\n");
-+			usage_with_options(probe_usage, options);
-+		}
- 		ret = show_perf_probe_events();
- 		if (ret < 0)
- 			pr_err("  Error: Failed to show event list. (%d)\n",
-@@ -333,8 +364,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
- 		if (!params.filter)
- 			params.filter = strfilter__new(DEFAULT_FUNC_FILTER,
- 						       NULL);
--		ret = show_available_funcs(params.target,
--					   params.filter);
-+		ret = show_available_funcs(params.target, params.filter,
-+					params.uprobes);
- 		strfilter__delete(params.filter);
- 		if (ret < 0)
- 			pr_err("  Error: Failed to show functions."
-@@ -343,7 +374,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
- 	}
- 
- #ifdef DWARF_SUPPORT
--	if (params.show_lines) {
-+	if (params.show_lines && !params.uprobes) {
- 		if (params.mod_events) {
- 			pr_err("  Error: Don't use --line with"
- 			       " --add/--del.\n");
-diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
-index 8a8ee64..59dccc9 100644
---- a/tools/perf/util/probe-event.c
-+++ b/tools/perf/util/probe-event.c
-@@ -44,6 +44,7 @@
- #include "trace-event.h"	/* For __unused */
- #include "probe-event.h"
- #include "probe-finder.h"
-+#include "session.h"
- 
- #define MAX_CMDLEN 256
- #define MAX_PROBE_ARGS 128
-@@ -70,6 +71,8 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
- }
- 
- static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
-+static int convert_name_to_addr(struct perf_probe_event *pev,
-+				const char *exec);
- static struct machine machine;
- 
- /* Initialize symbol maps and path of vmlinux/modules */
-@@ -170,6 +173,34 @@ const char *kernel_get_module_path(const char *module)
- 	return (dso) ? dso->long_name : NULL;
- }
- 
-+static int init_user_exec(void)
-+{
-+	int ret = 0;
-+
-+	symbol_conf.try_vmlinux_path = false;
-+	symbol_conf.sort_by_name = true;
-+	ret = symbol__init();
-+
-+	if (ret < 0)
-+		pr_debug("Failed to init symbol map.\n");
-+
-+	return ret;
-+}
-+
-+static int convert_to_perf_probe_point(struct probe_trace_point *tp,
-+					struct perf_probe_point *pp)
-+{
-+	pp->function = strdup(tp->symbol);
-+
-+	if (pp->function == NULL)
-+		return -ENOMEM;
-+
-+	pp->offset = tp->offset;
-+	pp->retprobe = tp->retprobe;
-+
-+	return 0;
-+}
-+
- #ifdef DWARF_SUPPORT
- /* Open new debuginfo of given module */
- static struct debuginfo *open_debuginfo(const char *module)
-@@ -224,10 +255,7 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
- 	if (ret <= 0) {
- 		pr_debug("Failed to find corresponding probes from "
- 			 "debuginfo. Use kprobe event information.\n");
--		pp->function = strdup(tp->symbol);
--		if (pp->function == NULL)
--			return -ENOMEM;
--		pp->offset = tp->offset;
-+		return convert_to_perf_probe_point(tp, pp);
- 	}
- 	pp->retprobe = tp->retprobe;
- 
-@@ -275,9 +303,20 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
- 					  int max_tevs, const char *target)
- {
- 	bool need_dwarf = perf_probe_event_need_dwarf(pev);
--	struct debuginfo *dinfo = open_debuginfo(target);
-+	struct debuginfo *dinfo;
- 	int ntevs, ret = 0;
- 
-+	if (pev->uprobes) {
-+		if (need_dwarf) {
-+			pr_warning("Debuginfo-analysis is not yet supported"
-+					" with -x/--exec option.\n");
-+			return -ENOSYS;
-+		}
-+		return convert_name_to_addr(pev, target);
-+	}
-+
-+	dinfo = open_debuginfo(target);
-+
- 	if (!dinfo) {
- 		if (need_dwarf) {
- 			pr_warning("Failed to open debuginfo file.\n");
-@@ -603,23 +642,22 @@ static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
- 		pr_err("Failed to find symbol %s in kernel.\n", tp->symbol);
- 		return -ENOENT;
- 	}
--	pp->function = strdup(tp->symbol);
--	if (pp->function == NULL)
--		return -ENOMEM;
--	pp->offset = tp->offset;
--	pp->retprobe = tp->retprobe;
- 
--	return 0;
-+	return convert_to_perf_probe_point(tp, pp);
- }
- 
- static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
- 				struct probe_trace_event **tevs __unused,
--				int max_tevs __unused, const char *mod __unused)
-+				int max_tevs __unused, const char *target)
- {
- 	if (perf_probe_event_need_dwarf(pev)) {
- 		pr_warning("Debuginfo-analysis is not supported.\n");
- 		return -ENOSYS;
- 	}
-+
-+	if (pev->uprobes)
-+		return convert_name_to_addr(pev, target);
-+
- 	return 0;
- }
- 
-@@ -1341,11 +1379,18 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
- 	if (buf == NULL)
- 		return NULL;
- 
--	len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
--			 tp->retprobe ? 'r' : 'p',
--			 tev->group, tev->event,
--			 tp->module ?: "", tp->module ? ":" : "",
--			 tp->symbol, tp->offset);
-+	if (tev->uprobes)
-+		len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s:%s",
-+				 tp->retprobe ? 'r' : 'p',
-+				 tev->group, tev->event,
-+				 tp->module, tp->symbol);
-+	else
-+		len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
-+				 tp->retprobe ? 'r' : 'p',
-+				 tev->group, tev->event,
-+				 tp->module ?: "", tp->module ? ":" : "",
-+				 tp->symbol, tp->offset);
-+
- 	if (len <= 0)
- 		goto error;
- 
-@@ -1364,7 +1409,7 @@ error:
- }
- 
- static int convert_to_perf_probe_event(struct probe_trace_event *tev,
--				       struct perf_probe_event *pev)
-+			       struct perf_probe_event *pev, bool is_kprobe)
- {
- 	char buf[64] = "";
- 	int i, ret;
-@@ -1376,7 +1421,11 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev,
- 		return -ENOMEM;
- 
- 	/* Convert trace_point to probe_point */
--	ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
-+	if (is_kprobe)
-+		ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
-+	else
-+		ret = convert_to_perf_probe_point(&tev->point, &pev->point);
-+
- 	if (ret < 0)
- 		return ret;
- 
-@@ -1472,7 +1521,26 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
- 	memset(tev, 0, sizeof(*tev));
- }
- 
--static int open_kprobe_events(bool readwrite)
-+static void print_warn_msg(const char *file, bool is_kprobe)
-+{
-+
-+	if (errno == ENOENT) {
-+		const char *config;
-+
-+		if (!is_kprobe)
-+			config = "CONFIG_UPROBE_EVENTS";
-+		else
-+			config = "CONFIG_KPROBE_EVENTS";
-+
-+		pr_warning("%s file does not exist - please rebuild kernel"
-+				" with %s.\n", file, config);
-+	} else
-+		pr_warning("Failed to open %s file: %s\n", file,
-+				strerror(errno));
-+}
-+
-+static int open_probe_events(const char *trace_file, bool readwrite,
-+				bool is_kprobe)
- {
- 	char buf[PATH_MAX];
- 	const char *__debugfs;
-@@ -1484,27 +1552,31 @@ static int open_kprobe_events(bool readwrite)
- 		return -ENOENT;
- 	}
- 
--	ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
-+	ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file);
- 	if (ret >= 0) {
- 		pr_debug("Opening %s write=%d\n", buf, readwrite);
- 		if (readwrite && !probe_event_dry_run)
- 			ret = open(buf, O_RDWR, O_APPEND);
- 		else
- 			ret = open(buf, O_RDONLY, 0);
--	}
- 
--	if (ret < 0) {
--		if (errno == ENOENT)
--			pr_warning("kprobe_events file does not exist - please"
--				 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
--		else
--			pr_warning("Failed to open kprobe_events file: %s\n",
--				   strerror(errno));
-+		if (ret < 0)
-+			print_warn_msg(buf, is_kprobe);
- 	}
- 	return ret;
- }
- 
--/* Get raw string list of current kprobe_events */
-+static int open_kprobe_events(bool readwrite)
-+{
-+	return open_probe_events("tracing/kprobe_events", readwrite, true);
-+}
-+
-+static int open_uprobe_events(bool readwrite)
-+{
-+	return open_probe_events("tracing/uprobe_events", readwrite, false);
-+}
-+
-+/* Get raw string list of current kprobe_events  or uprobe_events */
- static struct strlist *get_probe_trace_command_rawlist(int fd)
- {
- 	int ret, idx;
-@@ -1569,36 +1641,26 @@ static int show_perf_probe_event(struct perf_probe_event *pev)
- 	return ret;
- }
- 
--/* List up current perf-probe events */
--int show_perf_probe_events(void)
-+static int __show_perf_probe_events(int fd, bool is_kprobe)
- {
--	int fd, ret;
-+	int ret = 0;
- 	struct probe_trace_event tev;
- 	struct perf_probe_event pev;
- 	struct strlist *rawlist;
- 	struct str_node *ent;
- 
--	setup_pager();
--	ret = init_vmlinux();
--	if (ret < 0)
--		return ret;
--
- 	memset(&tev, 0, sizeof(tev));
- 	memset(&pev, 0, sizeof(pev));
- 
--	fd = open_kprobe_events(false);
--	if (fd < 0)
--		return fd;
--
- 	rawlist = get_probe_trace_command_rawlist(fd);
--	close(fd);
- 	if (!rawlist)
- 		return -ENOENT;
- 
- 	strlist__for_each(ent, rawlist) {
- 		ret = parse_probe_trace_command(ent->s, &tev);
- 		if (ret >= 0) {
--			ret = convert_to_perf_probe_event(&tev, &pev);
-+			ret = convert_to_perf_probe_event(&tev, &pev,
-+								is_kprobe);
- 			if (ret >= 0)
- 				ret = show_perf_probe_event(&pev);
- 		}
-@@ -1612,6 +1674,33 @@ int show_perf_probe_events(void)
- 	return ret;
- }
- 
-+/* List up current perf-probe events */
-+int show_perf_probe_events(void)
-+{
-+	int fd, ret;
-+
-+	setup_pager();
-+	fd = open_kprobe_events(false);
-+
-+	if (fd < 0)
-+		return fd;
-+
-+	ret = init_vmlinux();
-+	if (ret < 0)
-+		return ret;
-+
-+	ret = __show_perf_probe_events(fd, true);
-+	close(fd);
-+
-+	fd = open_uprobe_events(false);
-+	if (fd >= 0) {
-+		ret = __show_perf_probe_events(fd, false);
-+		close(fd);
-+	}
-+
-+	return ret;
-+}
-+
- /* Get current perf-probe event names */
- static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
- {
-@@ -1717,7 +1806,11 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
- 	const char *event, *group;
- 	struct strlist *namelist;
- 
--	fd = open_kprobe_events(true);
-+	if (pev->uprobes)
-+		fd = open_uprobe_events(true);
-+	else
-+		fd = open_kprobe_events(true);
-+
- 	if (fd < 0)
- 		return fd;
- 	/* Get current event names */
-@@ -1829,6 +1922,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
- 	tev->point.offset = pev->point.offset;
- 	tev->point.retprobe = pev->point.retprobe;
- 	tev->nargs = pev->nargs;
-+	tev->uprobes = pev->uprobes;
-+
- 	if (tev->nargs) {
- 		tev->args = zalloc(sizeof(struct probe_trace_arg)
- 				   * tev->nargs);
-@@ -1859,6 +1954,9 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
- 		}
- 	}
- 
-+	if (pev->uprobes)
-+		return 1;
-+
- 	/* Currently just checking function name from symbol map */
- 	sym = __find_kernel_function_by_name(tev->point.symbol, NULL);
- 	if (!sym) {
-@@ -1894,12 +1992,18 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
- 	int i, j, ret;
- 	struct __event_package *pkgs;
- 
-+	ret = 0;
- 	pkgs = zalloc(sizeof(struct __event_package) * npevs);
-+
- 	if (pkgs == NULL)
- 		return -ENOMEM;
- 
--	/* Init vmlinux path */
--	ret = init_vmlinux();
-+	if (!pevs->uprobes)
-+		/* Init vmlinux path */
-+		ret = init_vmlinux();
-+	else
-+		ret = init_user_exec();
-+
- 	if (ret < 0) {
- 		free(pkgs);
- 		return ret;
-@@ -1971,23 +2075,15 @@ error:
- 	return ret;
- }
- 
--static int del_trace_probe_event(int fd, const char *group,
--				  const char *event, struct strlist *namelist)
-+static int del_trace_probe_event(int fd, const char *buf,
-+						  struct strlist *namelist)
- {
--	char buf[128];
- 	struct str_node *ent, *n;
--	int found = 0, ret = 0;
--
--	ret = e_snprintf(buf, 128, "%s:%s", group, event);
--	if (ret < 0) {
--		pr_err("Failed to copy event.\n");
--		return ret;
--	}
-+	int ret = -1;
- 
- 	if (strpbrk(buf, "*?")) { /* Glob-exp */
- 		strlist__for_each_safe(ent, n, namelist)
- 			if (strglobmatch(ent->s, buf)) {
--				found++;
- 				ret = __del_trace_probe_event(fd, ent);
- 				if (ret < 0)
- 					break;
-@@ -1996,40 +2092,43 @@ static int del_trace_probe_event(int fd, const char *group,
- 	} else {
- 		ent = strlist__find(namelist, buf);
- 		if (ent) {
--			found++;
- 			ret = __del_trace_probe_event(fd, ent);
- 			if (ret >= 0)
- 				strlist__remove(namelist, ent);
- 		}
- 	}
--	if (found == 0 && ret >= 0)
--		pr_info("Info: Event \"%s\" does not exist.\n", buf);
- 
- 	return ret;
- }
- 
- int del_perf_probe_events(struct strlist *dellist)
- {
--	int fd, ret = 0;
-+	int ret = -1, ufd = -1, kfd = -1;
-+	char buf[128];
- 	const char *group, *event;
- 	char *p, *str;
- 	struct str_node *ent;
--	struct strlist *namelist;
--
--	fd = open_kprobe_events(true);
--	if (fd < 0)
--		return fd;
-+	struct strlist *namelist = NULL, *unamelist = NULL;
- 
- 	/* Get current event names */
--	namelist = get_probe_trace_event_names(fd, true);
--	if (namelist == NULL)
--		return -EINVAL;
-+	kfd = open_kprobe_events(true);
-+	if (kfd < 0)
-+		return kfd;
-+
-+	namelist = get_probe_trace_event_names(kfd, true);
-+	ufd = open_uprobe_events(true);
-+
-+	if (ufd >= 0)
-+		unamelist = get_probe_trace_event_names(ufd, true);
-+
-+	if (namelist == NULL && unamelist == NULL)
-+		goto error;
- 
- 	strlist__for_each(ent, dellist) {
- 		str = strdup(ent->s);
- 		if (str == NULL) {
- 			ret = -ENOMEM;
--			break;
-+			goto error;
- 		}
- 		pr_debug("Parsing: %s\n", str);
- 		p = strchr(str, ':');
-@@ -2041,17 +2140,46 @@ int del_perf_probe_events(struct strlist *dellist)
- 			group = "*";
- 			event = str;
- 		}
-+
-+		ret = e_snprintf(buf, 128, "%s:%s", group, event);
-+		if (ret < 0) {
-+			pr_err("Failed to copy event.");
-+			free(str);
-+			goto error;
-+		}
-+
- 		pr_debug("Group: %s, Event: %s\n", group, event);
--		ret = del_trace_probe_event(fd, group, event, namelist);
-+
-+		if (namelist)
-+			ret = del_trace_probe_event(kfd, buf, namelist);
-+
-+		if (unamelist && ret != 0)
-+			ret = del_trace_probe_event(ufd, buf, unamelist);
-+
-+		if (ret != 0)
-+			pr_info("Info: Event \"%s\" does not exist.\n", buf);
-+
- 		free(str);
--		if (ret < 0)
--			break;
- 	}
--	strlist__delete(namelist);
--	close(fd);
-+
-+error:
-+	if (kfd >= 0) {
-+		if (namelist)
-+			strlist__delete(namelist);
-+
-+		close(kfd);
-+	}
-+
-+	if (ufd >= 0) {
-+		if (unamelist)
-+			strlist__delete(unamelist);
-+
-+		close(ufd);
-+	}
- 
- 	return ret;
- }
-+
- /* TODO: don't use a global variable for filter ... */
- static struct strfilter *available_func_filter;
- 
-@@ -2068,30 +2196,152 @@ static int filter_available_functions(struct map *map __unused,
- 	return 1;
- }
- 
--int show_available_funcs(const char *target, struct strfilter *_filter)
-+static int __show_available_funcs(struct map *map)
-+{
-+	if (map__load(map, filter_available_functions)) {
-+		pr_err("Failed to load map.\n");
-+		return -EINVAL;
-+	}
-+	if (!dso__sorted_by_name(map->dso, map->type))
-+		dso__sort_by_name(map->dso, map->type);
-+
-+	dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
-+	return 0;
-+}
-+
-+static int available_kernel_funcs(const char *module)
- {
- 	struct map *map;
- 	int ret;
- 
--	setup_pager();
--
- 	ret = init_vmlinux();
- 	if (ret < 0)
- 		return ret;
- 
--	map = kernel_get_module_map(target);
-+	map = kernel_get_module_map(module);
- 	if (!map) {
--		pr_err("Failed to find %s map.\n", (target) ? : "kernel");
-+		pr_err("Failed to find %s map.\n", (module) ? : "kernel");
- 		return -EINVAL;
- 	}
-+	return __show_available_funcs(map);
-+}
-+
-+static int available_user_funcs(const char *target)
-+{
-+	struct map *map;
-+	int ret;
-+
-+	ret = init_user_exec();
-+	if (ret < 0)
-+		return ret;
-+
-+	map = dso__new_map(target);
-+	ret = __show_available_funcs(map);
-+	dso__delete(map->dso);
-+	map__delete(map);
-+	return ret;
-+}
-+
-+int show_available_funcs(const char *target, struct strfilter *_filter,
-+					bool user)
-+{
-+	setup_pager();
- 	available_func_filter = _filter;
-+
-+	if (!user)
-+		return available_kernel_funcs(target);
-+
-+	return available_user_funcs(target);
-+}
-+
-+/*
-+ * uprobe_events only accepts address:
-+ * Convert function and any offset to address
-+ */
-+static int convert_name_to_addr(struct perf_probe_event *pev, const char *exec)
-+{
-+	struct perf_probe_point *pp = &pev->point;
-+	struct symbol *sym;
-+	struct map *map = NULL;
-+	char *function = NULL, *name = NULL;
-+	int ret = -EINVAL;
-+	unsigned long long vaddr = 0;
-+
-+	if (!pp->function) {
-+		pr_warning("No function specified for uprobes");
-+		goto out;
-+	}
-+
-+	function = strdup(pp->function);
-+	if (!function) {
-+		pr_warning("Failed to allocate memory by strdup.\n");
-+		ret = -ENOMEM;
-+		goto out;
-+	}
-+
-+	name = realpath(exec, NULL);
-+	if (!name) {
-+		pr_warning("Cannot find realpath for %s.\n", exec);
-+		goto out;
-+	}
-+	map = dso__new_map(name);
-+	if (!map) {
-+		pr_warning("Cannot find appropriate DSO for %s.\n", exec);
-+		goto out;
-+	}
-+	available_func_filter = strfilter__new(function, NULL);
- 	if (map__load(map, filter_available_functions)) {
- 		pr_err("Failed to load map.\n");
--		return -EINVAL;
-+		goto out;
- 	}
--	if (!dso__sorted_by_name(map->dso, map->type))
--		dso__sort_by_name(map->dso, map->type);
- 
--	dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
--	return 0;
-+	sym = map__find_symbol_by_name(map, function, NULL);
-+	if (!sym) {
-+		pr_warning("Cannot find %s in DSO %s\n", function, exec);
-+		goto out;
-+	}
-+
-+	if (map->start > sym->start)
-+		vaddr = map->start;
-+	vaddr += sym->start + pp->offset + map->pgoff;
-+	pp->offset = 0;
-+
-+	if (!pev->event) {
-+		pev->event = function;
-+		function = NULL;
-+	}
-+	if (!pev->group) {
-+		char *ptr1, *ptr2;
-+
-+		pev->group = zalloc(sizeof(char *) * 64);
-+		ptr1 = strdup(basename(exec));
-+		if (ptr1) {
-+			ptr2 = strpbrk(ptr1, "-._");
-+			if (ptr2)
-+				*ptr2 = '\0';
-+			e_snprintf(pev->group, 64, "%s_%s", PERFPROBE_GROUP,
-+					ptr1);
-+			free(ptr1);
-+		}
-+	}
-+	free(pp->function);
-+	pp->function = zalloc(sizeof(char *) * MAX_PROBE_ARGS);
-+	if (!pp->function) {
-+		ret = -ENOMEM;
-+		pr_warning("Failed to allocate memory by zalloc.\n");
-+		goto out;
-+	}
-+	e_snprintf(pp->function, MAX_PROBE_ARGS, "0x%llx", vaddr);
-+	ret = 0;
-+
-+out:
-+	if (map) {
-+		dso__delete(map->dso);
-+		map__delete(map);
-+	}
-+	if (function)
-+		free(function);
-+	if (name)
-+		free(name);
-+	return ret;
- }
-diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
-index a7dee83..f9f3de8 100644
---- a/tools/perf/util/probe-event.h
-+++ b/tools/perf/util/probe-event.h
-@@ -7,7 +7,7 @@
- 
- extern bool probe_event_dry_run;
- 
--/* kprobe-tracer tracing point */
-+/* kprobe-tracer and uprobe-tracer tracing point */
- struct probe_trace_point {
- 	char		*symbol;	/* Base symbol */
- 	char		*module;	/* Module name */
-@@ -21,7 +21,7 @@ struct probe_trace_arg_ref {
- 	long				offset;	/* Offset value */
- };
- 
--/* kprobe-tracer tracing argument */
-+/* kprobe-tracer and uprobe-tracer tracing argument */
- struct probe_trace_arg {
- 	char				*name;	/* Argument name */
- 	char				*value;	/* Base value */
-@@ -29,12 +29,13 @@ struct probe_trace_arg {
- 	struct probe_trace_arg_ref	*ref;	/* Referencing offset */
- };
- 
--/* kprobe-tracer tracing event (point + arg) */
-+/* kprobe-tracer and uprobe-tracer tracing event (point + arg) */
- struct probe_trace_event {
- 	char				*event;	/* Event name */
- 	char				*group;	/* Group name */
- 	struct probe_trace_point	point;	/* Trace point */
- 	int				nargs;	/* Number of args */
-+	bool				uprobes;	/* uprobes only */
- 	struct probe_trace_arg		*args;	/* Arguments */
- };
- 
-@@ -70,6 +71,7 @@ struct perf_probe_event {
- 	char			*group;	/* Group name */
- 	struct perf_probe_point	point;	/* Probe point */
- 	int			nargs;	/* Number of arguments */
-+	bool			uprobes;
- 	struct perf_probe_arg	*args;	/* Arguments */
- };
- 
-@@ -129,8 +131,8 @@ extern int show_line_range(struct line_range *lr, const char *module);
- extern int show_available_vars(struct perf_probe_event *pevs, int npevs,
- 			       int max_probe_points, const char *module,
- 			       struct strfilter *filter, bool externs);
--extern int show_available_funcs(const char *module, struct strfilter *filter);
--
-+extern int show_available_funcs(const char *module, struct strfilter *filter,
-+				bool user);
- 
- /* Maximum index number of event-name postfix */
- #define MAX_EVENT_INDEX	1024
-diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
-index ab9867b..e2ba885 100644
---- a/tools/perf/util/symbol.c
-+++ b/tools/perf/util/symbol.c
-@@ -2783,3 +2783,11 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
- 
- 	return ret;
- }
-+
-+struct map *dso__new_map(const char *name)
-+{
-+	struct dso *dso = dso__new(name);
-+	struct map *map = map__new2(0, dso, MAP__FUNCTION);
-+
-+	return map;
-+}
-diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
-index ac49ef2..9e7742c 100644
---- a/tools/perf/util/symbol.h
-+++ b/tools/perf/util/symbol.h
-@@ -237,6 +237,7 @@ void dso__set_long_name(struct dso *dso, char *name);
- void dso__set_build_id(struct dso *dso, void *build_id);
- void dso__read_running_kernel_build_id(struct dso *dso,
- 				       struct machine *machine);
-+struct map *dso__new_map(const char *name);
- struct symbol *dso__find_symbol(struct dso *dso, enum map_type type,
- 				u64 addr);
- struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
--- 
-1.7.5.4
-
diff --git a/features/uprobe/powerpc-Add-trap_nr-to-thread_struct.patch b/features/uprobe/powerpc-Add-trap_nr-to-thread_struct.patch
deleted file mode 100644
index e9cbc45d229f8bc99639fd2fff4be3801b85a186..0000000000000000000000000000000000000000
--- a/features/uprobe/powerpc-Add-trap_nr-to-thread_struct.patch
+++ /dev/null
@@ -1,84 +0,0 @@
-From d40e73dea840d9e6e7617b45fd98638615ab2c45 Mon Sep 17 00:00:00 2001
-From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Date: Wed, 25 Jul 2012 19:19:02 +0000
-Subject: [PATCH 1/2] powerpc: Add trap_nr to thread_struct
-
-http://patchwork.ozlabs.org/patch/173338/
-
-Add thread_struct.trap_nr and use it to store the last exception
-the thread experienced. In this patch, we populate the field at
-various places where we force_sig_info() to the process.
-
-This is also used in uprobes to determine if the probed instruction
-caused an exception.
-
-Patch applies on the current master branch of Linus' tree (bdc0077af)
-
-Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/powerpc/include/asm/processor.h |    1 +
- arch/powerpc/kernel/process.c        |    2 ++
- arch/powerpc/kernel/traps.c          |    1 +
- arch/powerpc/mm/fault.c              |    1 +
- 4 files changed, 5 insertions(+), 0 deletions(-)
-
-diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
-index 8e2d037..88ceb27 100644
---- a/arch/powerpc/include/asm/processor.h
-+++ b/arch/powerpc/include/asm/processor.h
-@@ -222,6 +222,7 @@ struct thread_struct {
- #endif /* CONFIG_HAVE_HW_BREAKPOINT */
- #endif
- 	unsigned long	dabr;		/* Data address breakpoint register */
-+	unsigned long	trap_nr;	/* last trap # on this thread */
- #ifdef CONFIG_ALTIVEC
- 	/* Complete AltiVec register set */
- 	vector128	vr[32] __attribute__((aligned(16)));
-diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
-index 4937c96..e2a4be7 100644
---- a/arch/powerpc/kernel/process.c
-+++ b/arch/powerpc/kernel/process.c
-@@ -258,6 +258,7 @@ void do_send_trap(struct pt_regs *regs, unsigned long address,
- {
- 	siginfo_t info;
- 
-+	current->thread.trap_nr = signal_code;
- 	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
- 			11, SIGSEGV) == NOTIFY_STOP)
- 		return;
-@@ -275,6 +276,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
- {
- 	siginfo_t info;
- 
-+	current->thread.trap_nr = TRAP_HWBKPT;
- 	if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code,
- 			11, SIGSEGV) == NOTIFY_STOP)
- 		return;
-diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
-index 1589723..8831322 100644
---- a/arch/powerpc/kernel/traps.c
-+++ b/arch/powerpc/kernel/traps.c
-@@ -251,6 +251,7 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
- 	if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs))
- 		local_irq_enable();
- 
-+	current->thread.trap_nr = code;
- 	memset(&info, 0, sizeof(info));
- 	info.si_signo = signr;
- 	info.si_code = code;
-diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
-index 08ffcf5..995f924 100644
---- a/arch/powerpc/mm/fault.c
-+++ b/arch/powerpc/mm/fault.c
-@@ -133,6 +133,7 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address)
- 	up_read(&current->mm->mmap_sem);
- 
- 	if (user_mode(regs)) {
-+		current->thread.trap_nr = BUS_ADRERR;
- 		info.si_signo = SIGBUS;
- 		info.si_errno = 0;
- 		info.si_code = BUS_ADRERR;
--- 
-1.7.5.4
-
diff --git a/features/uprobe/powerpc-Uprobes-port-to-powerpc.patch b/features/uprobe/powerpc-Uprobes-port-to-powerpc.patch
deleted file mode 100644
index 31df9904ba7d4ef6ee969085beba56f6bcb6d670..0000000000000000000000000000000000000000
--- a/features/uprobe/powerpc-Uprobes-port-to-powerpc.patch
+++ /dev/null
@@ -1,372 +0,0 @@
-From c262f3eed4690512f702fec529eda094ad29f5d6 Mon Sep 17 00:00:00 2001
-From: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Date: Wed, 25 Jul 2012 19:20:29 +0000
-Subject: [PATCH 2/2] powerpc: Uprobes port to powerpc
-
-http://patchwork.ozlabs.org/patch/173343/
-
-This is the port of uprobes to powerpc. Usage is similar to x86.
-
-[root@xxxx ~]# ./bin/perf probe -x /lib64/libc.so.6 malloc
-Added new event:
-  probe_libc:malloc    (on 0xb4860)
-
-You can now use it in all perf tools, such as:
-
-	perf record -e probe_libc:malloc -aR sleep 1
-
-[root@xxxx ~]# ./bin/perf record -e probe_libc:malloc -aR sleep 20
-[ perf record: Woken up 22 times to write data ]
-[ perf record: Captured and wrote 5.843 MB perf.data (~255302 samples) ]
-[root@xxxx ~]# ./bin/perf report --stdio
-...
-
-# Samples: 83K of event 'probe_libc:malloc'
-# Event count (approx.): 83484
-#
-# Overhead       Command  Shared Object      Symbol
-# ........  ............  .............  ..........
-#
-    69.05%           tar  libc-2.12.so   [.] malloc
-    28.57%            rm  libc-2.12.so   [.] malloc
-     1.32%  avahi-daemon  libc-2.12.so   [.] malloc
-     0.58%          bash  libc-2.12.so   [.] malloc
-     0.28%          sshd  libc-2.12.so   [.] malloc
-     0.08%    irqbalance  libc-2.12.so   [.] malloc
-     0.05%         bzip2  libc-2.12.so   [.] malloc
-     0.04%         sleep  libc-2.12.so   [.] malloc
-     0.03%    multipathd  libc-2.12.so   [.] malloc
-     0.01%      sendmail  libc-2.12.so   [.] malloc
-     0.01%     automount  libc-2.12.so   [.] malloc
-
-Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/powerpc/Kconfig                   |    3 +
- arch/powerpc/include/asm/thread_info.h |    4 +-
- arch/powerpc/include/asm/uprobes.h     |   50 +++++++++
- arch/powerpc/kernel/Makefile           |    1 +
- arch/powerpc/kernel/signal.c           |    6 +
- arch/powerpc/kernel/uprobes.c          |  174 ++++++++++++++++++++++++++++++++
- 6 files changed, 237 insertions(+), 1 deletions(-)
- create mode 100644 arch/powerpc/include/asm/uprobes.h
- create mode 100644 arch/powerpc/kernel/uprobes.c
-
-diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
-index feab3ba..b2a13ca 100644
---- a/arch/powerpc/Kconfig
-+++ b/arch/powerpc/Kconfig
-@@ -244,6 +244,9 @@ config PPC_OF_PLATFORM_PCI
- config ARCH_SUPPORTS_DEBUG_PAGEALLOC
- 	def_bool y
- 
-+config ARCH_SUPPORTS_UPROBES
-+	def_bool y
-+
- config PPC_ADV_DEBUG_REGS
- 	bool
- 	depends on 40x || BOOKE
-diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
-index 4a741c7..9a30809 100644
---- a/arch/powerpc/include/asm/thread_info.h
-+++ b/arch/powerpc/include/asm/thread_info.h
-@@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void)
- #define TIF_RESTOREALL		11	/* Restore all regs (implies NOERROR) */
- #define TIF_NOERROR		12	/* Force successful syscall return */
- #define TIF_NOTIFY_RESUME	13	/* callback before returning to user */
-+#define TIF_UPROBE		14	/* breakpointed or single-stepping */
- #define TIF_SYSCALL_TRACEPOINT	15	/* syscall tracepoint instrumentation */
- 
- /* as above, but as bit values */
-@@ -125,13 +126,14 @@ static inline struct thread_info *current_thread_info(void)
- #define _TIF_RESTOREALL		(1<<TIF_RESTOREALL)
- #define _TIF_NOERROR		(1<<TIF_NOERROR)
- #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
-+#define _TIF_UPROBE		(1<<TIF_UPROBE)
- #define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
- #define _TIF_RUNLATCH		(1<<TIF_RUNLATCH)
- #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
- 				 _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
- 
- #define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
--				 _TIF_NOTIFY_RESUME)
-+				 _TIF_NOTIFY_RESUME | _TIF_UPROBE)
- #define _TIF_PERSYSCALL_MASK	(_TIF_RESTOREALL|_TIF_NOERROR)
- 
- /* Bits in local_flags */
-diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
-new file mode 100644
-index 0000000..a7f5950
---- /dev/null
-+++ b/arch/powerpc/include/asm/uprobes.h
-@@ -0,0 +1,50 @@
-+#ifndef _ASM_UPROBES_H
-+#define _ASM_UPROBES_H
-+/*
-+ * User-space Probes (UProbes) for powerpc
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2007-2012
-+ *
-+ * Adapted from the x86 port by Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-+ */
-+
-+#include <linux/notifier.h>
-+
-+typedef unsigned int uprobe_opcode_t;
-+
-+#define MAX_UINSN_BYTES			4
-+#define UPROBE_XOL_SLOT_BYTES		(MAX_UINSN_BYTES)
-+
-+#define UPROBE_SWBP_INSN		0x7fe00008
-+#define UPROBE_SWBP_INSN_SIZE		4 /* swbp insn size in bytes */
-+
-+struct arch_uprobe {
-+	u8	insn[MAX_UINSN_BYTES];
-+};
-+
-+struct arch_uprobe_task {
-+	unsigned long	saved_trap_nr;
-+};
-+
-+extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
-+extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs);
-+extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-+extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-+extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
-+extern int  arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
-+extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-+#endif	/* _ASM_UPROBES_H */
-diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
-index f5808a3..1cedb0e 100644
---- a/arch/powerpc/kernel/Makefile
-+++ b/arch/powerpc/kernel/Makefile
-@@ -96,6 +96,7 @@ obj-$(CONFIG_MODULES)		+= ppc_ksyms.o
- obj-$(CONFIG_BOOTX_TEXT)	+= btext.o
- obj-$(CONFIG_SMP)		+= smp.o
- obj-$(CONFIG_KPROBES)		+= kprobes.o
-+obj-$(CONFIG_UPROBES)		+= uprobes.o
- obj-$(CONFIG_PPC_UDBG_16550)	+= legacy_serial.o udbg_16550.o
- obj-$(CONFIG_STACKTRACE)	+= stacktrace.o
- obj-$(CONFIG_SWIOTLB)		+= dma-swiotlb.o
-diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
-index bfc3ec1..e72fb65 100644
---- a/arch/powerpc/kernel/signal.c
-+++ b/arch/powerpc/kernel/signal.c
-@@ -11,6 +11,7 @@
- 
- #include <linux/tracehook.h>
- #include <linux/signal.h>
-+#include <linux/uprobes.h>
- #include <linux/key.h>
- #include <asm/hw_breakpoint.h>
- #include <asm/uaccess.h>
-@@ -187,6 +188,11 @@ static int do_signal(struct pt_regs *regs)
- 
- void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
- {
-+	if (thread_info_flags & _TIF_UPROBE) {
-+		clear_thread_flag(TIF_UPROBE);
-+		uprobe_notify_resume(regs);
-+	}
-+
- 	if (thread_info_flags & _TIF_SIGPENDING)
- 		do_signal(regs);
- 
-diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c
-new file mode 100644
-index 0000000..a193611
---- /dev/null
-+++ b/arch/powerpc/kernel/uprobes.c
-@@ -0,0 +1,174 @@
-+/*
-+ * User-space Probes (UProbes) for powerpc
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2007-2012
-+ *
-+ * Adapted from the x86 port by Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-+ */
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/ptrace.h>
-+#include <linux/uprobes.h>
-+#include <linux/uaccess.h>
-+#include <linux/kdebug.h>
-+
-+#include <asm/sstep.h>
-+
-+#define UPROBE_TRAP_NR	UINT_MAX
-+
-+/**
-+ * arch_uprobe_analyze_insn
-+ * @mm: the probed address space.
-+ * @arch_uprobe: the probepoint information.
-+ * @addr: vaddr to probe.
-+ * Return 0 on success or a -ve number on error.
-+ */
-+int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long addr)
-+{
-+	if (addr & 0x03)
-+		return -EINVAL;
-+	return 0;
-+}
-+
-+/*
-+ * arch_uprobe_pre_xol - prepare to execute out of line.
-+ * @auprobe: the probepoint information.
-+ * @regs: reflects the saved user state of current task.
-+ */
-+int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	struct arch_uprobe_task *autask = &current->utask->autask;
-+
-+	autask->saved_trap_nr = current->thread.trap_nr;
-+	current->thread.trap_nr = UPROBE_TRAP_NR;
-+	regs->nip = current->utask->xol_vaddr;
-+	return 0;
-+}
-+
-+/**
-+ * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
-+ * @regs: Reflects the saved state of the task after it has hit a breakpoint
-+ * instruction.
-+ * Return the address of the breakpoint instruction.
-+ */
-+unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
-+{
-+	return instruction_pointer(regs);
-+}
-+
-+/*
-+ * If xol insn itself traps and generates a signal (SIGILL/SIGSEGV/etc),
-+ * then detect the case where a singlestepped instruction jumps back to its
-+ * own address. It is assumed that anything like do_page_fault/do_trap/etc
-+ * sets thread.trap_nr != -1.
-+ *
-+ * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr,
-+ * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to
-+ * UPROBE_TRAP_NR == -1 set by arch_uprobe_pre_xol().
-+ */
-+bool arch_uprobe_xol_was_trapped(struct task_struct *t)
-+{
-+	if (t->thread.trap_nr != UPROBE_TRAP_NR)
-+		return true;
-+
-+	return false;
-+}
-+
-+/*
-+ * Called after single-stepping. To avoid the SMP problems that can
-+ * occur when we temporarily put back the original opcode to
-+ * single-step, we single-stepped a copy of the instruction.
-+ *
-+ * This function prepares to resume execution after the single-step.
-+ */
-+int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask = current->utask;
-+
-+	WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
-+
-+	current->thread.trap_nr = utask->autask.saved_trap_nr;
-+
-+	/*
-+	 * On powerpc, except for loads and stores, most instructions
-+	 * including ones that alter code flow (branches, calls, returns)
-+	 * are emulated in the kernel. We get here only if the emulation
-+	 * support doesn't exist and have to fix-up the next instruction
-+	 * to be executed.
-+	 */
-+	regs->nip = utask->vaddr + MAX_UINSN_BYTES;
-+	return 0;
-+}
-+
-+/* callback routine for handling exceptions. */
-+int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data)
-+{
-+	struct die_args *args = data;
-+	struct pt_regs *regs = args->regs;
-+
-+	/* We are only interested in userspace traps */
-+	if (regs && !user_mode(regs))
-+		return NOTIFY_DONE;
-+
-+	switch (val) {
-+	case DIE_BPT:
-+		if (uprobe_pre_sstep_notifier(regs))
-+			return NOTIFY_STOP;
-+		break;
-+	case DIE_SSTEP:
-+		if (uprobe_post_sstep_notifier(regs))
-+			return NOTIFY_STOP;
-+	default:
-+		break;
-+	}
-+	return NOTIFY_DONE;
-+}
-+
-+/*
-+ * This function gets called when XOL instruction either gets trapped or
-+ * the thread has a fatal signal, so reset the instruction pointer to its
-+ * probed address.
-+ */
-+void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask = current->utask;
-+
-+	current->thread.trap_nr = utask->autask.saved_trap_nr;
-+	instruction_pointer_set(regs, utask->vaddr);
-+}
-+
-+/*
-+ * See if the instruction can be emulated.
-+ * Returns true if instruction was emulated, false otherwise.
-+ */
-+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	int ret;
-+	unsigned int insn;
-+
-+	memcpy(&insn, auprobe->insn, MAX_UINSN_BYTES);
-+
-+	/*
-+	 * emulate_step() returns 1 if the insn was successfully emulated.
-+	 * For all other cases, we need to single-step in hardware.
-+	 */
-+	ret = emulate_step(regs, insn);
-+	if (ret > 0)
-+		return true;
-+
-+	return false;
-+}
--- 
-1.7.5.4
-
diff --git a/features/uprobe/powerpc-uprobes-removed-external-declaration-of-upro.patch b/features/uprobe/powerpc-uprobes-removed-external-declaration-of-upro.patch
deleted file mode 100644
index 478d448bf0709dc2a53fa896d2e81e5bf5800aee..0000000000000000000000000000000000000000
--- a/features/uprobe/powerpc-uprobes-removed-external-declaration-of-upro.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 6f70bc1d54887ad3a97dd9c9ae52f86302274932 Mon Sep 17 00:00:00 2001
-From: Paul Barrette <paul.barrette@windriver.com>
-Date: Tue, 12 Jun 2012 14:24:12 -0400
-Subject: [PATCH 24/24] powerpc: uprobes: removed external declaration of
- uprobe_get_swbp_addr.
-
-uprobe_get_swbp_addr is declared as static inline in linux/uprobes.h.
-Redeclaring it differently breaks compilation.
-
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/powerpc/include/asm/uprobes.h |    1 -
- 1 files changed, 0 insertions(+), 1 deletions(-)
-
-diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h
-index bd9e8412..ed6197b 100644
---- a/arch/powerpc/include/asm/uprobes.h
-+++ b/arch/powerpc/include/asm/uprobes.h
-@@ -40,7 +40,6 @@ struct arch_uprobe_task {
- };
- 
- extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr);
--extern unsigned long uprobe_get_swbp_addr(struct pt_regs *regs);
- extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
- extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
- extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
--- 
-1.7.5.4
-
diff --git a/features/uprobe/task_work_add-generic-process-context-callbacks.patch b/features/uprobe/task_work_add-generic-process-context-callbacks.patch
deleted file mode 100644
index 4bd791ff146ddf72f38d76b8dc5ebf3b297ef1c2..0000000000000000000000000000000000000000
--- a/features/uprobe/task_work_add-generic-process-context-callbacks.patch
+++ /dev/null
@@ -1,287 +0,0 @@
-From 5ee34dd5dffe2d2a971ee208de419be114ecf77e Mon Sep 17 00:00:00 2001
-From: Oleg Nesterov <oleg@redhat.com>
-Date: Fri, 11 May 2012 10:59:07 +1000
-Subject: [PATCH 2/6] task_work_add: generic process-context callbacks
-
-commit e73f8959af0439d114847eab5a8a5ce48f1217c4 upstream.
-
-Provide a simple mechanism that allows running code in the (nonatomic)
-context of the arbitrary task.
-
-The caller does task_work_add(task, task_work) and this task executes
-task_work->func() either from do_notify_resume() or from do_exit().  The
-callback can rely on PF_EXITING to detect the latter case.
-
-"struct task_work" can be embedded in another struct, still it has "void
-*data" to handle the most common/simple case.
-
-This allows us to kill the ->replacement_session_keyring hack, and
-potentially this can have more users.
-
-Performance-wise, this adds 2 "unlikely(!hlist_empty())" checks into
-tracehook_notify_resume() and do_exit().  But at the same time we can
-remove the "replacement_session_keyring != NULL" checks from
-arch/*/signal.c and exit_creds().
-
-Note: task_work_add/task_work_run abuses ->pi_lock.  This is only because
-this lock is already used by lookup_pi_state() to synchronize with
-do_exit() setting PF_EXITING.  Fortunately the scope of this lock in
-task_work.c is really tiny, and the code is unlikely anyway.
-
-Signed-off-by: Oleg Nesterov <oleg@redhat.com>
-Acked-by: David Howells <dhowells@redhat.com>
-Cc: Thomas Gleixner <tglx@linutronix.de>
-Cc: Richard Kuo <rkuo@codeaurora.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Alexander Gordeev <agordeev@redhat.com>
-Cc: Chris Zankel <chris@zankel.net>
-Cc: David Smith <dsmith@redhat.com>
-Cc: "Frank Ch. Eigler" <fche@redhat.com>
-Cc: Geert Uytterhoeven <geert@linux-m68k.org>
-Cc: Larry Woodman <lwoodman@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Tejun Heo <tj@kernel.org>
-Cc: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
-Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/sched.h     |    2 +
- include/linux/task_work.h |   33 +++++++++++++++++
- include/linux/tracehook.h |   11 ++++++
- kernel/Makefile           |    2 +-
- kernel/exit.c             |    5 ++-
- kernel/fork.c             |    1 +
- kernel/task_work.c        |   84 +++++++++++++++++++++++++++++++++++++++++++++
- 7 files changed, 136 insertions(+), 2 deletions(-)
- create mode 100644 include/linux/task_work.h
- create mode 100644 kernel/task_work.c
-
-diff --git a/include/linux/sched.h b/include/linux/sched.h
-index 7bcc634..d62c928 100644
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -1447,6 +1447,8 @@ struct task_struct {
- 	int (*notifier)(void *priv);
- 	void *notifier_data;
- 	sigset_t *notifier_mask;
-+	struct hlist_head task_works;
-+
- 	struct audit_context *audit_context;
- #ifdef CONFIG_AUDITSYSCALL
- 	uid_t loginuid;
-diff --git a/include/linux/task_work.h b/include/linux/task_work.h
-new file mode 100644
-index 0000000..294d5d5
---- /dev/null
-+++ b/include/linux/task_work.h
-@@ -0,0 +1,33 @@
-+#ifndef _LINUX_TASK_WORK_H
-+#define _LINUX_TASK_WORK_H
-+
-+#include <linux/list.h>
-+#include <linux/sched.h>
-+
-+struct task_work;
-+typedef void (*task_work_func_t)(struct task_work *);
-+
-+struct task_work {
-+	struct hlist_node hlist;
-+	task_work_func_t func;
-+	void *data;
-+};
-+
-+static inline void
-+init_task_work(struct task_work *twork, task_work_func_t func, void *data)
-+{
-+	twork->func = func;
-+	twork->data = data;
-+}
-+
-+int task_work_add(struct task_struct *task, struct task_work *twork, bool);
-+struct task_work *task_work_cancel(struct task_struct *, task_work_func_t);
-+void task_work_run(void);
-+
-+static inline void exit_task_work(struct task_struct *task)
-+{
-+	if (unlikely(!hlist_empty(&task->task_works)))
-+		task_work_run();
-+}
-+
-+#endif	/* _LINUX_TASK_WORK_H */
-diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index d28ceaf..ea9558f 100644
---- a/include/linux/tracehook.h
-+++ b/include/linux/tracehook.h
-@@ -49,6 +49,7 @@
- #include <linux/sched.h>
- #include <linux/ptrace.h>
- #include <linux/security.h>
-+#include <linux/task_work.h>
- struct linux_binprm;
- 
- /*
-@@ -165,8 +166,10 @@ static inline void tracehook_signal_handler(int sig, siginfo_t *info,
-  */
- static inline void set_notify_resume(struct task_struct *task)
- {
-+#ifdef TIF_NOTIFY_RESUME
- 	if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
- 		kick_process(task);
-+#endif
- }
- 
- /**
-@@ -186,6 +189,14 @@ static inline void tracehook_notify_resume(struct pt_regs *regs)
- {
- 	if (current->replacement_session_keyring)
- 		key_replace_session_keyring();
-+	/*
-+	 * The caller just cleared TIF_NOTIFY_RESUME. This barrier
-+	 * pairs with task_work_add()->set_notify_resume() after
-+	 * hlist_add_head(task->task_works);
-+	 */
-+	smp_mb__after_clear_bit();
-+	if (unlikely(!hlist_empty(&current->task_works)))
-+		task_work_run();
- }
- #endif	/* TIF_NOTIFY_RESUME */
- 
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 633b548..d06c109 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -5,7 +5,7 @@
- obj-y     = fork.o exec_domain.o panic.o printk.o \
- 	    cpu.o exit.o itimer.o time.o softirq.o resource.o \
- 	    sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
--	    signal.o sys.o kmod.o workqueue.o pid.o \
-+	    signal.o sys.o kmod.o workqueue.o pid.o task_work.o \
- 	    rcupdate.o extable.o params.o posix-timers.o \
- 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
- 	    hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
-diff --git a/kernel/exit.c b/kernel/exit.c
-index 9d81012..36516fc 100644
---- a/kernel/exit.c
-+++ b/kernel/exit.c
-@@ -947,11 +947,14 @@ void do_exit(long code)
- 	exit_signals(tsk);  /* sets PF_EXITING */
- 	/*
- 	 * tsk->flags are checked in the futex code to protect against
--	 * an exiting task cleaning up the robust pi futexes.
-+	 * an exiting task cleaning up the robust pi futexes, and in
-+	 * task_work_add() to avoid the race with exit_task_work().
- 	 */
- 	smp_mb();
- 	raw_spin_unlock_wait(&tsk->pi_lock);
- 
-+	exit_task_work(tsk);
-+
- 	exit_irq_thread();
- 
- 	if (unlikely(in_atomic()))
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 764efe3..6c77a93 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -1394,6 +1394,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
- 	 */
- 	p->group_leader = p;
- 	INIT_LIST_HEAD(&p->thread_group);
-+	INIT_HLIST_HEAD(&p->task_works);
- 
- 	/* Now that the task is set up, run cgroup callbacks if
- 	 * necessary. We need to run them before the task is visible
-diff --git a/kernel/task_work.c b/kernel/task_work.c
-new file mode 100644
-index 0000000..82d1c79
---- /dev/null
-+++ b/kernel/task_work.c
-@@ -0,0 +1,84 @@
-+#include <linux/spinlock.h>
-+#include <linux/task_work.h>
-+#include <linux/tracehook.h>
-+
-+int
-+task_work_add(struct task_struct *task, struct task_work *twork, bool notify)
-+{
-+	unsigned long flags;
-+	int err = -ESRCH;
-+
-+#ifndef TIF_NOTIFY_RESUME
-+	if (notify)
-+		return -ENOTSUPP;
-+#endif
-+	/*
-+	 * We must not insert the new work if the task has already passed
-+	 * exit_task_work(). We rely on do_exit()->raw_spin_unlock_wait()
-+	 * and check PF_EXITING under pi_lock.
-+	 */
-+	raw_spin_lock_irqsave(&task->pi_lock, flags);
-+	if (likely(!(task->flags & PF_EXITING))) {
-+		hlist_add_head(&twork->hlist, &task->task_works);
-+		err = 0;
-+	}
-+	raw_spin_unlock_irqrestore(&task->pi_lock, flags);
-+
-+	/* test_and_set_bit() implies mb(), see tracehook_notify_resume(). */
-+	if (likely(!err) && notify)
-+		set_notify_resume(task);
-+	return err;
-+}
-+
-+struct task_work *
-+task_work_cancel(struct task_struct *task, task_work_func_t func)
-+{
-+	unsigned long flags;
-+	struct task_work *twork;
-+	struct hlist_node *pos;
-+
-+	raw_spin_lock_irqsave(&task->pi_lock, flags);
-+	hlist_for_each_entry(twork, pos, &task->task_works, hlist) {
-+		if (twork->func == func) {
-+			hlist_del(&twork->hlist);
-+			goto found;
-+		}
-+	}
-+	twork = NULL;
-+ found:
-+	raw_spin_unlock_irqrestore(&task->pi_lock, flags);
-+
-+	return twork;
-+}
-+
-+void task_work_run(void)
-+{
-+	struct task_struct *task = current;
-+	struct hlist_head task_works;
-+	struct hlist_node *pos;
-+
-+	raw_spin_lock_irq(&task->pi_lock);
-+	hlist_move_list(&task->task_works, &task_works);
-+	raw_spin_unlock_irq(&task->pi_lock);
-+
-+	if (unlikely(hlist_empty(&task_works)))
-+		return;
-+	/*
-+	 * We use hlist to save the space in task_struct, but we want fifo.
-+	 * Find the last entry, the list should be short, then process them
-+	 * in reverse order.
-+	 */
-+	for (pos = task_works.first; pos->next; pos = pos->next)
-+		;
-+
-+	for (;;) {
-+		struct hlist_node **pprev = pos->pprev;
-+		struct task_work *twork = container_of(pos, struct task_work,
-+							hlist);
-+		twork->func(twork);
-+
-+		if (pprev == &task_works.first)
-+			break;
-+		pos = container_of(pprev, struct hlist_node, next);
-+	}
-+}
--- 
-1.7.5.4
-
diff --git a/features/uprobe/tracing-Extract-out-common-code-for-kprobes-uprobes-.patch b/features/uprobe/tracing-Extract-out-common-code-for-kprobes-uprobes-.patch
deleted file mode 100644
index 6a11c0d270c7288a968d0b2486156529a21f6a1c..0000000000000000000000000000000000000000
--- a/features/uprobe/tracing-Extract-out-common-code-for-kprobes-uprobes-.patch
+++ /dev/null
@@ -1,2083 +0,0 @@
-From b9b7281e08e0f3c38a5f9e333d9c5481615d8211 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 9 Apr 2012 14:41:44 +0530
-Subject: [PATCH 17/24] tracing: Extract out common code for kprobes/uprobes
- trace events
-
-Move parts of trace_kprobe.c that can be shared with upcoming
-trace_uprobe.c. Common code to kernel/trace/trace_probe.h and
-kernel/trace/trace_probe.c. There are no functional changes.
-
-commit 8ab83f56475ec9151645a888dfe1941f4a92091d upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Acked-by: Steven Rostedt <rostedt@goodmis.org>
-Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120409091144.8343.76218.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- kernel/trace/Kconfig        |    4 +
- kernel/trace/Makefile       |    1 +
- kernel/trace/trace_kprobe.c |  889 +------------------------------------------
- kernel/trace/trace_probe.c  |  833 ++++++++++++++++++++++++++++++++++++++++
- kernel/trace/trace_probe.h  |  160 ++++++++
- 5 files changed, 1016 insertions(+), 871 deletions(-)
- create mode 100644 kernel/trace/trace_probe.c
- create mode 100644 kernel/trace/trace_probe.h
-
-diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
-index a1d2849..ce5a5c5 100644
---- a/kernel/trace/Kconfig
-+++ b/kernel/trace/Kconfig
-@@ -373,6 +373,7 @@ config KPROBE_EVENT
- 	depends on HAVE_REGS_AND_STACK_ACCESS_API
- 	bool "Enable kprobes-based dynamic events"
- 	select TRACING
-+	select PROBE_EVENTS
- 	default y
- 	help
- 	  This allows the user to add tracing events (similar to tracepoints)
-@@ -385,6 +386,9 @@ config KPROBE_EVENT
- 	  This option is also required by perf-probe subcommand of perf tools.
- 	  If you want to use perf tools, this option is strongly recommended.
- 
-+config PROBE_EVENTS
-+	def_bool n
-+
- config DYNAMIC_FTRACE
- 	bool "enable/disable ftrace tracepoints dynamically"
- 	depends on FUNCTION_TRACER
-diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
-index 5f39a07..fa10d5c 100644
---- a/kernel/trace/Makefile
-+++ b/kernel/trace/Makefile
-@@ -61,5 +61,6 @@ endif
- ifeq ($(CONFIG_TRACING),y)
- obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
- endif
-+obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
- 
- libftrace-y := ftrace.o
-diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
-index 4f935f8..f8b7773 100644
---- a/kernel/trace/trace_kprobe.c
-+++ b/kernel/trace/trace_kprobe.c
-@@ -19,547 +19,15 @@
- 
- #include <linux/module.h>
- #include <linux/uaccess.h>
--#include <linux/kprobes.h>
--#include <linux/seq_file.h>
--#include <linux/slab.h>
--#include <linux/smp.h>
--#include <linux/debugfs.h>
--#include <linux/types.h>
--#include <linux/string.h>
--#include <linux/ctype.h>
--#include <linux/ptrace.h>
--#include <linux/perf_event.h>
--#include <linux/stringify.h>
--#include <linux/limits.h>
--#include <asm/bitsperlong.h>
--
--#include "trace.h"
--#include "trace_output.h"
--
--#define MAX_TRACE_ARGS 128
--#define MAX_ARGSTR_LEN 63
--#define MAX_EVENT_NAME_LEN 64
--#define MAX_STRING_SIZE PATH_MAX
--#define KPROBE_EVENT_SYSTEM "kprobes"
--
--/* Reserved field names */
--#define FIELD_STRING_IP "__probe_ip"
--#define FIELD_STRING_RETIP "__probe_ret_ip"
--#define FIELD_STRING_FUNC "__probe_func"
--
--const char *reserved_field_names[] = {
--	"common_type",
--	"common_flags",
--	"common_preempt_count",
--	"common_pid",
--	"common_tgid",
--	FIELD_STRING_IP,
--	FIELD_STRING_RETIP,
--	FIELD_STRING_FUNC,
--};
--
--/* Printing function type */
--typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *,
--				 void *);
--#define PRINT_TYPE_FUNC_NAME(type)	print_type_##type
--#define PRINT_TYPE_FMT_NAME(type)	print_type_format_##type
--
--/* Printing  in basic type function template */
--#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)			\
--static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,	\
--						const char *name,	\
--						void *data, void *ent)\
--{									\
--	return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
--}									\
--static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
--
--DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
--DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
--DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
--DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
--DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
--DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
--DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
--DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
--
--/* data_rloc: data relative location, compatible with u32 */
--#define make_data_rloc(len, roffs)	\
--	(((u32)(len) << 16) | ((u32)(roffs) & 0xffff))
--#define get_rloc_len(dl)	((u32)(dl) >> 16)
--#define get_rloc_offs(dl)	((u32)(dl) & 0xffff)
--
--static inline void *get_rloc_data(u32 *dl)
--{
--	return (u8 *)dl + get_rloc_offs(*dl);
--}
--
--/* For data_loc conversion */
--static inline void *get_loc_data(u32 *dl, void *ent)
--{
--	return (u8 *)ent + get_rloc_offs(*dl);
--}
--
--/*
-- * Convert data_rloc to data_loc:
-- *  data_rloc stores the offset from data_rloc itself, but data_loc
-- *  stores the offset from event entry.
-- */
--#define convert_rloc_to_loc(dl, offs)	((u32)(dl) + (offs))
--
--/* For defining macros, define string/string_size types */
--typedef u32 string;
--typedef u32 string_size;
--
--/* Print type function for string type */
--static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
--						  const char *name,
--						  void *data, void *ent)
--{
--	int len = *(u32 *)data >> 16;
--
--	if (!len)
--		return trace_seq_printf(s, " %s=(fault)", name);
--	else
--		return trace_seq_printf(s, " %s=\"%s\"", name,
--					(const char *)get_loc_data(data, ent));
--}
--static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
--
--/* Data fetch function type */
--typedef	void (*fetch_func_t)(struct pt_regs *, void *, void *);
--
--struct fetch_param {
--	fetch_func_t	fn;
--	void *data;
--};
--
--static __kprobes void call_fetch(struct fetch_param *fprm,
--				 struct pt_regs *regs, void *dest)
--{
--	return fprm->fn(regs, fprm->data, dest);
--}
--
--#define FETCH_FUNC_NAME(method, type)	fetch_##method##_##type
--/*
-- * Define macro for basic types - we don't need to define s* types, because
-- * we have to care only about bitwidth at recording time.
-- */
--#define DEFINE_BASIC_FETCH_FUNCS(method) \
--DEFINE_FETCH_##method(u8)		\
--DEFINE_FETCH_##method(u16)		\
--DEFINE_FETCH_##method(u32)		\
--DEFINE_FETCH_##method(u64)
--
--#define CHECK_FETCH_FUNCS(method, fn)			\
--	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
--	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
--	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
--	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
--	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
--	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
--	 && (fn != NULL))
--
--/* Data fetch function templates */
--#define DEFINE_FETCH_reg(type)						\
--static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,	\
--					void *offset, void *dest)	\
--{									\
--	*(type *)dest = (type)regs_get_register(regs,			\
--				(unsigned int)((unsigned long)offset));	\
--}
--DEFINE_BASIC_FETCH_FUNCS(reg)
--/* No string on the register */
--#define fetch_reg_string NULL
--#define fetch_reg_string_size NULL
--
--#define DEFINE_FETCH_stack(type)					\
--static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
--					  void *offset, void *dest)	\
--{									\
--	*(type *)dest = (type)regs_get_kernel_stack_nth(regs,		\
--				(unsigned int)((unsigned long)offset));	\
--}
--DEFINE_BASIC_FETCH_FUNCS(stack)
--/* No string on the stack entry */
--#define fetch_stack_string NULL
--#define fetch_stack_string_size NULL
--
--#define DEFINE_FETCH_retval(type)					\
--static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
--					  void *dummy, void *dest)	\
--{									\
--	*(type *)dest = (type)regs_return_value(regs);			\
--}
--DEFINE_BASIC_FETCH_FUNCS(retval)
--/* No string on the retval */
--#define fetch_retval_string NULL
--#define fetch_retval_string_size NULL
--
--#define DEFINE_FETCH_memory(type)					\
--static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
--					  void *addr, void *dest)	\
--{									\
--	type retval;							\
--	if (probe_kernel_address(addr, retval))				\
--		*(type *)dest = 0;					\
--	else								\
--		*(type *)dest = retval;					\
--}
--DEFINE_BASIC_FETCH_FUNCS(memory)
--/*
-- * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
-- * length and relative data location.
-- */
--static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
--						      void *addr, void *dest)
--{
--	long ret;
--	int maxlen = get_rloc_len(*(u32 *)dest);
--	u8 *dst = get_rloc_data(dest);
--	u8 *src = addr;
--	mm_segment_t old_fs = get_fs();
--	if (!maxlen)
--		return;
--	/*
--	 * Try to get string again, since the string can be changed while
--	 * probing.
--	 */
--	set_fs(KERNEL_DS);
--	pagefault_disable();
--	do
--		ret = __copy_from_user_inatomic(dst++, src++, 1);
--	while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
--	dst[-1] = '\0';
--	pagefault_enable();
--	set_fs(old_fs);
--
--	if (ret < 0) {	/* Failed to fetch string */
--		((u8 *)get_rloc_data(dest))[0] = '\0';
--		*(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
--	} else
--		*(u32 *)dest = make_data_rloc(src - (u8 *)addr,
--					      get_rloc_offs(*(u32 *)dest));
--}
--/* Return the length of string -- including null terminal byte */
--static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
--							void *addr, void *dest)
--{
--	int ret, len = 0;
--	u8 c;
--	mm_segment_t old_fs = get_fs();
--
--	set_fs(KERNEL_DS);
--	pagefault_disable();
--	do {
--		ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
--		len++;
--	} while (c && ret == 0 && len < MAX_STRING_SIZE);
--	pagefault_enable();
--	set_fs(old_fs);
--
--	if (ret < 0)	/* Failed to check the length */
--		*(u32 *)dest = 0;
--	else
--		*(u32 *)dest = len;
--}
--
--/* Memory fetching by symbol */
--struct symbol_cache {
--	char *symbol;
--	long offset;
--	unsigned long addr;
--};
--
--static unsigned long update_symbol_cache(struct symbol_cache *sc)
--{
--	sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
--	if (sc->addr)
--		sc->addr += sc->offset;
--	return sc->addr;
--}
--
--static void free_symbol_cache(struct symbol_cache *sc)
--{
--	kfree(sc->symbol);
--	kfree(sc);
--}
--
--static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
--{
--	struct symbol_cache *sc;
--
--	if (!sym || strlen(sym) == 0)
--		return NULL;
--	sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
--	if (!sc)
--		return NULL;
--
--	sc->symbol = kstrdup(sym, GFP_KERNEL);
--	if (!sc->symbol) {
--		kfree(sc);
--		return NULL;
--	}
--	sc->offset = offset;
- 
--	update_symbol_cache(sc);
--	return sc;
--}
--
--#define DEFINE_FETCH_symbol(type)					\
--static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
--					  void *data, void *dest)	\
--{									\
--	struct symbol_cache *sc = data;					\
--	if (sc->addr)							\
--		fetch_memory_##type(regs, (void *)sc->addr, dest);	\
--	else								\
--		*(type *)dest = 0;					\
--}
--DEFINE_BASIC_FETCH_FUNCS(symbol)
--DEFINE_FETCH_symbol(string)
--DEFINE_FETCH_symbol(string_size)
--
--/* Dereference memory access function */
--struct deref_fetch_param {
--	struct fetch_param orig;
--	long offset;
--};
--
--#define DEFINE_FETCH_deref(type)					\
--static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
--					    void *data, void *dest)	\
--{									\
--	struct deref_fetch_param *dprm = data;				\
--	unsigned long addr;						\
--	call_fetch(&dprm->orig, regs, &addr);				\
--	if (addr) {							\
--		addr += dprm->offset;					\
--		fetch_memory_##type(regs, (void *)addr, dest);		\
--	} else								\
--		*(type *)dest = 0;					\
--}
--DEFINE_BASIC_FETCH_FUNCS(deref)
--DEFINE_FETCH_deref(string)
--DEFINE_FETCH_deref(string_size)
--
--static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
--{
--	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
--		update_deref_fetch_param(data->orig.data);
--	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
--		update_symbol_cache(data->orig.data);
--}
--
--static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
--{
--	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
--		free_deref_fetch_param(data->orig.data);
--	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
--		free_symbol_cache(data->orig.data);
--	kfree(data);
--}
--
--/* Bitfield fetch function */
--struct bitfield_fetch_param {
--	struct fetch_param orig;
--	unsigned char hi_shift;
--	unsigned char low_shift;
--};
-+#include "trace_probe.h"
- 
--#define DEFINE_FETCH_bitfield(type)					\
--static __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
--					    void *data, void *dest)	\
--{									\
--	struct bitfield_fetch_param *bprm = data;			\
--	type buf = 0;							\
--	call_fetch(&bprm->orig, regs, &buf);				\
--	if (buf) {							\
--		buf <<= bprm->hi_shift;					\
--		buf >>= bprm->low_shift;				\
--	}								\
--	*(type *)dest = buf;						\
--}
--DEFINE_BASIC_FETCH_FUNCS(bitfield)
--#define fetch_bitfield_string NULL
--#define fetch_bitfield_string_size NULL
--
--static __kprobes void
--update_bitfield_fetch_param(struct bitfield_fetch_param *data)
--{
--	/*
--	 * Don't check the bitfield itself, because this must be the
--	 * last fetch function.
--	 */
--	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
--		update_deref_fetch_param(data->orig.data);
--	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
--		update_symbol_cache(data->orig.data);
--}
--
--static __kprobes void
--free_bitfield_fetch_param(struct bitfield_fetch_param *data)
--{
--	/*
--	 * Don't check the bitfield itself, because this must be the
--	 * last fetch function.
--	 */
--	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
--		free_deref_fetch_param(data->orig.data);
--	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
--		free_symbol_cache(data->orig.data);
--	kfree(data);
--}
--
--/* Default (unsigned long) fetch type */
--#define __DEFAULT_FETCH_TYPE(t) u##t
--#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
--#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
--#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
--
--/* Fetch types */
--enum {
--	FETCH_MTD_reg = 0,
--	FETCH_MTD_stack,
--	FETCH_MTD_retval,
--	FETCH_MTD_memory,
--	FETCH_MTD_symbol,
--	FETCH_MTD_deref,
--	FETCH_MTD_bitfield,
--	FETCH_MTD_END,
--};
--
--#define ASSIGN_FETCH_FUNC(method, type)	\
--	[FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
--
--#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)	\
--	{.name = _name,				\
--	 .size = _size,					\
--	 .is_signed = sign,				\
--	 .print = PRINT_TYPE_FUNC_NAME(ptype),		\
--	 .fmt = PRINT_TYPE_FMT_NAME(ptype),		\
--	 .fmttype = _fmttype,				\
--	 .fetch = {					\
--ASSIGN_FETCH_FUNC(reg, ftype),				\
--ASSIGN_FETCH_FUNC(stack, ftype),			\
--ASSIGN_FETCH_FUNC(retval, ftype),			\
--ASSIGN_FETCH_FUNC(memory, ftype),			\
--ASSIGN_FETCH_FUNC(symbol, ftype),			\
--ASSIGN_FETCH_FUNC(deref, ftype),			\
--ASSIGN_FETCH_FUNC(bitfield, ftype),			\
--	  }						\
--	}
--
--#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)			\
--	__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
--
--#define FETCH_TYPE_STRING 0
--#define FETCH_TYPE_STRSIZE 1
--
--/* Fetch type information table */
--static const struct fetch_type {
--	const char	*name;		/* Name of type */
--	size_t		size;		/* Byte size of type */
--	int		is_signed;	/* Signed flag */
--	print_type_func_t	print;	/* Print functions */
--	const char	*fmt;		/* Fromat string */
--	const char	*fmttype;	/* Name in format file */
--	/* Fetch functions */
--	fetch_func_t	fetch[FETCH_MTD_END];
--} fetch_type_table[] = {
--	/* Special types */
--	[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
--					sizeof(u32), 1, "__data_loc char[]"),
--	[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
--					string_size, sizeof(u32), 0, "u32"),
--	/* Basic types */
--	ASSIGN_FETCH_TYPE(u8,  u8,  0),
--	ASSIGN_FETCH_TYPE(u16, u16, 0),
--	ASSIGN_FETCH_TYPE(u32, u32, 0),
--	ASSIGN_FETCH_TYPE(u64, u64, 0),
--	ASSIGN_FETCH_TYPE(s8,  u8,  1),
--	ASSIGN_FETCH_TYPE(s16, u16, 1),
--	ASSIGN_FETCH_TYPE(s32, u32, 1),
--	ASSIGN_FETCH_TYPE(s64, u64, 1),
--};
--
--static const struct fetch_type *find_fetch_type(const char *type)
--{
--	int i;
--
--	if (!type)
--		type = DEFAULT_FETCH_TYPE_STR;
--
--	/* Special case: bitfield */
--	if (*type == 'b') {
--		unsigned long bs;
--		type = strchr(type, '/');
--		if (!type)
--			goto fail;
--		type++;
--		if (strict_strtoul(type, 0, &bs))
--			goto fail;
--		switch (bs) {
--		case 8:
--			return find_fetch_type("u8");
--		case 16:
--			return find_fetch_type("u16");
--		case 32:
--			return find_fetch_type("u32");
--		case 64:
--			return find_fetch_type("u64");
--		default:
--			goto fail;
--		}
--	}
--
--	for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
--		if (strcmp(type, fetch_type_table[i].name) == 0)
--			return &fetch_type_table[i];
--fail:
--	return NULL;
--}
--
--/* Special function : only accept unsigned long */
--static __kprobes void fetch_stack_address(struct pt_regs *regs,
--					  void *dummy, void *dest)
--{
--	*(unsigned long *)dest = kernel_stack_pointer(regs);
--}
--
--static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
--					    fetch_func_t orig_fn)
--{
--	int i;
--
--	if (type != &fetch_type_table[FETCH_TYPE_STRING])
--		return NULL;	/* Only string type needs size function */
--	for (i = 0; i < FETCH_MTD_END; i++)
--		if (type->fetch[i] == orig_fn)
--			return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
--
--	WARN_ON(1);	/* This should not happen */
--	return NULL;
--}
-+#define KPROBE_EVENT_SYSTEM "kprobes"
- 
- /**
-  * Kprobe event core functions
-  */
- 
--struct probe_arg {
--	struct fetch_param	fetch;
--	struct fetch_param	fetch_size;
--	unsigned int		offset;	/* Offset from argument entry */
--	const char		*name;	/* Name of this argument */
--	const char		*comm;	/* Command of this argument */
--	const struct fetch_type	*type;	/* Type of this argument */
--};
--
--/* Flags for trace_probe */
--#define TP_FLAG_TRACE	1
--#define TP_FLAG_PROFILE	2
--#define TP_FLAG_REGISTERED 4
--
- struct trace_probe {
- 	struct list_head	list;
- 	struct kretprobe	rp;	/* Use rp.kp for kprobe use */
-@@ -631,18 +99,6 @@ static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
- static int kretprobe_dispatcher(struct kretprobe_instance *ri,
- 				struct pt_regs *regs);
- 
--/* Check the name is good for event/group/fields */
--static int is_good_name(const char *name)
--{
--	if (!isalpha(*name) && *name != '_')
--		return 0;
--	while (*++name != '\0') {
--		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
--			return 0;
--	}
--	return 1;
--}
--
- /*
-  * Allocate new trace_probe and initialize it (including kprobes).
-  */
-@@ -702,34 +158,12 @@ error:
- 	return ERR_PTR(ret);
- }
- 
--static void update_probe_arg(struct probe_arg *arg)
--{
--	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
--		update_bitfield_fetch_param(arg->fetch.data);
--	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
--		update_deref_fetch_param(arg->fetch.data);
--	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
--		update_symbol_cache(arg->fetch.data);
--}
--
--static void free_probe_arg(struct probe_arg *arg)
--{
--	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
--		free_bitfield_fetch_param(arg->fetch.data);
--	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
--		free_deref_fetch_param(arg->fetch.data);
--	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
--		free_symbol_cache(arg->fetch.data);
--	kfree(arg->name);
--	kfree(arg->comm);
--}
--
- static void free_trace_probe(struct trace_probe *tp)
- {
- 	int i;
- 
- 	for (i = 0; i < tp->nr_args; i++)
--		free_probe_arg(&tp->args[i]);
-+		traceprobe_free_probe_arg(&tp->args[i]);
- 
- 	kfree(tp->call.class->system);
- 	kfree(tp->call.name);
-@@ -787,7 +221,7 @@ static int __register_trace_probe(struct trace_probe *tp)
- 		return -EINVAL;
- 
- 	for (i = 0; i < tp->nr_args; i++)
--		update_probe_arg(&tp->args[i]);
-+		traceprobe_update_arg(&tp->args[i]);
- 
- 	/* Set/clear disabled flag according to tp->flag */
- 	if (trace_probe_is_enabled(tp))
-@@ -919,227 +353,6 @@ static struct notifier_block trace_probe_module_nb = {
- 	.priority = 1	/* Invoked after kprobe module callback */
- };
- 
--/* Split symbol and offset. */
--static int split_symbol_offset(char *symbol, unsigned long *offset)
--{
--	char *tmp;
--	int ret;
--
--	if (!offset)
--		return -EINVAL;
--
--	tmp = strchr(symbol, '+');
--	if (tmp) {
--		/* skip sign because strict_strtol doesn't accept '+' */
--		ret = strict_strtoul(tmp + 1, 0, offset);
--		if (ret)
--			return ret;
--		*tmp = '\0';
--	} else
--		*offset = 0;
--	return 0;
--}
--
--#define PARAM_MAX_ARGS 16
--#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
--
--static int parse_probe_vars(char *arg, const struct fetch_type *t,
--			    struct fetch_param *f, bool is_return)
--{
--	int ret = 0;
--	unsigned long param;
--
--	if (strcmp(arg, "retval") == 0) {
--		if (is_return)
--			f->fn = t->fetch[FETCH_MTD_retval];
--		else
--			ret = -EINVAL;
--	} else if (strncmp(arg, "stack", 5) == 0) {
--		if (arg[5] == '\0') {
--			if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
--				f->fn = fetch_stack_address;
--			else
--				ret = -EINVAL;
--		} else if (isdigit(arg[5])) {
--			ret = strict_strtoul(arg + 5, 10, &param);
--			if (ret || param > PARAM_MAX_STACK)
--				ret = -EINVAL;
--			else {
--				f->fn = t->fetch[FETCH_MTD_stack];
--				f->data = (void *)param;
--			}
--		} else
--			ret = -EINVAL;
--	} else
--		ret = -EINVAL;
--	return ret;
--}
--
--/* Recursive argument parser */
--static int __parse_probe_arg(char *arg, const struct fetch_type *t,
--			     struct fetch_param *f, bool is_return)
--{
--	int ret = 0;
--	unsigned long param;
--	long offset;
--	char *tmp;
--
--	switch (arg[0]) {
--	case '$':
--		ret = parse_probe_vars(arg + 1, t, f, is_return);
--		break;
--	case '%':	/* named register */
--		ret = regs_query_register_offset(arg + 1);
--		if (ret >= 0) {
--			f->fn = t->fetch[FETCH_MTD_reg];
--			f->data = (void *)(unsigned long)ret;
--			ret = 0;
--		}
--		break;
--	case '@':	/* memory or symbol */
--		if (isdigit(arg[1])) {
--			ret = strict_strtoul(arg + 1, 0, &param);
--			if (ret)
--				break;
--			f->fn = t->fetch[FETCH_MTD_memory];
--			f->data = (void *)param;
--		} else {
--			ret = split_symbol_offset(arg + 1, &offset);
--			if (ret)
--				break;
--			f->data = alloc_symbol_cache(arg + 1, offset);
--			if (f->data)
--				f->fn = t->fetch[FETCH_MTD_symbol];
--		}
--		break;
--	case '+':	/* deref memory */
--		arg++;	/* Skip '+', because strict_strtol() rejects it. */
--	case '-':
--		tmp = strchr(arg, '(');
--		if (!tmp)
--			break;
--		*tmp = '\0';
--		ret = strict_strtol(arg, 0, &offset);
--		if (ret)
--			break;
--		arg = tmp + 1;
--		tmp = strrchr(arg, ')');
--		if (tmp) {
--			struct deref_fetch_param *dprm;
--			const struct fetch_type *t2 = find_fetch_type(NULL);
--			*tmp = '\0';
--			dprm = kzalloc(sizeof(struct deref_fetch_param),
--				       GFP_KERNEL);
--			if (!dprm)
--				return -ENOMEM;
--			dprm->offset = offset;
--			ret = __parse_probe_arg(arg, t2, &dprm->orig,
--						is_return);
--			if (ret)
--				kfree(dprm);
--			else {
--				f->fn = t->fetch[FETCH_MTD_deref];
--				f->data = (void *)dprm;
--			}
--		}
--		break;
--	}
--	if (!ret && !f->fn) {	/* Parsed, but do not find fetch method */
--		pr_info("%s type has no corresponding fetch method.\n",
--			t->name);
--		ret = -EINVAL;
--	}
--	return ret;
--}
--
--#define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
--
--/* Bitfield type needs to be parsed into a fetch function */
--static int __parse_bitfield_probe_arg(const char *bf,
--				      const struct fetch_type *t,
--				      struct fetch_param *f)
--{
--	struct bitfield_fetch_param *bprm;
--	unsigned long bw, bo;
--	char *tail;
--
--	if (*bf != 'b')
--		return 0;
--
--	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
--	if (!bprm)
--		return -ENOMEM;
--	bprm->orig = *f;
--	f->fn = t->fetch[FETCH_MTD_bitfield];
--	f->data = (void *)bprm;
--
--	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
--	if (bw == 0 || *tail != '@')
--		return -EINVAL;
--
--	bf = tail + 1;
--	bo = simple_strtoul(bf, &tail, 0);
--	if (tail == bf || *tail != '/')
--		return -EINVAL;
--
--	bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo);
--	bprm->low_shift = bprm->hi_shift + bo;
--	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
--}
--
--/* String length checking wrapper */
--static int parse_probe_arg(char *arg, struct trace_probe *tp,
--			   struct probe_arg *parg, bool is_return)
--{
--	const char *t;
--	int ret;
--
--	if (strlen(arg) > MAX_ARGSTR_LEN) {
--		pr_info("Argument is too long.: %s\n",  arg);
--		return -ENOSPC;
--	}
--	parg->comm = kstrdup(arg, GFP_KERNEL);
--	if (!parg->comm) {
--		pr_info("Failed to allocate memory for command '%s'.\n", arg);
--		return -ENOMEM;
--	}
--	t = strchr(parg->comm, ':');
--	if (t) {
--		arg[t - parg->comm] = '\0';
--		t++;
--	}
--	parg->type = find_fetch_type(t);
--	if (!parg->type) {
--		pr_info("Unsupported type: %s\n", t);
--		return -EINVAL;
--	}
--	parg->offset = tp->size;
--	tp->size += parg->type->size;
--	ret = __parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
--	if (ret >= 0 && t != NULL)
--		ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
--	if (ret >= 0) {
--		parg->fetch_size.fn = get_fetch_size_function(parg->type,
--							      parg->fetch.fn);
--		parg->fetch_size.data = parg->fetch.data;
--	}
--	return ret;
--}
--
--/* Return 1 if name is reserved or already used by another argument */
--static int conflict_field_name(const char *name,
--			       struct probe_arg *args, int narg)
--{
--	int i;
--	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
--		if (strcmp(reserved_field_names[i], name) == 0)
--			return 1;
--	for (i = 0; i < narg; i++)
--		if (strcmp(args[i].name, name) == 0)
--			return 1;
--	return 0;
--}
--
- static int create_trace_probe(int argc, char **argv)
- {
- 	/*
-@@ -1240,7 +453,7 @@ static int create_trace_probe(int argc, char **argv)
- 		/* a symbol specified */
- 		symbol = argv[1];
- 		/* TODO: support .init module functions */
--		ret = split_symbol_offset(symbol, &offset);
-+		ret = traceprobe_split_symbol_offset(symbol, &offset);
- 		if (ret) {
- 			pr_info("Failed to parse symbol.\n");
- 			return ret;
-@@ -1302,7 +515,8 @@ static int create_trace_probe(int argc, char **argv)
- 			goto error;
- 		}
- 
--		if (conflict_field_name(tp->args[i].name, tp->args, i)) {
-+		if (traceprobe_conflict_field_name(tp->args[i].name,
-+							tp->args, i)) {
- 			pr_info("Argument[%d] name '%s' conflicts with "
- 				"another field.\n", i, argv[i]);
- 			ret = -EINVAL;
-@@ -1310,7 +524,8 @@ static int create_trace_probe(int argc, char **argv)
- 		}
- 
- 		/* Parse fetch argument */
--		ret = parse_probe_arg(arg, tp, &tp->args[i], is_return);
-+		ret = traceprobe_parse_probe_arg(arg, &tp->size, &tp->args[i],
-+								is_return);
- 		if (ret) {
- 			pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
- 			goto error;
-@@ -1412,70 +627,11 @@ static int probes_open(struct inode *inode, struct file *file)
- 	return seq_open(file, &probes_seq_op);
- }
- 
--static int command_trace_probe(const char *buf)
--{
--	char **argv;
--	int argc = 0, ret = 0;
--
--	argv = argv_split(GFP_KERNEL, buf, &argc);
--	if (!argv)
--		return -ENOMEM;
--
--	if (argc)
--		ret = create_trace_probe(argc, argv);
--
--	argv_free(argv);
--	return ret;
--}
--
--#define WRITE_BUFSIZE 4096
--
- static ssize_t probes_write(struct file *file, const char __user *buffer,
- 			    size_t count, loff_t *ppos)
- {
--	char *kbuf, *tmp;
--	int ret;
--	size_t done;
--	size_t size;
--
--	kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL);
--	if (!kbuf)
--		return -ENOMEM;
--
--	ret = done = 0;
--	while (done < count) {
--		size = count - done;
--		if (size >= WRITE_BUFSIZE)
--			size = WRITE_BUFSIZE - 1;
--		if (copy_from_user(kbuf, buffer + done, size)) {
--			ret = -EFAULT;
--			goto out;
--		}
--		kbuf[size] = '\0';
--		tmp = strchr(kbuf, '\n');
--		if (tmp) {
--			*tmp = '\0';
--			size = tmp - kbuf + 1;
--		} else if (done + size < count) {
--			pr_warning("Line length is too long: "
--				   "Should be less than %d.", WRITE_BUFSIZE);
--			ret = -EINVAL;
--			goto out;
--		}
--		done += size;
--		/* Remove comments */
--		tmp = strchr(kbuf, '#');
--		if (tmp)
--			*tmp = '\0';
--
--		ret = command_trace_probe(kbuf);
--		if (ret)
--			goto out;
--	}
--	ret = done;
--out:
--	kfree(kbuf);
--	return ret;
-+	return traceprobe_probes_write(file, buffer, count, ppos,
-+			create_trace_probe);
- }
- 
- static const struct file_operations kprobe_events_ops = {
-@@ -1711,16 +867,6 @@ partial:
- 	return TRACE_TYPE_PARTIAL_LINE;
- }
- 
--#undef DEFINE_FIELD
--#define DEFINE_FIELD(type, item, name, is_signed)			\
--	do {								\
--		ret = trace_define_field(event_call, #type, name,	\
--					 offsetof(typeof(field), item),	\
--					 sizeof(field.item), is_signed, \
--					 FILTER_OTHER);			\
--		if (ret)						\
--			return ret;					\
--	} while (0)
- 
- static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
- {
-@@ -2051,8 +1197,9 @@ static __init int kprobe_trace_self_tests_init(void)
- 
- 	pr_info("Testing kprobe tracing: ");
- 
--	ret = command_trace_probe("p:testprobe kprobe_trace_selftest_target "
--				  "$stack $stack0 +0($stack)");
-+	ret = traceprobe_command("p:testprobe kprobe_trace_selftest_target "
-+				  "$stack $stack0 +0($stack)",
-+				  create_trace_probe);
- 	if (WARN_ON_ONCE(ret)) {
- 		pr_warning("error on probing function entry.\n");
- 		warn++;
-@@ -2066,8 +1213,8 @@ static __init int kprobe_trace_self_tests_init(void)
- 			enable_trace_probe(tp, TP_FLAG_TRACE);
- 	}
- 
--	ret = command_trace_probe("r:testprobe2 kprobe_trace_selftest_target "
--				  "$retval");
-+	ret = traceprobe_command("r:testprobe2 kprobe_trace_selftest_target "
-+				  "$retval", create_trace_probe);
- 	if (WARN_ON_ONCE(ret)) {
- 		pr_warning("error on probing function return.\n");
- 		warn++;
-@@ -2101,13 +1248,13 @@ static __init int kprobe_trace_self_tests_init(void)
- 	} else
- 		disable_trace_probe(tp, TP_FLAG_TRACE);
- 
--	ret = command_trace_probe("-:testprobe");
-+	ret = traceprobe_command("-:testprobe", create_trace_probe);
- 	if (WARN_ON_ONCE(ret)) {
- 		pr_warning("error on deleting a probe.\n");
- 		warn++;
- 	}
- 
--	ret = command_trace_probe("-:testprobe2");
-+	ret = traceprobe_command("-:testprobe2", create_trace_probe);
- 	if (WARN_ON_ONCE(ret)) {
- 		pr_warning("error on deleting a probe.\n");
- 		warn++;
-diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
-new file mode 100644
-index 0000000..8e526b9
---- /dev/null
-+++ b/kernel/trace/trace_probe.c
-@@ -0,0 +1,833 @@
-+/*
-+ * Common code for probe-based Dynamic events.
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * This code was copied from kernel/trace/trace_kprobe.c written by
-+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-+ *
-+ * Updates to make this generic:
-+ * Copyright (C) IBM Corporation, 2010-2011
-+ * Author:     Srikar Dronamraju
-+ */
-+
-+#include "trace_probe.h"
-+
-+const char *reserved_field_names[] = {
-+	"common_type",
-+	"common_flags",
-+	"common_preempt_count",
-+	"common_pid",
-+	"common_tgid",
-+	FIELD_STRING_IP,
-+	FIELD_STRING_RETIP,
-+	FIELD_STRING_FUNC,
-+};
-+
-+/* Printing function type */
-+#define PRINT_TYPE_FUNC_NAME(type)	print_type_##type
-+#define PRINT_TYPE_FMT_NAME(type)	print_type_format_##type
-+
-+/* Printing  in basic type function template */
-+#define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast)			\
-+static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s,	\
-+						const char *name,	\
-+						void *data, void *ent)\
-+{									\
-+	return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\
-+}									\
-+static const char PRINT_TYPE_FMT_NAME(type)[] = fmt;
-+
-+DEFINE_BASIC_PRINT_TYPE_FUNC(u8, "%x", unsigned int)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "%x", unsigned int)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(u32, "%lx", unsigned long)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(u64, "%llx", unsigned long long)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(s8, "%d", int)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long)
-+DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long)
-+
-+static inline void *get_rloc_data(u32 *dl)
-+{
-+	return (u8 *)dl + get_rloc_offs(*dl);
-+}
-+
-+/* For data_loc conversion */
-+static inline void *get_loc_data(u32 *dl, void *ent)
-+{
-+	return (u8 *)ent + get_rloc_offs(*dl);
-+}
-+
-+/* For defining macros, define string/string_size types */
-+typedef u32 string;
-+typedef u32 string_size;
-+
-+/* Print type function for string type */
-+static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s,
-+						  const char *name,
-+						  void *data, void *ent)
-+{
-+	int len = *(u32 *)data >> 16;
-+
-+	if (!len)
-+		return trace_seq_printf(s, " %s=(fault)", name);
-+	else
-+		return trace_seq_printf(s, " %s=\"%s\"", name,
-+					(const char *)get_loc_data(data, ent));
-+}
-+
-+static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
-+
-+#define FETCH_FUNC_NAME(method, type)	fetch_##method##_##type
-+/*
-+ * Define macro for basic types - we don't need to define s* types, because
-+ * we have to care only about bitwidth at recording time.
-+ */
-+#define DEFINE_BASIC_FETCH_FUNCS(method) \
-+DEFINE_FETCH_##method(u8)		\
-+DEFINE_FETCH_##method(u16)		\
-+DEFINE_FETCH_##method(u32)		\
-+DEFINE_FETCH_##method(u64)
-+
-+#define CHECK_FETCH_FUNCS(method, fn)			\
-+	(((FETCH_FUNC_NAME(method, u8) == fn) ||	\
-+	  (FETCH_FUNC_NAME(method, u16) == fn) ||	\
-+	  (FETCH_FUNC_NAME(method, u32) == fn) ||	\
-+	  (FETCH_FUNC_NAME(method, u64) == fn) ||	\
-+	  (FETCH_FUNC_NAME(method, string) == fn) ||	\
-+	  (FETCH_FUNC_NAME(method, string_size) == fn)) \
-+	 && (fn != NULL))
-+
-+/* Data fetch function templates */
-+#define DEFINE_FETCH_reg(type)						\
-+static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs,	\
-+					void *offset, void *dest)	\
-+{									\
-+	*(type *)dest = (type)regs_get_register(regs,			\
-+				(unsigned int)((unsigned long)offset));	\
-+}
-+DEFINE_BASIC_FETCH_FUNCS(reg)
-+/* No string on the register */
-+#define fetch_reg_string	NULL
-+#define fetch_reg_string_size	NULL
-+
-+#define DEFINE_FETCH_stack(type)					\
-+static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\
-+					  void *offset, void *dest)	\
-+{									\
-+	*(type *)dest = (type)regs_get_kernel_stack_nth(regs,		\
-+				(unsigned int)((unsigned long)offset));	\
-+}
-+DEFINE_BASIC_FETCH_FUNCS(stack)
-+/* No string on the stack entry */
-+#define fetch_stack_string	NULL
-+#define fetch_stack_string_size	NULL
-+
-+#define DEFINE_FETCH_retval(type)					\
-+static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\
-+					  void *dummy, void *dest)	\
-+{									\
-+	*(type *)dest = (type)regs_return_value(regs);			\
-+}
-+DEFINE_BASIC_FETCH_FUNCS(retval)
-+/* No string on the retval */
-+#define fetch_retval_string		NULL
-+#define fetch_retval_string_size	NULL
-+
-+#define DEFINE_FETCH_memory(type)					\
-+static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\
-+					  void *addr, void *dest)	\
-+{									\
-+	type retval;							\
-+	if (probe_kernel_address(addr, retval))				\
-+		*(type *)dest = 0;					\
-+	else								\
-+		*(type *)dest = retval;					\
-+}
-+DEFINE_BASIC_FETCH_FUNCS(memory)
-+/*
-+ * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
-+ * length and relative data location.
-+ */
-+static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
-+						      void *addr, void *dest)
-+{
-+	long ret;
-+	int maxlen = get_rloc_len(*(u32 *)dest);
-+	u8 *dst = get_rloc_data(dest);
-+	u8 *src = addr;
-+	mm_segment_t old_fs = get_fs();
-+
-+	if (!maxlen)
-+		return;
-+
-+	/*
-+	 * Try to get string again, since the string can be changed while
-+	 * probing.
-+	 */
-+	set_fs(KERNEL_DS);
-+	pagefault_disable();
-+
-+	do
-+		ret = __copy_from_user_inatomic(dst++, src++, 1);
-+	while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen);
-+
-+	dst[-1] = '\0';
-+	pagefault_enable();
-+	set_fs(old_fs);
-+
-+	if (ret < 0) {	/* Failed to fetch string */
-+		((u8 *)get_rloc_data(dest))[0] = '\0';
-+		*(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
-+	} else {
-+		*(u32 *)dest = make_data_rloc(src - (u8 *)addr,
-+					      get_rloc_offs(*(u32 *)dest));
-+	}
-+}
-+
-+/* Return the length of string -- including null terminal byte */
-+static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
-+							void *addr, void *dest)
-+{
-+	mm_segment_t old_fs;
-+	int ret, len = 0;
-+	u8 c;
-+
-+	old_fs = get_fs();
-+	set_fs(KERNEL_DS);
-+	pagefault_disable();
-+
-+	do {
-+		ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
-+		len++;
-+	} while (c && ret == 0 && len < MAX_STRING_SIZE);
-+
-+	pagefault_enable();
-+	set_fs(old_fs);
-+
-+	if (ret < 0)	/* Failed to check the length */
-+		*(u32 *)dest = 0;
-+	else
-+		*(u32 *)dest = len;
-+}
-+
-+/* Memory fetching by symbol */
-+struct symbol_cache {
-+	char		*symbol;
-+	long		offset;
-+	unsigned long	addr;
-+};
-+
-+static unsigned long update_symbol_cache(struct symbol_cache *sc)
-+{
-+	sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
-+
-+	if (sc->addr)
-+		sc->addr += sc->offset;
-+
-+	return sc->addr;
-+}
-+
-+static void free_symbol_cache(struct symbol_cache *sc)
-+{
-+	kfree(sc->symbol);
-+	kfree(sc);
-+}
-+
-+static struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
-+{
-+	struct symbol_cache *sc;
-+
-+	if (!sym || strlen(sym) == 0)
-+		return NULL;
-+
-+	sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
-+	if (!sc)
-+		return NULL;
-+
-+	sc->symbol = kstrdup(sym, GFP_KERNEL);
-+	if (!sc->symbol) {
-+		kfree(sc);
-+		return NULL;
-+	}
-+	sc->offset = offset;
-+	update_symbol_cache(sc);
-+
-+	return sc;
-+}
-+
-+#define DEFINE_FETCH_symbol(type)					\
-+static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\
-+					  void *data, void *dest)	\
-+{									\
-+	struct symbol_cache *sc = data;					\
-+	if (sc->addr)							\
-+		fetch_memory_##type(regs, (void *)sc->addr, dest);	\
-+	else								\
-+		*(type *)dest = 0;					\
-+}
-+DEFINE_BASIC_FETCH_FUNCS(symbol)
-+DEFINE_FETCH_symbol(string)
-+DEFINE_FETCH_symbol(string_size)
-+
-+/* Dereference memory access function */
-+struct deref_fetch_param {
-+	struct fetch_param	orig;
-+	long			offset;
-+};
-+
-+#define DEFINE_FETCH_deref(type)					\
-+static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\
-+					    void *data, void *dest)	\
-+{									\
-+	struct deref_fetch_param *dprm = data;				\
-+	unsigned long addr;						\
-+	call_fetch(&dprm->orig, regs, &addr);				\
-+	if (addr) {							\
-+		addr += dprm->offset;					\
-+		fetch_memory_##type(regs, (void *)addr, dest);		\
-+	} else								\
-+		*(type *)dest = 0;					\
-+}
-+DEFINE_BASIC_FETCH_FUNCS(deref)
-+DEFINE_FETCH_deref(string)
-+DEFINE_FETCH_deref(string_size)
-+
-+static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data)
-+{
-+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-+		update_deref_fetch_param(data->orig.data);
-+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-+		update_symbol_cache(data->orig.data);
-+}
-+
-+static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data)
-+{
-+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-+		free_deref_fetch_param(data->orig.data);
-+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-+		free_symbol_cache(data->orig.data);
-+	kfree(data);
-+}
-+
-+/* Bitfield fetch function */
-+struct bitfield_fetch_param {
-+	struct fetch_param	orig;
-+	unsigned char		hi_shift;
-+	unsigned char		low_shift;
-+};
-+
-+#define DEFINE_FETCH_bitfield(type)					\
-+static __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs,\
-+					    void *data, void *dest)	\
-+{									\
-+	struct bitfield_fetch_param *bprm = data;			\
-+	type buf = 0;							\
-+	call_fetch(&bprm->orig, regs, &buf);				\
-+	if (buf) {							\
-+		buf <<= bprm->hi_shift;					\
-+		buf >>= bprm->low_shift;				\
-+	}								\
-+	*(type *)dest = buf;						\
-+}
-+
-+DEFINE_BASIC_FETCH_FUNCS(bitfield)
-+#define fetch_bitfield_string		NULL
-+#define fetch_bitfield_string_size	NULL
-+
-+static __kprobes void
-+update_bitfield_fetch_param(struct bitfield_fetch_param *data)
-+{
-+	/*
-+	 * Don't check the bitfield itself, because this must be the
-+	 * last fetch function.
-+	 */
-+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-+		update_deref_fetch_param(data->orig.data);
-+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-+		update_symbol_cache(data->orig.data);
-+}
-+
-+static __kprobes void
-+free_bitfield_fetch_param(struct bitfield_fetch_param *data)
-+{
-+	/*
-+	 * Don't check the bitfield itself, because this must be the
-+	 * last fetch function.
-+	 */
-+	if (CHECK_FETCH_FUNCS(deref, data->orig.fn))
-+		free_deref_fetch_param(data->orig.data);
-+	else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn))
-+		free_symbol_cache(data->orig.data);
-+
-+	kfree(data);
-+}
-+
-+/* Default (unsigned long) fetch type */
-+#define __DEFAULT_FETCH_TYPE(t) u##t
-+#define _DEFAULT_FETCH_TYPE(t) __DEFAULT_FETCH_TYPE(t)
-+#define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG)
-+#define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE)
-+
-+#define ASSIGN_FETCH_FUNC(method, type)	\
-+	[FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type)
-+
-+#define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype)	\
-+	{.name = _name,				\
-+	 .size = _size,					\
-+	 .is_signed = sign,				\
-+	 .print = PRINT_TYPE_FUNC_NAME(ptype),		\
-+	 .fmt = PRINT_TYPE_FMT_NAME(ptype),		\
-+	 .fmttype = _fmttype,				\
-+	 .fetch = {					\
-+ASSIGN_FETCH_FUNC(reg, ftype),				\
-+ASSIGN_FETCH_FUNC(stack, ftype),			\
-+ASSIGN_FETCH_FUNC(retval, ftype),			\
-+ASSIGN_FETCH_FUNC(memory, ftype),			\
-+ASSIGN_FETCH_FUNC(symbol, ftype),			\
-+ASSIGN_FETCH_FUNC(deref, ftype),			\
-+ASSIGN_FETCH_FUNC(bitfield, ftype),			\
-+	  }						\
-+	}
-+
-+#define ASSIGN_FETCH_TYPE(ptype, ftype, sign)			\
-+	__ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype)
-+
-+#define FETCH_TYPE_STRING	0
-+#define FETCH_TYPE_STRSIZE	1
-+
-+/* Fetch type information table */
-+static const struct fetch_type fetch_type_table[] = {
-+	/* Special types */
-+	[FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
-+					sizeof(u32), 1, "__data_loc char[]"),
-+	[FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
-+					string_size, sizeof(u32), 0, "u32"),
-+	/* Basic types */
-+	ASSIGN_FETCH_TYPE(u8,  u8,  0),
-+	ASSIGN_FETCH_TYPE(u16, u16, 0),
-+	ASSIGN_FETCH_TYPE(u32, u32, 0),
-+	ASSIGN_FETCH_TYPE(u64, u64, 0),
-+	ASSIGN_FETCH_TYPE(s8,  u8,  1),
-+	ASSIGN_FETCH_TYPE(s16, u16, 1),
-+	ASSIGN_FETCH_TYPE(s32, u32, 1),
-+	ASSIGN_FETCH_TYPE(s64, u64, 1),
-+};
-+
-+static const struct fetch_type *find_fetch_type(const char *type)
-+{
-+	int i;
-+
-+	if (!type)
-+		type = DEFAULT_FETCH_TYPE_STR;
-+
-+	/* Special case: bitfield */
-+	if (*type == 'b') {
-+		unsigned long bs;
-+
-+		type = strchr(type, '/');
-+		if (!type)
-+			goto fail;
-+
-+		type++;
-+		if (strict_strtoul(type, 0, &bs))
-+			goto fail;
-+
-+		switch (bs) {
-+		case 8:
-+			return find_fetch_type("u8");
-+		case 16:
-+			return find_fetch_type("u16");
-+		case 32:
-+			return find_fetch_type("u32");
-+		case 64:
-+			return find_fetch_type("u64");
-+		default:
-+			goto fail;
-+		}
-+	}
-+
-+	for (i = 0; i < ARRAY_SIZE(fetch_type_table); i++)
-+		if (strcmp(type, fetch_type_table[i].name) == 0)
-+			return &fetch_type_table[i];
-+
-+fail:
-+	return NULL;
-+}
-+
-+/* Special function : only accept unsigned long */
-+static __kprobes void fetch_stack_address(struct pt_regs *regs,
-+					void *dummy, void *dest)
-+{
-+	*(unsigned long *)dest = kernel_stack_pointer(regs);
-+}
-+
-+static fetch_func_t get_fetch_size_function(const struct fetch_type *type,
-+					fetch_func_t orig_fn)
-+{
-+	int i;
-+
-+	if (type != &fetch_type_table[FETCH_TYPE_STRING])
-+		return NULL;	/* Only string type needs size function */
-+
-+	for (i = 0; i < FETCH_MTD_END; i++)
-+		if (type->fetch[i] == orig_fn)
-+			return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i];
-+
-+	WARN_ON(1);	/* This should not happen */
-+
-+	return NULL;
-+}
-+
-+/* Split symbol and offset. */
-+int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset)
-+{
-+	char *tmp;
-+	int ret;
-+
-+	if (!offset)
-+		return -EINVAL;
-+
-+	tmp = strchr(symbol, '+');
-+	if (tmp) {
-+		/* skip sign because strict_strtol doesn't accept '+' */
-+		ret = strict_strtoul(tmp + 1, 0, offset);
-+		if (ret)
-+			return ret;
-+
-+		*tmp = '\0';
-+	} else
-+		*offset = 0;
-+
-+	return 0;
-+}
-+
-+#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
-+
-+static int parse_probe_vars(char *arg, const struct fetch_type *t,
-+			    struct fetch_param *f, bool is_return)
-+{
-+	int ret = 0;
-+	unsigned long param;
-+
-+	if (strcmp(arg, "retval") == 0) {
-+		if (is_return)
-+			f->fn = t->fetch[FETCH_MTD_retval];
-+		else
-+			ret = -EINVAL;
-+	} else if (strncmp(arg, "stack", 5) == 0) {
-+		if (arg[5] == '\0') {
-+			if (strcmp(t->name, DEFAULT_FETCH_TYPE_STR) == 0)
-+				f->fn = fetch_stack_address;
-+			else
-+				ret = -EINVAL;
-+		} else if (isdigit(arg[5])) {
-+			ret = strict_strtoul(arg + 5, 10, &param);
-+			if (ret || param > PARAM_MAX_STACK)
-+				ret = -EINVAL;
-+			else {
-+				f->fn = t->fetch[FETCH_MTD_stack];
-+				f->data = (void *)param;
-+			}
-+		} else
-+			ret = -EINVAL;
-+	} else
-+		ret = -EINVAL;
-+
-+	return ret;
-+}
-+
-+/* Recursive argument parser */
-+static int parse_probe_arg(char *arg, const struct fetch_type *t,
-+		     struct fetch_param *f, bool is_return)
-+{
-+	unsigned long param;
-+	long offset;
-+	char *tmp;
-+	int ret;
-+
-+	ret = 0;
-+	switch (arg[0]) {
-+	case '$':
-+		ret = parse_probe_vars(arg + 1, t, f, is_return);
-+		break;
-+
-+	case '%':	/* named register */
-+		ret = regs_query_register_offset(arg + 1);
-+		if (ret >= 0) {
-+			f->fn = t->fetch[FETCH_MTD_reg];
-+			f->data = (void *)(unsigned long)ret;
-+			ret = 0;
-+		}
-+		break;
-+
-+	case '@':	/* memory or symbol */
-+		if (isdigit(arg[1])) {
-+			ret = strict_strtoul(arg + 1, 0, &param);
-+			if (ret)
-+				break;
-+
-+			f->fn = t->fetch[FETCH_MTD_memory];
-+			f->data = (void *)param;
-+		} else {
-+			ret = traceprobe_split_symbol_offset(arg + 1, &offset);
-+			if (ret)
-+				break;
-+
-+			f->data = alloc_symbol_cache(arg + 1, offset);
-+			if (f->data)
-+				f->fn = t->fetch[FETCH_MTD_symbol];
-+		}
-+		break;
-+
-+	case '+':	/* deref memory */
-+		arg++;	/* Skip '+', because strict_strtol() rejects it. */
-+	case '-':
-+		tmp = strchr(arg, '(');
-+		if (!tmp)
-+			break;
-+
-+		*tmp = '\0';
-+		ret = strict_strtol(arg, 0, &offset);
-+
-+		if (ret)
-+			break;
-+
-+		arg = tmp + 1;
-+		tmp = strrchr(arg, ')');
-+
-+		if (tmp) {
-+			struct deref_fetch_param	*dprm;
-+			const struct fetch_type		*t2;
-+
-+			t2 = find_fetch_type(NULL);
-+			*tmp = '\0';
-+			dprm = kzalloc(sizeof(struct deref_fetch_param), GFP_KERNEL);
-+
-+			if (!dprm)
-+				return -ENOMEM;
-+
-+			dprm->offset = offset;
-+			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return);
-+			if (ret)
-+				kfree(dprm);
-+			else {
-+				f->fn = t->fetch[FETCH_MTD_deref];
-+				f->data = (void *)dprm;
-+			}
-+		}
-+		break;
-+	}
-+	if (!ret && !f->fn) {	/* Parsed, but do not find fetch method */
-+		pr_info("%s type has no corresponding fetch method.\n", t->name);
-+		ret = -EINVAL;
-+	}
-+
-+	return ret;
-+}
-+
-+#define BYTES_TO_BITS(nb)	((BITS_PER_LONG * (nb)) / sizeof(long))
-+
-+/* Bitfield type needs to be parsed into a fetch function */
-+static int __parse_bitfield_probe_arg(const char *bf,
-+				      const struct fetch_type *t,
-+				      struct fetch_param *f)
-+{
-+	struct bitfield_fetch_param *bprm;
-+	unsigned long bw, bo;
-+	char *tail;
-+
-+	if (*bf != 'b')
-+		return 0;
-+
-+	bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
-+	if (!bprm)
-+		return -ENOMEM;
-+
-+	bprm->orig = *f;
-+	f->fn = t->fetch[FETCH_MTD_bitfield];
-+	f->data = (void *)bprm;
-+	bw = simple_strtoul(bf + 1, &tail, 0);	/* Use simple one */
-+
-+	if (bw == 0 || *tail != '@')
-+		return -EINVAL;
-+
-+	bf = tail + 1;
-+	bo = simple_strtoul(bf, &tail, 0);
-+
-+	if (tail == bf || *tail != '/')
-+		return -EINVAL;
-+
-+	bprm->hi_shift = BYTES_TO_BITS(t->size) - (bw + bo);
-+	bprm->low_shift = bprm->hi_shift + bo;
-+
-+	return (BYTES_TO_BITS(t->size) < (bw + bo)) ? -EINVAL : 0;
-+}
-+
-+/* String length checking wrapper */
-+int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
-+		struct probe_arg *parg, bool is_return)
-+{
-+	const char *t;
-+	int ret;
-+
-+	if (strlen(arg) > MAX_ARGSTR_LEN) {
-+		pr_info("Argument is too long.: %s\n",  arg);
-+		return -ENOSPC;
-+	}
-+	parg->comm = kstrdup(arg, GFP_KERNEL);
-+	if (!parg->comm) {
-+		pr_info("Failed to allocate memory for command '%s'.\n", arg);
-+		return -ENOMEM;
-+	}
-+	t = strchr(parg->comm, ':');
-+	if (t) {
-+		arg[t - parg->comm] = '\0';
-+		t++;
-+	}
-+	parg->type = find_fetch_type(t);
-+	if (!parg->type) {
-+		pr_info("Unsupported type: %s\n", t);
-+		return -EINVAL;
-+	}
-+	parg->offset = *size;
-+	*size += parg->type->size;
-+	ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
-+
-+	if (ret >= 0 && t != NULL)
-+		ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
-+
-+	if (ret >= 0) {
-+		parg->fetch_size.fn = get_fetch_size_function(parg->type,
-+							      parg->fetch.fn);
-+		parg->fetch_size.data = parg->fetch.data;
-+	}
-+
-+	return ret;
-+}
-+
-+/* Return 1 if name is reserved or already used by another argument */
-+int traceprobe_conflict_field_name(const char *name,
-+			       struct probe_arg *args, int narg)
-+{
-+	int i;
-+
-+	for (i = 0; i < ARRAY_SIZE(reserved_field_names); i++)
-+		if (strcmp(reserved_field_names[i], name) == 0)
-+			return 1;
-+
-+	for (i = 0; i < narg; i++)
-+		if (strcmp(args[i].name, name) == 0)
-+			return 1;
-+
-+	return 0;
-+}
-+
-+void traceprobe_update_arg(struct probe_arg *arg)
-+{
-+	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
-+		update_bitfield_fetch_param(arg->fetch.data);
-+	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
-+		update_deref_fetch_param(arg->fetch.data);
-+	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
-+		update_symbol_cache(arg->fetch.data);
-+}
-+
-+void traceprobe_free_probe_arg(struct probe_arg *arg)
-+{
-+	if (CHECK_FETCH_FUNCS(bitfield, arg->fetch.fn))
-+		free_bitfield_fetch_param(arg->fetch.data);
-+	else if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn))
-+		free_deref_fetch_param(arg->fetch.data);
-+	else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn))
-+		free_symbol_cache(arg->fetch.data);
-+
-+	kfree(arg->name);
-+	kfree(arg->comm);
-+}
-+
-+int traceprobe_command(const char *buf, int (*createfn)(int, char **))
-+{
-+	char **argv;
-+	int argc, ret;
-+
-+	argc = 0;
-+	ret = 0;
-+	argv = argv_split(GFP_KERNEL, buf, &argc);
-+	if (!argv)
-+		return -ENOMEM;
-+
-+	if (argc)
-+		ret = createfn(argc, argv);
-+
-+	argv_free(argv);
-+
-+	return ret;
-+}
-+
-+#define WRITE_BUFSIZE  4096
-+
-+ssize_t traceprobe_probes_write(struct file *file, const char __user *buffer,
-+				size_t count, loff_t *ppos,
-+				int (*createfn)(int, char **))
-+{
-+	char *kbuf, *tmp;
-+	int ret = 0;
-+	size_t done = 0;
-+	size_t size;
-+
-+	kbuf = kmalloc(WRITE_BUFSIZE, GFP_KERNEL);
-+	if (!kbuf)
-+		return -ENOMEM;
-+
-+	while (done < count) {
-+		size = count - done;
-+
-+		if (size >= WRITE_BUFSIZE)
-+			size = WRITE_BUFSIZE - 1;
-+
-+		if (copy_from_user(kbuf, buffer + done, size)) {
-+			ret = -EFAULT;
-+			goto out;
-+		}
-+		kbuf[size] = '\0';
-+		tmp = strchr(kbuf, '\n');
-+
-+		if (tmp) {
-+			*tmp = '\0';
-+			size = tmp - kbuf + 1;
-+		} else if (done + size < count) {
-+			pr_warning("Line length is too long: "
-+				   "Should be less than %d.", WRITE_BUFSIZE);
-+			ret = -EINVAL;
-+			goto out;
-+		}
-+		done += size;
-+		/* Remove comments */
-+		tmp = strchr(kbuf, '#');
-+
-+		if (tmp)
-+			*tmp = '\0';
-+
-+		ret = traceprobe_command(kbuf, createfn);
-+		if (ret)
-+			goto out;
-+	}
-+	ret = done;
-+
-+out:
-+	kfree(kbuf);
-+
-+	return ret;
-+}
-diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
-new file mode 100644
-index 0000000..2df9a18
---- /dev/null
-+++ b/kernel/trace/trace_probe.h
-@@ -0,0 +1,160 @@
-+/*
-+ * Common header file for probe-based Dynamic events.
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * This code was copied from kernel/trace/trace_kprobe.h written by
-+ * Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-+ *
-+ * Updates to make this generic:
-+ * Copyright (C) IBM Corporation, 2010-2011
-+ * Author:     Srikar Dronamraju
-+ */
-+
-+#include <linux/seq_file.h>
-+#include <linux/slab.h>
-+#include <linux/smp.h>
-+#include <linux/debugfs.h>
-+#include <linux/types.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/ptrace.h>
-+#include <linux/perf_event.h>
-+#include <linux/kprobes.h>
-+#include <linux/stringify.h>
-+#include <linux/limits.h>
-+#include <linux/uaccess.h>
-+#include <asm/bitsperlong.h>
-+
-+#include "trace.h"
-+#include "trace_output.h"
-+
-+#define MAX_TRACE_ARGS		128
-+#define MAX_ARGSTR_LEN		63
-+#define MAX_EVENT_NAME_LEN	64
-+#define MAX_STRING_SIZE		PATH_MAX
-+
-+/* Reserved field names */
-+#define FIELD_STRING_IP		"__probe_ip"
-+#define FIELD_STRING_RETIP	"__probe_ret_ip"
-+#define FIELD_STRING_FUNC	"__probe_func"
-+
-+#undef DEFINE_FIELD
-+#define DEFINE_FIELD(type, item, name, is_signed)			\
-+	do {								\
-+		ret = trace_define_field(event_call, #type, name,	\
-+					 offsetof(typeof(field), item),	\
-+					 sizeof(field.item), is_signed, \
-+					 FILTER_OTHER);			\
-+		if (ret)						\
-+			return ret;					\
-+	} while (0)
-+
-+
-+/* Flags for trace_probe */
-+#define TP_FLAG_TRACE		1
-+#define TP_FLAG_PROFILE		2
-+#define TP_FLAG_REGISTERED	4
-+
-+
-+/* data_rloc: data relative location, compatible with u32 */
-+#define make_data_rloc(len, roffs)	\
-+	(((u32)(len) << 16) | ((u32)(roffs) & 0xffff))
-+#define get_rloc_len(dl)		((u32)(dl) >> 16)
-+#define get_rloc_offs(dl)		((u32)(dl) & 0xffff)
-+
-+/*
-+ * Convert data_rloc to data_loc:
-+ *  data_rloc stores the offset from data_rloc itself, but data_loc
-+ *  stores the offset from event entry.
-+ */
-+#define convert_rloc_to_loc(dl, offs)	((u32)(dl) + (offs))
-+
-+/* Data fetch function type */
-+typedef	void (*fetch_func_t)(struct pt_regs *, void *, void *);
-+/* Printing function type */
-+typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *, void *);
-+
-+/* Fetch types */
-+enum {
-+	FETCH_MTD_reg = 0,
-+	FETCH_MTD_stack,
-+	FETCH_MTD_retval,
-+	FETCH_MTD_memory,
-+	FETCH_MTD_symbol,
-+	FETCH_MTD_deref,
-+	FETCH_MTD_bitfield,
-+	FETCH_MTD_END,
-+};
-+
-+/* Fetch type information table */
-+struct fetch_type {
-+	const char		*name;		/* Name of type */
-+	size_t			size;		/* Byte size of type */
-+	int			is_signed;	/* Signed flag */
-+	print_type_func_t	print;		/* Print functions */
-+	const char		*fmt;		/* Fromat string */
-+	const char		*fmttype;	/* Name in format file */
-+	/* Fetch functions */
-+	fetch_func_t		fetch[FETCH_MTD_END];
-+};
-+
-+struct fetch_param {
-+	fetch_func_t		fn;
-+	void 			*data;
-+};
-+
-+struct probe_arg {
-+	struct fetch_param	fetch;
-+	struct fetch_param	fetch_size;
-+	unsigned int		offset;	/* Offset from argument entry */
-+	const char		*name;	/* Name of this argument */
-+	const char		*comm;	/* Command of this argument */
-+	const struct fetch_type	*type;	/* Type of this argument */
-+};
-+
-+static inline __kprobes void call_fetch(struct fetch_param *fprm,
-+				 struct pt_regs *regs, void *dest)
-+{
-+	return fprm->fn(regs, fprm->data, dest);
-+}
-+
-+/* Check the name is good for event/group/fields */
-+static inline int is_good_name(const char *name)
-+{
-+	if (!isalpha(*name) && *name != '_')
-+		return 0;
-+	while (*++name != '\0') {
-+		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
-+			return 0;
-+	}
-+	return 1;
-+}
-+
-+extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
-+		   struct probe_arg *parg, bool is_return);
-+
-+extern int traceprobe_conflict_field_name(const char *name,
-+			       struct probe_arg *args, int narg);
-+
-+extern void traceprobe_update_arg(struct probe_arg *arg);
-+extern void traceprobe_free_probe_arg(struct probe_arg *arg);
-+
-+extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset);
-+
-+extern ssize_t traceprobe_probes_write(struct file *file,
-+		const char __user *buffer, size_t count, loff_t *ppos,
-+		int (*createfn)(int, char**));
-+
-+extern int traceprobe_command(const char *buf, int (*createfn)(int, char**));
--- 
-1.7.5.4
-
diff --git a/features/uprobe/tracing-Fix-kconfig-warning-due-to-a-typo.patch b/features/uprobe/tracing-Fix-kconfig-warning-due-to-a-typo.patch
deleted file mode 100644
index e0d0ebf1141fc8aa168632fb68cf0bb813051d61..0000000000000000000000000000000000000000
--- a/features/uprobe/tracing-Fix-kconfig-warning-due-to-a-typo.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-From 103b503daaff2328d12b1ba2bd8d27e95a1474bb Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Tue, 8 May 2012 16:41:26 +0530
-Subject: [PATCH 19/24] tracing: Fix kconfig warning due to a typo
-
-Commit f3f096cfe ("tracing: Provide trace events interface for
-uprobes") throws a warning about unmet dependencies.
-
-The exact warning message is:
-	warning: (UPROBE_EVENT) selects UPROBES which has unmet direct dependencies (UPROBE_EVENTS && PERF_EVENTS)
-
-This is due to a typo in arch/Kconfig file. Fix similar typos in
-the uprobetracer documentation.
-
-Also add sample format of a uprobe event in the uprobetracer
-documentation as suggested by Masami Hiramatsu.
-
-commit ec83db0f78cd44c3b586ec1c3a348d1a8a389797 upstream
-
-Reported-by: Stephen Boyd <sboyd@codeaurora.org>
-Reported-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120508111126.21004.38285.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- Documentation/trace/uprobetracer.txt |   22 ++++++++++++++++++++--
- arch/Kconfig                         |    2 +-
- 2 files changed, 21 insertions(+), 3 deletions(-)
-
-diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt
-index eae40a0..24ce682 100644
---- a/Documentation/trace/uprobetracer.txt
-+++ b/Documentation/trace/uprobetracer.txt
-@@ -5,7 +5,7 @@
- Overview
- --------
- Uprobe based trace events are similar to kprobe based trace events.
--To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.
-+To enable this feature, build your kernel with CONFIG_UPROBE_EVENT=y.
- 
- Similar to the kprobe-event tracer, this doesn't need to be activated via
- current_tracer. Instead of that, add probe points via
-@@ -68,7 +68,25 @@ in the object. We can see the events that are registered by looking at the
- uprobe_events file.
- 
-     # cat uprobe_events
--    p:uprobes/p_zsh_0x46420 /bin/zsh:0x0000000000046420
-+    p:uprobes/p_zsh_0x46420 /bin/zsh:0x00046420 arg1=%ip arg2=%ax
-+
-+The format of events can be seen by viewing the file events/uprobes/p_zsh_0x46420/format
-+
-+    # cat events/uprobes/p_zsh_0x46420/format
-+    name: p_zsh_0x46420
-+    ID: 922
-+    format:
-+	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
-+	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
-+	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
-+	field:int common_pid;	offset:4;	size:4;	signed:1;
-+	field:int common_padding;	offset:8;	size:4;	signed:1;
-+
-+	field:unsigned long __probe_ip;	offset:12;	size:4;	signed:0;
-+	field:u32 arg1;	offset:16;	size:4;	signed:0;
-+	field:u32 arg2;	offset:20;	size:4;	signed:0;
-+
-+    print fmt: "(%lx) arg1=%lx arg2=%lx", REC->__probe_ip, REC->arg1, REC->arg2
- 
- Right after definition, each event is disabled by default. For tracing these
- events, you need to enable it by:
-diff --git a/arch/Kconfig b/arch/Kconfig
-index 5e4ab5c..dd939a9 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -78,7 +78,7 @@ config OPTPROBES
- 
- config UPROBES
- 	bool "Transparent user-space probes (EXPERIMENTAL)"
--	depends on UPROBE_EVENTS && PERF_EVENTS
-+	depends on UPROBE_EVENT && PERF_EVENTS
- 	default n
- 	help
- 	  Uprobes is the user-space counterpart to kprobes: they
--- 
-1.7.5.4
-
diff --git a/features/uprobe/tracing-Modify-is_delete-is_return-from-int-to-bool.patch b/features/uprobe/tracing-Modify-is_delete-is_return-from-int-to-bool.patch
deleted file mode 100644
index 36d06e2d3047b3836cca73a8684399c5ab71d793..0000000000000000000000000000000000000000
--- a/features/uprobe/tracing-Modify-is_delete-is_return-from-int-to-bool.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-From 91f0360db35261ddffbc89ee68e9d7b2dddb0cf6 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 9 Apr 2012 14:41:33 +0530
-Subject: [PATCH 16/24] tracing: Modify is_delete, is_return from int to bool
-
-is_delete and is_return can take utmost 2 values and are better
-of being a boolean than a int. There are no functional changes.
-
-commit 3a6b76661da8e92124a813b43607f5bec1a618de upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Acked-by: Steven Rostedt <rostedt@goodmis.org>
-Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120409091133.8343.65289.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- kernel/trace/trace_kprobe.c |   16 ++++++++--------
- 1 files changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
-index 580a05e..4f935f8 100644
---- a/kernel/trace/trace_kprobe.c
-+++ b/kernel/trace/trace_kprobe.c
-@@ -651,7 +651,7 @@ static struct trace_probe *alloc_trace_probe(const char *group,
- 					     void *addr,
- 					     const char *symbol,
- 					     unsigned long offs,
--					     int nargs, int is_return)
-+					     int nargs, bool is_return)
- {
- 	struct trace_probe *tp;
- 	int ret = -ENOMEM;
-@@ -944,7 +944,7 @@ static int split_symbol_offset(char *symbol, unsigned long *offset)
- #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
- 
- static int parse_probe_vars(char *arg, const struct fetch_type *t,
--			    struct fetch_param *f, int is_return)
-+			    struct fetch_param *f, bool is_return)
- {
- 	int ret = 0;
- 	unsigned long param;
-@@ -977,7 +977,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
- 
- /* Recursive argument parser */
- static int __parse_probe_arg(char *arg, const struct fetch_type *t,
--			     struct fetch_param *f, int is_return)
-+			     struct fetch_param *f, bool is_return)
- {
- 	int ret = 0;
- 	unsigned long param;
-@@ -1089,7 +1089,7 @@ static int __parse_bitfield_probe_arg(const char *bf,
- 
- /* String length checking wrapper */
- static int parse_probe_arg(char *arg, struct trace_probe *tp,
--			   struct probe_arg *parg, int is_return)
-+			   struct probe_arg *parg, bool is_return)
- {
- 	const char *t;
- 	int ret;
-@@ -1162,7 +1162,7 @@ static int create_trace_probe(int argc, char **argv)
- 	 */
- 	struct trace_probe *tp;
- 	int i, ret = 0;
--	int is_return = 0, is_delete = 0;
-+	bool is_return = false, is_delete = false;
- 	char *symbol = NULL, *event = NULL, *group = NULL;
- 	char *arg;
- 	unsigned long offset = 0;
-@@ -1171,11 +1171,11 @@ static int create_trace_probe(int argc, char **argv)
- 
- 	/* argc must be >= 1 */
- 	if (argv[0][0] == 'p')
--		is_return = 0;
-+		is_return = false;
- 	else if (argv[0][0] == 'r')
--		is_return = 1;
-+		is_return = true;
- 	else if (argv[0][0] == '-')
--		is_delete = 1;
-+		is_delete = true;
- 	else {
- 		pr_info("Probe definition must be started with 'p', 'r' or"
- 			" '-'.\n");
--- 
-1.7.5.4
-
diff --git a/features/uprobe/tracing-Provide-trace-events-interface-for-uprobes.patch b/features/uprobe/tracing-Provide-trace-events-interface-for-uprobes.patch
deleted file mode 100644
index 747797458b60c2eb0ec97dfdc4f5c7e56e7fffe6..0000000000000000000000000000000000000000
--- a/features/uprobe/tracing-Provide-trace-events-interface-for-uprobes.patch
+++ /dev/null
@@ -1,1119 +0,0 @@
-From 9bb012e0faf6b1ea887a4c42cbfdf468285ce93a Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Wed, 11 Apr 2012 16:00:43 +0530
-Subject: [PATCH 18/24] tracing: Provide trace events interface for uprobes
-
-Implements trace_event support for uprobes. In its current form
-it can be used to put probes at a specified offset in a file and
-dump the required registers when the code flow reaches the
-probed address.
-
-The following example shows how to dump the instruction pointer
-and %ax a register at the probed text address.  Here we are
-trying to probe zfree in /bin/zsh:
-
- # cd /sys/kernel/debug/tracing/
- # cat /proc/`pgrep  zsh`/maps | grep /bin/zsh | grep r-xp
- 00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
- # objdump -T /bin/zsh | grep -w zfree
- 0000000000446420 g    DF .text  0000000000000012  Base
- zfree # echo 'p /bin/zsh:0x46420 %ip %ax' > uprobe_events
- # cat uprobe_events
- p:uprobes/p_zsh_0x46420 /bin/zsh:0x0000000000046420
- # echo 1 > events/uprobes/enable
- # sleep 20
- # echo 0 > events/uprobes/enable
- # cat trace
- # tracer: nop
- #
- #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
- #              | |       |          |         |
-              zsh-24842 [006] 258544.995456: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-              zsh-24842 [007] 258545.000270: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-              zsh-24842 [002] 258545.043929: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-              zsh-24842 [004] 258547.046129: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-
-commit f3f096cfedf8113380c56fc855275cc75cd8cf55 upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Acked-by: Steven Rostedt <rostedt@goodmis.org>
-Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120411103043.GB29437@linux.vnet.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- Documentation/trace/uprobetracer.txt |   95 ++++
- arch/Kconfig                         |    2 +-
- kernel/trace/Kconfig                 |   16 +
- kernel/trace/Makefile                |    1 +
- kernel/trace/trace.h                 |    5 +
- kernel/trace/trace_kprobe.c          |    2 +-
- kernel/trace/trace_probe.c           |   14 +-
- kernel/trace/trace_probe.h           |    3 +-
- kernel/trace/trace_uprobe.c          |  788 ++++++++++++++++++++++++++++++++++
- 9 files changed, 919 insertions(+), 7 deletions(-)
- create mode 100644 Documentation/trace/uprobetracer.txt
- create mode 100644 kernel/trace/trace_uprobe.c
-
-diff --git a/Documentation/trace/uprobetracer.txt b/Documentation/trace/uprobetracer.txt
-new file mode 100644
-index 0000000..eae40a0
---- /dev/null
-+++ b/Documentation/trace/uprobetracer.txt
-@@ -0,0 +1,95 @@
-+		Uprobe-tracer: Uprobe-based Event Tracing
-+		=========================================
-+                 Documentation written by Srikar Dronamraju
-+
-+Overview
-+--------
-+Uprobe based trace events are similar to kprobe based trace events.
-+To enable this feature, build your kernel with CONFIG_UPROBE_EVENTS=y.
-+
-+Similar to the kprobe-event tracer, this doesn't need to be activated via
-+current_tracer. Instead of that, add probe points via
-+/sys/kernel/debug/tracing/uprobe_events, and enable it via
-+/sys/kernel/debug/tracing/events/uprobes/<EVENT>/enabled.
-+
-+However unlike kprobe-event tracer, the uprobe event interface expects the
-+user to calculate the offset of the probepoint in the object
-+
-+Synopsis of uprobe_tracer
-+-------------------------
-+  p[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS]	: Set a probe
-+
-+ GRP		: Group name. If omitted, use "uprobes" for it.
-+ EVENT		: Event name. If omitted, the event name is generated
-+		  based on SYMBOL+offs.
-+ PATH		: path to an executable or a library.
-+ SYMBOL[+offs]	: Symbol+offset where the probe is inserted.
-+
-+ FETCHARGS	: Arguments. Each probe can have up to 128 args.
-+  %REG		: Fetch register REG
-+
-+Event Profiling
-+---------------
-+ You can check the total number of probe hits and probe miss-hits via
-+/sys/kernel/debug/tracing/uprobe_profile.
-+ The first column is event name, the second is the number of probe hits,
-+the third is the number of probe miss-hits.
-+
-+Usage examples
-+--------------
-+To add a probe as a new event, write a new definition to uprobe_events
-+as below.
-+
-+  echo 'p: /bin/bash:0x4245c0' > /sys/kernel/debug/tracing/uprobe_events
-+
-+ This sets a uprobe at an offset of 0x4245c0 in the executable /bin/bash
-+
-+  echo > /sys/kernel/debug/tracing/uprobe_events
-+
-+ This clears all probe points.
-+
-+The following example shows how to dump the instruction pointer and %ax
-+a register at the probed text address.  Here we are trying to probe
-+function zfree in /bin/zsh
-+
-+    # cd /sys/kernel/debug/tracing/
-+    # cat /proc/`pgrep  zsh`/maps | grep /bin/zsh | grep r-xp
-+    00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
-+    # objdump -T /bin/zsh | grep -w zfree
-+    0000000000446420 g    DF .text  0000000000000012  Base        zfree
-+
-+0x46420 is the offset of zfree in object /bin/zsh that is loaded at
-+0x00400000. Hence the command to probe would be :
-+
-+    # echo 'p /bin/zsh:0x46420 %ip %ax' > uprobe_events
-+
-+Please note: User has to explicitly calculate the offset of the probepoint
-+in the object. We can see the events that are registered by looking at the
-+uprobe_events file.
-+
-+    # cat uprobe_events
-+    p:uprobes/p_zsh_0x46420 /bin/zsh:0x0000000000046420
-+
-+Right after definition, each event is disabled by default. For tracing these
-+events, you need to enable it by:
-+
-+    # echo 1 > events/uprobes/enable
-+
-+Lets disable the event after sleeping for some time.
-+    # sleep 20
-+    # echo 0 > events/uprobes/enable
-+
-+And you can see the traced information via /sys/kernel/debug/tracing/trace.
-+
-+    # cat trace
-+    # tracer: nop
-+    #
-+    #           TASK-PID    CPU#    TIMESTAMP  FUNCTION
-+    #              | |       |          |         |
-+                 zsh-24842 [006] 258544.995456: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-+                 zsh-24842 [007] 258545.000270: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-+                 zsh-24842 [002] 258545.043929: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-+                 zsh-24842 [004] 258547.046129: p_zsh_0x46420: (0x446420) arg1=446421 arg2=79
-+
-+Each line shows us probes were triggered for a pid 24842 with ip being
-+0x446421 and contents of ax register being 79.
-diff --git a/arch/Kconfig b/arch/Kconfig
-index 88b9183..5e4ab5c 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -78,7 +78,7 @@ config OPTPROBES
- 
- config UPROBES
- 	bool "Transparent user-space probes (EXPERIMENTAL)"
--	depends on ARCH_SUPPORTS_UPROBES && PERF_EVENTS
-+	depends on UPROBE_EVENTS && PERF_EVENTS
- 	default n
- 	help
- 	  Uprobes is the user-space counterpart to kprobes: they
-diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
-index ce5a5c5..ea4bff6 100644
---- a/kernel/trace/Kconfig
-+++ b/kernel/trace/Kconfig
-@@ -386,6 +386,22 @@ config KPROBE_EVENT
- 	  This option is also required by perf-probe subcommand of perf tools.
- 	  If you want to use perf tools, this option is strongly recommended.
- 
-+config UPROBE_EVENT
-+	bool "Enable uprobes-based dynamic events"
-+	depends on ARCH_SUPPORTS_UPROBES
-+	depends on MMU
-+	select UPROBES
-+	select PROBE_EVENTS
-+	select TRACING
-+	default n
-+	help
-+	  This allows the user to add tracing events on top of userspace
-+	  dynamic events (similar to tracepoints) on the fly via the trace
-+	  events interface. Those events can be inserted wherever uprobes
-+	  can probe, and record various registers.
-+	  This option is required if you plan to use perf-probe subcommand
-+	  of perf tools on user space applications.
-+
- config PROBE_EVENTS
- 	def_bool n
- 
-diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
-index fa10d5c..1734c03 100644
---- a/kernel/trace/Makefile
-+++ b/kernel/trace/Makefile
-@@ -62,5 +62,6 @@ ifeq ($(CONFIG_TRACING),y)
- obj-$(CONFIG_KGDB_KDB) += trace_kdb.o
- endif
- obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
-+obj-$(CONFIG_UPROBE_EVENT) += trace_uprobe.o
- 
- libftrace-y := ftrace.o
-diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
-index f95d65d..a6bf705 100644
---- a/kernel/trace/trace.h
-+++ b/kernel/trace/trace.h
-@@ -103,6 +103,11 @@ struct kretprobe_trace_entry_head {
- 	unsigned long		ret_ip;
- };
- 
-+struct uprobe_trace_entry_head {
-+	struct trace_entry	ent;
-+	unsigned long		ip;
-+};
-+
- /*
-  * trace_flag_type is an enumeration that holds different
-  * states when a trace occurs. These are:
-diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
-index f8b7773..b31d3d5 100644
---- a/kernel/trace/trace_kprobe.c
-+++ b/kernel/trace/trace_kprobe.c
-@@ -525,7 +525,7 @@ static int create_trace_probe(int argc, char **argv)
- 
- 		/* Parse fetch argument */
- 		ret = traceprobe_parse_probe_arg(arg, &tp->size, &tp->args[i],
--								is_return);
-+						is_return, true);
- 		if (ret) {
- 			pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
- 			goto error;
-diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
-index 8e526b9..daa9980 100644
---- a/kernel/trace/trace_probe.c
-+++ b/kernel/trace/trace_probe.c
-@@ -550,7 +550,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
- 
- /* Recursive argument parser */
- static int parse_probe_arg(char *arg, const struct fetch_type *t,
--		     struct fetch_param *f, bool is_return)
-+		     struct fetch_param *f, bool is_return, bool is_kprobe)
- {
- 	unsigned long param;
- 	long offset;
-@@ -558,6 +558,11 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
- 	int ret;
- 
- 	ret = 0;
-+
-+	/* Until uprobe_events supports only reg arguments */
-+	if (!is_kprobe && arg[0] != '%')
-+		return -EINVAL;
-+
- 	switch (arg[0]) {
- 	case '$':
- 		ret = parse_probe_vars(arg + 1, t, f, is_return);
-@@ -619,7 +624,8 @@ static int parse_probe_arg(char *arg, const struct fetch_type *t,
- 				return -ENOMEM;
- 
- 			dprm->offset = offset;
--			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return);
-+			ret = parse_probe_arg(arg, t2, &dprm->orig, is_return,
-+							is_kprobe);
- 			if (ret)
- 				kfree(dprm);
- 			else {
-@@ -677,7 +683,7 @@ static int __parse_bitfield_probe_arg(const char *bf,
- 
- /* String length checking wrapper */
- int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
--		struct probe_arg *parg, bool is_return)
-+		struct probe_arg *parg, bool is_return, bool is_kprobe)
- {
- 	const char *t;
- 	int ret;
-@@ -703,7 +709,7 @@ int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
- 	}
- 	parg->offset = *size;
- 	*size += parg->type->size;
--	ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return);
-+	ret = parse_probe_arg(arg, parg->type, &parg->fetch, is_return, is_kprobe);
- 
- 	if (ret >= 0 && t != NULL)
- 		ret = __parse_bitfield_probe_arg(t, parg->type, &parg->fetch);
-diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
-index 2df9a18..9337086 100644
---- a/kernel/trace/trace_probe.h
-+++ b/kernel/trace/trace_probe.h
-@@ -66,6 +66,7 @@
- #define TP_FLAG_TRACE		1
- #define TP_FLAG_PROFILE		2
- #define TP_FLAG_REGISTERED	4
-+#define TP_FLAG_UPROBE		8
- 
- 
- /* data_rloc: data relative location, compatible with u32 */
-@@ -143,7 +144,7 @@ static inline int is_good_name(const char *name)
- }
- 
- extern int traceprobe_parse_probe_arg(char *arg, ssize_t *size,
--		   struct probe_arg *parg, bool is_return);
-+		   struct probe_arg *parg, bool is_return, bool is_kprobe);
- 
- extern int traceprobe_conflict_field_name(const char *name,
- 			       struct probe_arg *args, int narg);
-diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
-new file mode 100644
-index 0000000..2b36ac6
---- /dev/null
-+++ b/kernel/trace/trace_uprobe.c
-@@ -0,0 +1,788 @@
-+/*
-+ * uprobes-based tracing events
-+ *
-+ * 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.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-+ *
-+ * Copyright (C) IBM Corporation, 2010-2012
-+ * Author:	Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/uaccess.h>
-+#include <linux/uprobes.h>
-+#include <linux/namei.h>
-+
-+#include "trace_probe.h"
-+
-+#define UPROBE_EVENT_SYSTEM	"uprobes"
-+
-+/*
-+ * uprobe event core functions
-+ */
-+struct trace_uprobe;
-+struct uprobe_trace_consumer {
-+	struct uprobe_consumer		cons;
-+	struct trace_uprobe		*tu;
-+};
-+
-+struct trace_uprobe {
-+	struct list_head		list;
-+	struct ftrace_event_class	class;
-+	struct ftrace_event_call	call;
-+	struct uprobe_trace_consumer	*consumer;
-+	struct inode			*inode;
-+	char				*filename;
-+	unsigned long			offset;
-+	unsigned long			nhit;
-+	unsigned int			flags;	/* For TP_FLAG_* */
-+	ssize_t				size;	/* trace entry size */
-+	unsigned int			nr_args;
-+	struct probe_arg		args[];
-+};
-+
-+#define SIZEOF_TRACE_UPROBE(n)			\
-+	(offsetof(struct trace_uprobe, args) +	\
-+	(sizeof(struct probe_arg) * (n)))
-+
-+static int register_uprobe_event(struct trace_uprobe *tu);
-+static void unregister_uprobe_event(struct trace_uprobe *tu);
-+
-+static DEFINE_MUTEX(uprobe_lock);
-+static LIST_HEAD(uprobe_list);
-+
-+static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs);
-+
-+/*
-+ * Allocate new trace_uprobe and initialize it (including uprobes).
-+ */
-+static struct trace_uprobe *
-+alloc_trace_uprobe(const char *group, const char *event, int nargs)
-+{
-+	struct trace_uprobe *tu;
-+
-+	if (!event || !is_good_name(event))
-+		return ERR_PTR(-EINVAL);
-+
-+	if (!group || !is_good_name(group))
-+		return ERR_PTR(-EINVAL);
-+
-+	tu = kzalloc(SIZEOF_TRACE_UPROBE(nargs), GFP_KERNEL);
-+	if (!tu)
-+		return ERR_PTR(-ENOMEM);
-+
-+	tu->call.class = &tu->class;
-+	tu->call.name = kstrdup(event, GFP_KERNEL);
-+	if (!tu->call.name)
-+		goto error;
-+
-+	tu->class.system = kstrdup(group, GFP_KERNEL);
-+	if (!tu->class.system)
-+		goto error;
-+
-+	INIT_LIST_HEAD(&tu->list);
-+	return tu;
-+
-+error:
-+	kfree(tu->call.name);
-+	kfree(tu);
-+
-+	return ERR_PTR(-ENOMEM);
-+}
-+
-+static void free_trace_uprobe(struct trace_uprobe *tu)
-+{
-+	int i;
-+
-+	for (i = 0; i < tu->nr_args; i++)
-+		traceprobe_free_probe_arg(&tu->args[i]);
-+
-+	iput(tu->inode);
-+	kfree(tu->call.class->system);
-+	kfree(tu->call.name);
-+	kfree(tu->filename);
-+	kfree(tu);
-+}
-+
-+static struct trace_uprobe *find_probe_event(const char *event, const char *group)
-+{
-+	struct trace_uprobe *tu;
-+
-+	list_for_each_entry(tu, &uprobe_list, list)
-+		if (strcmp(tu->call.name, event) == 0 &&
-+		    strcmp(tu->call.class->system, group) == 0)
-+			return tu;
-+
-+	return NULL;
-+}
-+
-+/* Unregister a trace_uprobe and probe_event: call with locking uprobe_lock */
-+static void unregister_trace_uprobe(struct trace_uprobe *tu)
-+{
-+	list_del(&tu->list);
-+	unregister_uprobe_event(tu);
-+	free_trace_uprobe(tu);
-+}
-+
-+/* Register a trace_uprobe and probe_event */
-+static int register_trace_uprobe(struct trace_uprobe *tu)
-+{
-+	struct trace_uprobe *old_tp;
-+	int ret;
-+
-+	mutex_lock(&uprobe_lock);
-+
-+	/* register as an event */
-+	old_tp = find_probe_event(tu->call.name, tu->call.class->system);
-+	if (old_tp)
-+		/* delete old event */
-+		unregister_trace_uprobe(old_tp);
-+
-+	ret = register_uprobe_event(tu);
-+	if (ret) {
-+		pr_warning("Failed to register probe event(%d)\n", ret);
-+		goto end;
-+	}
-+
-+	list_add_tail(&tu->list, &uprobe_list);
-+
-+end:
-+	mutex_unlock(&uprobe_lock);
-+
-+	return ret;
-+}
-+
-+/*
-+ * Argument syntax:
-+ *  - Add uprobe: p[:[GRP/]EVENT] PATH:SYMBOL[+offs] [FETCHARGS]
-+ *
-+ *  - Remove uprobe: -:[GRP/]EVENT
-+ */
-+static int create_trace_uprobe(int argc, char **argv)
-+{
-+	struct trace_uprobe *tu;
-+	struct inode *inode;
-+	char *arg, *event, *group, *filename;
-+	char buf[MAX_EVENT_NAME_LEN];
-+	struct path path;
-+	unsigned long offset;
-+	bool is_delete;
-+	int i, ret;
-+
-+	inode = NULL;
-+	ret = 0;
-+	is_delete = false;
-+	event = NULL;
-+	group = NULL;
-+
-+	/* argc must be >= 1 */
-+	if (argv[0][0] == '-')
-+		is_delete = true;
-+	else if (argv[0][0] != 'p') {
-+		pr_info("Probe definition must be started with 'p', 'r' or" " '-'.\n");
-+		return -EINVAL;
-+	}
-+
-+	if (argv[0][1] == ':') {
-+		event = &argv[0][2];
-+		arg = strchr(event, '/');
-+
-+		if (arg) {
-+			group = event;
-+			event = arg + 1;
-+			event[-1] = '\0';
-+
-+			if (strlen(group) == 0) {
-+				pr_info("Group name is not specified\n");
-+				return -EINVAL;
-+			}
-+		}
-+		if (strlen(event) == 0) {
-+			pr_info("Event name is not specified\n");
-+			return -EINVAL;
-+		}
-+	}
-+	if (!group)
-+		group = UPROBE_EVENT_SYSTEM;
-+
-+	if (is_delete) {
-+		if (!event) {
-+			pr_info("Delete command needs an event name.\n");
-+			return -EINVAL;
-+		}
-+		mutex_lock(&uprobe_lock);
-+		tu = find_probe_event(event, group);
-+
-+		if (!tu) {
-+			mutex_unlock(&uprobe_lock);
-+			pr_info("Event %s/%s doesn't exist.\n", group, event);
-+			return -ENOENT;
-+		}
-+		/* delete an event */
-+		unregister_trace_uprobe(tu);
-+		mutex_unlock(&uprobe_lock);
-+		return 0;
-+	}
-+
-+	if (argc < 2) {
-+		pr_info("Probe point is not specified.\n");
-+		return -EINVAL;
-+	}
-+	if (isdigit(argv[1][0])) {
-+		pr_info("probe point must be have a filename.\n");
-+		return -EINVAL;
-+	}
-+	arg = strchr(argv[1], ':');
-+	if (!arg)
-+		goto fail_address_parse;
-+
-+	*arg++ = '\0';
-+	filename = argv[1];
-+	ret = kern_path(filename, LOOKUP_FOLLOW, &path);
-+	if (ret)
-+		goto fail_address_parse;
-+
-+	ret = strict_strtoul(arg, 0, &offset);
-+	if (ret)
-+		goto fail_address_parse;
-+
-+	inode = igrab(path.dentry->d_inode);
-+
-+	argc -= 2;
-+	argv += 2;
-+
-+	/* setup a probe */
-+	if (!event) {
-+		char *tail = strrchr(filename, '/');
-+		char *ptr;
-+
-+		ptr = kstrdup((tail ? tail + 1 : filename), GFP_KERNEL);
-+		if (!ptr) {
-+			ret = -ENOMEM;
-+			goto fail_address_parse;
-+		}
-+
-+		tail = ptr;
-+		ptr = strpbrk(tail, ".-_");
-+		if (ptr)
-+			*ptr = '\0';
-+
-+		snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_0x%lx", 'p', tail, offset);
-+		event = buf;
-+		kfree(tail);
-+	}
-+
-+	tu = alloc_trace_uprobe(group, event, argc);
-+	if (IS_ERR(tu)) {
-+		pr_info("Failed to allocate trace_uprobe.(%d)\n", (int)PTR_ERR(tu));
-+		ret = PTR_ERR(tu);
-+		goto fail_address_parse;
-+	}
-+	tu->offset = offset;
-+	tu->inode = inode;
-+	tu->filename = kstrdup(filename, GFP_KERNEL);
-+
-+	if (!tu->filename) {
-+		pr_info("Failed to allocate filename.\n");
-+		ret = -ENOMEM;
-+		goto error;
-+	}
-+
-+	/* parse arguments */
-+	ret = 0;
-+	for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
-+		/* Increment count for freeing args in error case */
-+		tu->nr_args++;
-+
-+		/* Parse argument name */
-+		arg = strchr(argv[i], '=');
-+		if (arg) {
-+			*arg++ = '\0';
-+			tu->args[i].name = kstrdup(argv[i], GFP_KERNEL);
-+		} else {
-+			arg = argv[i];
-+			/* If argument name is omitted, set "argN" */
-+			snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
-+			tu->args[i].name = kstrdup(buf, GFP_KERNEL);
-+		}
-+
-+		if (!tu->args[i].name) {
-+			pr_info("Failed to allocate argument[%d] name.\n", i);
-+			ret = -ENOMEM;
-+			goto error;
-+		}
-+
-+		if (!is_good_name(tu->args[i].name)) {
-+			pr_info("Invalid argument[%d] name: %s\n", i, tu->args[i].name);
-+			ret = -EINVAL;
-+			goto error;
-+		}
-+
-+		if (traceprobe_conflict_field_name(tu->args[i].name, tu->args, i)) {
-+			pr_info("Argument[%d] name '%s' conflicts with "
-+				"another field.\n", i, argv[i]);
-+			ret = -EINVAL;
-+			goto error;
-+		}
-+
-+		/* Parse fetch argument */
-+		ret = traceprobe_parse_probe_arg(arg, &tu->size, &tu->args[i], false, false);
-+		if (ret) {
-+			pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
-+			goto error;
-+		}
-+	}
-+
-+	ret = register_trace_uprobe(tu);
-+	if (ret)
-+		goto error;
-+	return 0;
-+
-+error:
-+	free_trace_uprobe(tu);
-+	return ret;
-+
-+fail_address_parse:
-+	if (inode)
-+		iput(inode);
-+
-+	pr_info("Failed to parse address.\n");
-+
-+	return ret;
-+}
-+
-+static void cleanup_all_probes(void)
-+{
-+	struct trace_uprobe *tu;
-+
-+	mutex_lock(&uprobe_lock);
-+	while (!list_empty(&uprobe_list)) {
-+		tu = list_entry(uprobe_list.next, struct trace_uprobe, list);
-+		unregister_trace_uprobe(tu);
-+	}
-+	mutex_unlock(&uprobe_lock);
-+}
-+
-+/* Probes listing interfaces */
-+static void *probes_seq_start(struct seq_file *m, loff_t *pos)
-+{
-+	mutex_lock(&uprobe_lock);
-+	return seq_list_start(&uprobe_list, *pos);
-+}
-+
-+static void *probes_seq_next(struct seq_file *m, void *v, loff_t *pos)
-+{
-+	return seq_list_next(v, &uprobe_list, pos);
-+}
-+
-+static void probes_seq_stop(struct seq_file *m, void *v)
-+{
-+	mutex_unlock(&uprobe_lock);
-+}
-+
-+static int probes_seq_show(struct seq_file *m, void *v)
-+{
-+	struct trace_uprobe *tu = v;
-+	int i;
-+
-+	seq_printf(m, "p:%s/%s", tu->call.class->system, tu->call.name);
-+	seq_printf(m, " %s:0x%p", tu->filename, (void *)tu->offset);
-+
-+	for (i = 0; i < tu->nr_args; i++)
-+		seq_printf(m, " %s=%s", tu->args[i].name, tu->args[i].comm);
-+
-+	seq_printf(m, "\n");
-+	return 0;
-+}
-+
-+static const struct seq_operations probes_seq_op = {
-+	.start	= probes_seq_start,
-+	.next	= probes_seq_next,
-+	.stop	= probes_seq_stop,
-+	.show	= probes_seq_show
-+};
-+
-+static int probes_open(struct inode *inode, struct file *file)
-+{
-+	if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC))
-+		cleanup_all_probes();
-+
-+	return seq_open(file, &probes_seq_op);
-+}
-+
-+static ssize_t probes_write(struct file *file, const char __user *buffer,
-+			    size_t count, loff_t *ppos)
-+{
-+	return traceprobe_probes_write(file, buffer, count, ppos, create_trace_uprobe);
-+}
-+
-+static const struct file_operations uprobe_events_ops = {
-+	.owner		= THIS_MODULE,
-+	.open		= probes_open,
-+	.read		= seq_read,
-+	.llseek		= seq_lseek,
-+	.release	= seq_release,
-+	.write		= probes_write,
-+};
-+
-+/* Probes profiling interfaces */
-+static int probes_profile_seq_show(struct seq_file *m, void *v)
-+{
-+	struct trace_uprobe *tu = v;
-+
-+	seq_printf(m, "  %s %-44s %15lu\n", tu->filename, tu->call.name, tu->nhit);
-+	return 0;
-+}
-+
-+static const struct seq_operations profile_seq_op = {
-+	.start	= probes_seq_start,
-+	.next	= probes_seq_next,
-+	.stop	= probes_seq_stop,
-+	.show	= probes_profile_seq_show
-+};
-+
-+static int profile_open(struct inode *inode, struct file *file)
-+{
-+	return seq_open(file, &profile_seq_op);
-+}
-+
-+static const struct file_operations uprobe_profile_ops = {
-+	.owner		= THIS_MODULE,
-+	.open		= profile_open,
-+	.read		= seq_read,
-+	.llseek		= seq_lseek,
-+	.release	= seq_release,
-+};
-+
-+/* uprobe handler */
-+static void uprobe_trace_func(struct trace_uprobe *tu, struct pt_regs *regs)
-+{
-+	struct uprobe_trace_entry_head *entry;
-+	struct ring_buffer_event *event;
-+	struct ring_buffer *buffer;
-+	u8 *data;
-+	int size, i, pc;
-+	unsigned long irq_flags;
-+	struct ftrace_event_call *call = &tu->call;
-+
-+	tu->nhit++;
-+
-+	local_save_flags(irq_flags);
-+	pc = preempt_count();
-+
-+	size = sizeof(*entry) + tu->size;
-+
-+	event = trace_current_buffer_lock_reserve(&buffer, call->event.type,
-+						  size, irq_flags, pc);
-+	if (!event)
-+		return;
-+
-+	entry = ring_buffer_event_data(event);
-+	entry->ip = uprobe_get_swbp_addr(task_pt_regs(current));
-+	data = (u8 *)&entry[1];
-+	for (i = 0; i < tu->nr_args; i++)
-+		call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset);
-+
-+	if (!filter_current_check_discard(buffer, call, entry, event))
-+		trace_buffer_unlock_commit(buffer, event, irq_flags, pc);
-+}
-+
-+/* Event entry printers */
-+static enum print_line_t
-+print_uprobe_event(struct trace_iterator *iter, int flags, struct trace_event *event)
-+{
-+	struct uprobe_trace_entry_head *field;
-+	struct trace_seq *s = &iter->seq;
-+	struct trace_uprobe *tu;
-+	u8 *data;
-+	int i;
-+
-+	field = (struct uprobe_trace_entry_head *)iter->ent;
-+	tu = container_of(event, struct trace_uprobe, call.event);
-+
-+	if (!trace_seq_printf(s, "%s: (", tu->call.name))
-+		goto partial;
-+
-+	if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
-+		goto partial;
-+
-+	if (!trace_seq_puts(s, ")"))
-+		goto partial;
-+
-+	data = (u8 *)&field[1];
-+	for (i = 0; i < tu->nr_args; i++) {
-+		if (!tu->args[i].type->print(s, tu->args[i].name,
-+					     data + tu->args[i].offset, field))
-+			goto partial;
-+	}
-+
-+	if (trace_seq_puts(s, "\n"))
-+		return TRACE_TYPE_HANDLED;
-+
-+partial:
-+	return TRACE_TYPE_PARTIAL_LINE;
-+}
-+
-+static int probe_event_enable(struct trace_uprobe *tu, int flag)
-+{
-+	struct uprobe_trace_consumer *utc;
-+	int ret = 0;
-+
-+	if (!tu->inode || tu->consumer)
-+		return -EINTR;
-+
-+	utc = kzalloc(sizeof(struct uprobe_trace_consumer), GFP_KERNEL);
-+	if (!utc)
-+		return -EINTR;
-+
-+	utc->cons.handler = uprobe_dispatcher;
-+	utc->cons.filter = NULL;
-+	ret = uprobe_register(tu->inode, tu->offset, &utc->cons);
-+	if (ret) {
-+		kfree(utc);
-+		return ret;
-+	}
-+
-+	tu->flags |= flag;
-+	utc->tu = tu;
-+	tu->consumer = utc;
-+
-+	return 0;
-+}
-+
-+static void probe_event_disable(struct trace_uprobe *tu, int flag)
-+{
-+	if (!tu->inode || !tu->consumer)
-+		return;
-+
-+	uprobe_unregister(tu->inode, tu->offset, &tu->consumer->cons);
-+	tu->flags &= ~flag;
-+	kfree(tu->consumer);
-+	tu->consumer = NULL;
-+}
-+
-+static int uprobe_event_define_fields(struct ftrace_event_call *event_call)
-+{
-+	int ret, i;
-+	struct uprobe_trace_entry_head field;
-+	struct trace_uprobe *tu = (struct trace_uprobe *)event_call->data;
-+
-+	DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
-+	/* Set argument names as fields */
-+	for (i = 0; i < tu->nr_args; i++) {
-+		ret = trace_define_field(event_call, tu->args[i].type->fmttype,
-+					 tu->args[i].name,
-+					 sizeof(field) + tu->args[i].offset,
-+					 tu->args[i].type->size,
-+					 tu->args[i].type->is_signed,
-+					 FILTER_OTHER);
-+
-+		if (ret)
-+			return ret;
-+	}
-+	return 0;
-+}
-+
-+#define LEN_OR_ZERO		(len ? len - pos : 0)
-+static int __set_print_fmt(struct trace_uprobe *tu, char *buf, int len)
-+{
-+	const char *fmt, *arg;
-+	int i;
-+	int pos = 0;
-+
-+	fmt = "(%lx)";
-+	arg = "REC->" FIELD_STRING_IP;
-+
-+	/* When len=0, we just calculate the needed length */
-+
-+	pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
-+
-+	for (i = 0; i < tu->nr_args; i++) {
-+		pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
-+				tu->args[i].name, tu->args[i].type->fmt);
-+	}
-+
-+	pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
-+
-+	for (i = 0; i < tu->nr_args; i++) {
-+		pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
-+				tu->args[i].name);
-+	}
-+
-+	return pos;	/* return the length of print_fmt */
-+}
-+#undef LEN_OR_ZERO
-+
-+static int set_print_fmt(struct trace_uprobe *tu)
-+{
-+	char *print_fmt;
-+	int len;
-+
-+	/* First: called with 0 length to calculate the needed length */
-+	len = __set_print_fmt(tu, NULL, 0);
-+	print_fmt = kmalloc(len + 1, GFP_KERNEL);
-+	if (!print_fmt)
-+		return -ENOMEM;
-+
-+	/* Second: actually write the @print_fmt */
-+	__set_print_fmt(tu, print_fmt, len + 1);
-+	tu->call.print_fmt = print_fmt;
-+
-+	return 0;
-+}
-+
-+#ifdef CONFIG_PERF_EVENTS
-+/* uprobe profile handler */
-+static void uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs)
-+{
-+	struct ftrace_event_call *call = &tu->call;
-+	struct uprobe_trace_entry_head *entry;
-+	struct hlist_head *head;
-+	u8 *data;
-+	int size, __size, i;
-+	int rctx;
-+
-+	__size = sizeof(*entry) + tu->size;
-+	size = ALIGN(__size + sizeof(u32), sizeof(u64));
-+	size -= sizeof(u32);
-+	if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, "profile buffer not large enough"))
-+		return;
-+
-+	preempt_disable();
-+
-+	entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
-+	if (!entry)
-+		goto out;
-+
-+	entry->ip = uprobe_get_swbp_addr(task_pt_regs(current));
-+	data = (u8 *)&entry[1];
-+	for (i = 0; i < tu->nr_args; i++)
-+		call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset);
-+
-+	head = this_cpu_ptr(call->perf_events);
-+	perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head);
-+
-+ out:
-+	preempt_enable();
-+}
-+#endif	/* CONFIG_PERF_EVENTS */
-+
-+static
-+int trace_uprobe_register(struct ftrace_event_call *event, enum trace_reg type, void *data)
-+{
-+	struct trace_uprobe *tu = (struct trace_uprobe *)event->data;
-+
-+	switch (type) {
-+	case TRACE_REG_REGISTER:
-+		return probe_event_enable(tu, TP_FLAG_TRACE);
-+
-+	case TRACE_REG_UNREGISTER:
-+		probe_event_disable(tu, TP_FLAG_TRACE);
-+		return 0;
-+
-+#ifdef CONFIG_PERF_EVENTS
-+	case TRACE_REG_PERF_REGISTER:
-+		return probe_event_enable(tu, TP_FLAG_PROFILE);
-+
-+	case TRACE_REG_PERF_UNREGISTER:
-+		probe_event_disable(tu, TP_FLAG_PROFILE);
-+		return 0;
-+#endif
-+	default:
-+		return 0;
-+	}
-+	return 0;
-+}
-+
-+static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs)
-+{
-+	struct uprobe_trace_consumer *utc;
-+	struct trace_uprobe *tu;
-+
-+	utc = container_of(con, struct uprobe_trace_consumer, cons);
-+	tu = utc->tu;
-+	if (!tu || tu->consumer != utc)
-+		return 0;
-+
-+	if (tu->flags & TP_FLAG_TRACE)
-+		uprobe_trace_func(tu, regs);
-+
-+#ifdef CONFIG_PERF_EVENTS
-+	if (tu->flags & TP_FLAG_PROFILE)
-+		uprobe_perf_func(tu, regs);
-+#endif
-+	return 0;
-+}
-+
-+static struct trace_event_functions uprobe_funcs = {
-+	.trace		= print_uprobe_event
-+};
-+
-+static int register_uprobe_event(struct trace_uprobe *tu)
-+{
-+	struct ftrace_event_call *call = &tu->call;
-+	int ret;
-+
-+	/* Initialize ftrace_event_call */
-+	INIT_LIST_HEAD(&call->class->fields);
-+	call->event.funcs = &uprobe_funcs;
-+	call->class->define_fields = uprobe_event_define_fields;
-+
-+	if (set_print_fmt(tu) < 0)
-+		return -ENOMEM;
-+
-+	ret = register_ftrace_event(&call->event);
-+	if (!ret) {
-+		kfree(call->print_fmt);
-+		return -ENODEV;
-+	}
-+	call->flags = 0;
-+	call->class->reg = trace_uprobe_register;
-+	call->data = tu;
-+	ret = trace_add_event_call(call);
-+
-+	if (ret) {
-+		pr_info("Failed to register uprobe event: %s\n", call->name);
-+		kfree(call->print_fmt);
-+		unregister_ftrace_event(&call->event);
-+	}
-+
-+	return ret;
-+}
-+
-+static void unregister_uprobe_event(struct trace_uprobe *tu)
-+{
-+	/* tu->event is unregistered in trace_remove_event_call() */
-+	trace_remove_event_call(&tu->call);
-+	kfree(tu->call.print_fmt);
-+	tu->call.print_fmt = NULL;
-+}
-+
-+/* Make a trace interface for controling probe points */
-+static __init int init_uprobe_trace(void)
-+{
-+	struct dentry *d_tracer;
-+
-+	d_tracer = tracing_init_dentry();
-+	if (!d_tracer)
-+		return 0;
-+
-+	trace_create_file("uprobe_events", 0644, d_tracer,
-+				    NULL, &uprobe_events_ops);
-+	/* Profile interface */
-+	trace_create_file("uprobe_profile", 0444, d_tracer,
-+				    NULL, &uprobe_profile_ops);
-+	return 0;
-+}
-+
-+fs_initcall(init_uprobe_trace);
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobe.scc b/features/uprobe/uprobe.scc
index 15e519c3fca5ec426e529526c14125a8478a224d..39391a51a07d0459466371568222c925888a962e 100644
--- a/features/uprobe/uprobe.scc
+++ b/features/uprobe/uprobe.scc
@@ -1,32 +1 @@
 # place holder for uprobe
-patch uprobes-mm-x86-Add-the-ability-to-install-and-remove.patch
-patch uprobes-core-Clean-up-refactor-and-improve-the-code.patch
-patch uprobes-Move-to-kernel-events.patch
-patch uprobes-core-Make-instruction-tables-volatile.patch
-patch uprobes-core-Remove-uprobe_opcode_sz.patch
-patch uprobes-core-Move-insn-to-arch-specific-structure.patch
-patch uprobes-Update-copyright-notices.patch
-patch uprobes-core-Make-macro-names-consistent.patch
-patch uprobes-core-Make-order-of-function-parameters-consi.patch
-patch uprobes-core-Rename-bkpt-to-swbp.patch
-patch uprobes-core-Handle-breakpoint-and-singlestep-except.patch
-patch uprobes-core-Allocate-XOL-slots-for-uprobes-use.patch
-patch uprobes-core-Optimize-probe-hits-with-the-help-of-a-.patch
-patch uprobes-core-Make-background-page-replacement-logic-.patch
-patch uprobes-core-Decrement-uprobe-count-before-the-pages.patch
-patch tracing-Modify-is_delete-is_return-from-int-to-bool.patch
-patch tracing-Extract-out-common-code-for-kprobes-uprobes-.patch
-patch tracing-Provide-trace-events-interface-for-uprobes.patch
-patch tracing-Fix-kconfig-warning-due-to-a-typo.patch
-patch perf-probe-Provide-perf-interface-for-uprobes.patch
-patch perf-probe-Detect-probe-target-when-m-x-options-are-.patch
-patch On-RISC-architectures-like-powerpc-instructions-are-.patch
-patch powerpc-Add-trap_nr-to-thread_struct.patch
-patch powerpc-Uprobes-port-to-powerpc.patch
-patch powerpc-uprobes-removed-external-declaration-of-upro.patch
-patch move-key_repace_session_keyring-into-tracehook_notif.patch
-patch task_work_add-generic-process-context-callbacks.patch
-patch genirq-reimplement-exit_irq_thread-hook-via-task_wor.patch
-patch keys-change-keyctl_session_to_parent-to-use-task_wor.patch
-patch keys-kill-the-dummy-key_replace_session_keyring.patch
-patch keys-kill-task_struct-replacement_session_keyring.patch
diff --git a/features/uprobe/uprobes-Move-to-kernel-events.patch b/features/uprobe/uprobes-Move-to-kernel-events.patch
deleted file mode 100644
index f4872403b3da61c98fca45fbedcd6e14e1241c5e..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-Move-to-kernel-events.patch
+++ /dev/null
@@ -1,2105 +0,0 @@
-From 56c1e99bdd34661e774e055d6748685310284306 Mon Sep 17 00:00:00 2001
-From: Ingo Molnar <mingo@elte.hu>
-Date: Wed, 22 Feb 2012 11:01:49 +0100
-Subject: [PATCH 03/24] uprobes: Move to kernel/events/
-
-Consolidate the uprobes code under kernel/events/, where the various
-core kernel event handling routines live.
-
-commit a5f4374a9610fd7286c2164d4e680436727eff71 upstream
-
-Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
-Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Jim Keniston <jkenisto@us.ibm.com>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Link: http://lkml.kernel.org/n/tip-biuyhhwohxgbp2vzbap5yr8o@git.kernel.org
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/Kconfig            |    2 +-
- kernel/Makefile         |    1 -
- kernel/events/Makefile  |    3 +
- kernel/events/uprobes.c | 1011 +++++++++++++++++++++++++++++++++++++++++++++++
- kernel/uprobes.c        | 1011 -----------------------------------------------
- 5 files changed, 1015 insertions(+), 1013 deletions(-)
- create mode 100644 kernel/events/uprobes.c
- delete mode 100644 kernel/uprobes.c
-
-diff --git a/arch/Kconfig b/arch/Kconfig
-index b78bf33..88b9183 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -78,7 +78,7 @@ config OPTPROBES
- 
- config UPROBES
- 	bool "Transparent user-space probes (EXPERIMENTAL)"
--	depends on ARCH_SUPPORTS_UPROBES
-+	depends on ARCH_SUPPORTS_UPROBES && PERF_EVENTS
- 	default n
- 	help
- 	  Uprobes is the user-space counterpart to kprobes: they
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 72ea789..633b548 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -107,7 +107,6 @@ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
- obj-$(CONFIG_PADATA) += padata.o
- obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
- obj-$(CONFIG_JUMP_LABEL) += jump_label.o
--obj-$(CONFIG_UPROBES) += uprobes.o
- 
- $(obj)/configs.o: $(obj)/config_data.h
- 
-diff --git a/kernel/events/Makefile b/kernel/events/Makefile
-index 22d901f..103f5d1 100644
---- a/kernel/events/Makefile
-+++ b/kernel/events/Makefile
-@@ -3,4 +3,7 @@ CFLAGS_REMOVE_core.o = -pg
- endif
- 
- obj-y := core.o ring_buffer.o callchain.o
-+
- obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
-+obj-$(CONFIG_UPROBES) += uprobes.o
-+
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-new file mode 100644
-index 0000000..884817f
---- /dev/null
-+++ b/kernel/events/uprobes.c
-@@ -0,0 +1,1011 @@
-+/*
-+ * User-space Probes (UProbes)
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2008-2011
-+ * Authors:
-+ *	Srikar Dronamraju
-+ *	Jim Keniston
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/highmem.h>
-+#include <linux/pagemap.h>	/* read_mapping_page */
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/rmap.h>		/* anon_vma_prepare */
-+#include <linux/mmu_notifier.h>	/* set_pte_at_notify */
-+#include <linux/swap.h>		/* try_to_free_swap */
-+
-+#include <linux/uprobes.h>
-+
-+static struct rb_root uprobes_tree = RB_ROOT;
-+
-+static DEFINE_SPINLOCK(uprobes_treelock);	/* serialize rbtree access */
-+
-+#define UPROBES_HASH_SZ	13
-+
-+/* serialize (un)register */
-+static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
-+
-+#define uprobes_hash(v)		(&uprobes_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
-+
-+/* serialize uprobe->pending_list */
-+static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
-+#define uprobes_mmap_hash(v)	(&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
-+
-+/*
-+ * uprobe_events allows us to skip the uprobe_mmap if there are no uprobe
-+ * events active at this time.  Probably a fine grained per inode count is
-+ * better?
-+ */
-+static atomic_t uprobe_events = ATOMIC_INIT(0);
-+
-+/*
-+ * Maintain a temporary per vma info that can be used to search if a vma
-+ * has already been handled. This structure is introduced since extending
-+ * vm_area_struct wasnt recommended.
-+ */
-+struct vma_info {
-+	struct list_head	probe_list;
-+	struct mm_struct	*mm;
-+	loff_t			vaddr;
-+};
-+
-+/*
-+ * valid_vma: Verify if the specified vma is an executable vma
-+ * Relax restrictions while unregistering: vm_flags might have
-+ * changed after breakpoint was inserted.
-+ *	- is_register: indicates if we are in register context.
-+ *	- Return 1 if the specified virtual address is in an
-+ *	  executable vma.
-+ */
-+static bool valid_vma(struct vm_area_struct *vma, bool is_register)
-+{
-+	if (!vma->vm_file)
-+		return false;
-+
-+	if (!is_register)
-+		return true;
-+
-+	if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC))
-+		return true;
-+
-+	return false;
-+}
-+
-+static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
-+{
-+	loff_t vaddr;
-+
-+	vaddr = vma->vm_start + offset;
-+	vaddr -= vma->vm_pgoff << PAGE_SHIFT;
-+
-+	return vaddr;
-+}
-+
-+/**
-+ * __replace_page - replace page in vma by new page.
-+ * based on replace_page in mm/ksm.c
-+ *
-+ * @vma:      vma that holds the pte pointing to page
-+ * @page:     the cowed page we are replacing by kpage
-+ * @kpage:    the modified page we replace page by
-+ *
-+ * Returns 0 on success, -EFAULT on failure.
-+ */
-+static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage)
-+{
-+	struct mm_struct *mm = vma->vm_mm;
-+	pgd_t *pgd;
-+	pud_t *pud;
-+	pmd_t *pmd;
-+	pte_t *ptep;
-+	spinlock_t *ptl;
-+	unsigned long addr;
-+	int err = -EFAULT;
-+
-+	addr = page_address_in_vma(page, vma);
-+	if (addr == -EFAULT)
-+		goto out;
-+
-+	pgd = pgd_offset(mm, addr);
-+	if (!pgd_present(*pgd))
-+		goto out;
-+
-+	pud = pud_offset(pgd, addr);
-+	if (!pud_present(*pud))
-+		goto out;
-+
-+	pmd = pmd_offset(pud, addr);
-+	if (!pmd_present(*pmd))
-+		goto out;
-+
-+	ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
-+	if (!ptep)
-+		goto out;
-+
-+	get_page(kpage);
-+	page_add_new_anon_rmap(kpage, vma, addr);
-+
-+	flush_cache_page(vma, addr, pte_pfn(*ptep));
-+	ptep_clear_flush(vma, addr, ptep);
-+	set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot));
-+
-+	page_remove_rmap(page);
-+	if (!page_mapped(page))
-+		try_to_free_swap(page);
-+	put_page(page);
-+	pte_unmap_unlock(ptep, ptl);
-+	err = 0;
-+
-+out:
-+	return err;
-+}
-+
-+/**
-+ * is_bkpt_insn - check if instruction is breakpoint instruction.
-+ * @insn: instruction to be checked.
-+ * Default implementation of is_bkpt_insn
-+ * Returns true if @insn is a breakpoint instruction.
-+ */
-+bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
-+{
-+	return *insn == UPROBES_BKPT_INSN;
-+}
-+
-+/*
-+ * NOTE:
-+ * Expect the breakpoint instruction to be the smallest size instruction for
-+ * the architecture. If an arch has variable length instruction and the
-+ * breakpoint instruction is not of the smallest length instruction
-+ * supported by that architecture then we need to modify read_opcode /
-+ * write_opcode accordingly. This would never be a problem for archs that
-+ * have fixed length instructions.
-+ */
-+
-+/*
-+ * write_opcode - write the opcode at a given virtual address.
-+ * @mm: the probed process address space.
-+ * @uprobe: the breakpointing information.
-+ * @vaddr: the virtual address to store the opcode.
-+ * @opcode: opcode to be written at @vaddr.
-+ *
-+ * Called with mm->mmap_sem held (for read and with a reference to
-+ * mm).
-+ *
-+ * For mm @mm, write the opcode at @vaddr.
-+ * Return 0 (success) or a negative errno.
-+ */
-+static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
-+			unsigned long vaddr, uprobe_opcode_t opcode)
-+{
-+	struct page *old_page, *new_page;
-+	struct address_space *mapping;
-+	void *vaddr_old, *vaddr_new;
-+	struct vm_area_struct *vma;
-+	loff_t addr;
-+	int ret;
-+
-+	/* Read the page with vaddr into memory */
-+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
-+	if (ret <= 0)
-+		return ret;
-+
-+	ret = -EINVAL;
-+
-+	/*
-+	 * We are interested in text pages only. Our pages of interest
-+	 * should be mapped for read and execute only. We desist from
-+	 * adding probes in write mapped pages since the breakpoints
-+	 * might end up in the file copy.
-+	 */
-+	if (!valid_vma(vma, is_bkpt_insn(&opcode)))
-+		goto put_out;
-+
-+	mapping = uprobe->inode->i_mapping;
-+	if (mapping != vma->vm_file->f_mapping)
-+		goto put_out;
-+
-+	addr = vma_address(vma, uprobe->offset);
-+	if (vaddr != (unsigned long)addr)
-+		goto put_out;
-+
-+	ret = -ENOMEM;
-+	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
-+	if (!new_page)
-+		goto put_out;
-+
-+	__SetPageUptodate(new_page);
-+
-+	/*
-+	 * lock page will serialize against do_wp_page()'s
-+	 * PageAnon() handling
-+	 */
-+	lock_page(old_page);
-+	/* copy the page now that we've got it stable */
-+	vaddr_old = kmap_atomic(old_page);
-+	vaddr_new = kmap_atomic(new_page);
-+
-+	memcpy(vaddr_new, vaddr_old, PAGE_SIZE);
-+
-+	/* poke the new insn in, ASSUMES we don't cross page boundary */
-+	vaddr &= ~PAGE_MASK;
-+	BUG_ON(vaddr + uprobe_opcode_sz > PAGE_SIZE);
-+	memcpy(vaddr_new + vaddr, &opcode, uprobe_opcode_sz);
-+
-+	kunmap_atomic(vaddr_new);
-+	kunmap_atomic(vaddr_old);
-+
-+	ret = anon_vma_prepare(vma);
-+	if (ret)
-+		goto unlock_out;
-+
-+	lock_page(new_page);
-+	ret = __replace_page(vma, old_page, new_page);
-+	unlock_page(new_page);
-+
-+unlock_out:
-+	unlock_page(old_page);
-+	page_cache_release(new_page);
-+
-+put_out:
-+	put_page(old_page);
-+
-+	return ret;
-+}
-+
-+/**
-+ * read_opcode - read the opcode at a given virtual address.
-+ * @mm: the probed process address space.
-+ * @vaddr: the virtual address to read the opcode.
-+ * @opcode: location to store the read opcode.
-+ *
-+ * Called with mm->mmap_sem held (for read and with a reference to
-+ * mm.
-+ *
-+ * For mm @mm, read the opcode at @vaddr and store it in @opcode.
-+ * Return 0 (success) or a negative errno.
-+ */
-+static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode)
-+{
-+	struct page *page;
-+	void *vaddr_new;
-+	int ret;
-+
-+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL);
-+	if (ret <= 0)
-+		return ret;
-+
-+	lock_page(page);
-+	vaddr_new = kmap_atomic(page);
-+	vaddr &= ~PAGE_MASK;
-+	memcpy(opcode, vaddr_new + vaddr, uprobe_opcode_sz);
-+	kunmap_atomic(vaddr_new);
-+	unlock_page(page);
-+
-+	put_page(page);
-+
-+	return 0;
-+}
-+
-+static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
-+{
-+	uprobe_opcode_t opcode;
-+	int result;
-+
-+	result = read_opcode(mm, vaddr, &opcode);
-+	if (result)
-+		return result;
-+
-+	if (is_bkpt_insn(&opcode))
-+		return 1;
-+
-+	return 0;
-+}
-+
-+/**
-+ * set_bkpt - store breakpoint at a given address.
-+ * @mm: the probed process address space.
-+ * @uprobe: the probepoint information.
-+ * @vaddr: the virtual address to insert the opcode.
-+ *
-+ * For mm @mm, store the breakpoint instruction at @vaddr.
-+ * Return 0 (success) or a negative errno.
-+ */
-+int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr)
-+{
-+	int result;
-+
-+	result = is_bkpt_at_addr(mm, vaddr);
-+	if (result == 1)
-+		return -EEXIST;
-+
-+	if (result)
-+		return result;
-+
-+	return write_opcode(mm, uprobe, vaddr, UPROBES_BKPT_INSN);
-+}
-+
-+/**
-+ * set_orig_insn - Restore the original instruction.
-+ * @mm: the probed process address space.
-+ * @uprobe: the probepoint information.
-+ * @vaddr: the virtual address to insert the opcode.
-+ * @verify: if true, verify existance of breakpoint instruction.
-+ *
-+ * For mm @mm, restore the original opcode (opcode) at @vaddr.
-+ * Return 0 (success) or a negative errno.
-+ */
-+int __weak
-+set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify)
-+{
-+	if (verify) {
-+		int result;
-+
-+		result = is_bkpt_at_addr(mm, vaddr);
-+		if (!result)
-+			return -EINVAL;
-+
-+		if (result != 1)
-+			return result;
-+	}
-+	return write_opcode(mm, uprobe, vaddr, *(uprobe_opcode_t *)uprobe->insn);
-+}
-+
-+static int match_uprobe(struct uprobe *l, struct uprobe *r)
-+{
-+	if (l->inode < r->inode)
-+		return -1;
-+
-+	if (l->inode > r->inode)
-+		return 1;
-+
-+	if (l->offset < r->offset)
-+		return -1;
-+
-+	if (l->offset > r->offset)
-+		return 1;
-+
-+	return 0;
-+}
-+
-+static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
-+{
-+	struct uprobe u = { .inode = inode, .offset = offset };
-+	struct rb_node *n = uprobes_tree.rb_node;
-+	struct uprobe *uprobe;
-+	int match;
-+
-+	while (n) {
-+		uprobe = rb_entry(n, struct uprobe, rb_node);
-+		match = match_uprobe(&u, uprobe);
-+		if (!match) {
-+			atomic_inc(&uprobe->ref);
-+			return uprobe;
-+		}
-+
-+		if (match < 0)
-+			n = n->rb_left;
-+		else
-+			n = n->rb_right;
-+	}
-+	return NULL;
-+}
-+
-+/*
-+ * Find a uprobe corresponding to a given inode:offset
-+ * Acquires uprobes_treelock
-+ */
-+static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
-+{
-+	struct uprobe *uprobe;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	uprobe = __find_uprobe(inode, offset);
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+
-+	return uprobe;
-+}
-+
-+static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
-+{
-+	struct rb_node **p = &uprobes_tree.rb_node;
-+	struct rb_node *parent = NULL;
-+	struct uprobe *u;
-+	int match;
-+
-+	while (*p) {
-+		parent = *p;
-+		u = rb_entry(parent, struct uprobe, rb_node);
-+		match = match_uprobe(uprobe, u);
-+		if (!match) {
-+			atomic_inc(&u->ref);
-+			return u;
-+		}
-+
-+		if (match < 0)
-+			p = &parent->rb_left;
-+		else
-+			p = &parent->rb_right;
-+
-+	}
-+
-+	u = NULL;
-+	rb_link_node(&uprobe->rb_node, parent, p);
-+	rb_insert_color(&uprobe->rb_node, &uprobes_tree);
-+	/* get access + creation ref */
-+	atomic_set(&uprobe->ref, 2);
-+
-+	return u;
-+}
-+
-+/*
-+ * Acquire uprobes_treelock.
-+ * Matching uprobe already exists in rbtree;
-+ *	increment (access refcount) and return the matching uprobe.
-+ *
-+ * No matching uprobe; insert the uprobe in rb_tree;
-+ *	get a double refcount (access + creation) and return NULL.
-+ */
-+static struct uprobe *insert_uprobe(struct uprobe *uprobe)
-+{
-+	unsigned long flags;
-+	struct uprobe *u;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	u = __insert_uprobe(uprobe);
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+
-+	return u;
-+}
-+
-+static void put_uprobe(struct uprobe *uprobe)
-+{
-+	if (atomic_dec_and_test(&uprobe->ref))
-+		kfree(uprobe);
-+}
-+
-+static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
-+{
-+	struct uprobe *uprobe, *cur_uprobe;
-+
-+	uprobe = kzalloc(sizeof(struct uprobe), GFP_KERNEL);
-+	if (!uprobe)
-+		return NULL;
-+
-+	uprobe->inode = igrab(inode);
-+	uprobe->offset = offset;
-+	init_rwsem(&uprobe->consumer_rwsem);
-+	INIT_LIST_HEAD(&uprobe->pending_list);
-+
-+	/* add to uprobes_tree, sorted on inode:offset */
-+	cur_uprobe = insert_uprobe(uprobe);
-+
-+	/* a uprobe exists for this inode:offset combination */
-+	if (cur_uprobe) {
-+		kfree(uprobe);
-+		uprobe = cur_uprobe;
-+		iput(inode);
-+	} else {
-+		atomic_inc(&uprobe_events);
-+	}
-+
-+	return uprobe;
-+}
-+
-+/* Returns the previous consumer */
-+static struct uprobe_consumer *
-+consumer_add(struct uprobe *uprobe, struct uprobe_consumer *consumer)
-+{
-+	down_write(&uprobe->consumer_rwsem);
-+	consumer->next = uprobe->consumers;
-+	uprobe->consumers = consumer;
-+	up_write(&uprobe->consumer_rwsem);
-+
-+	return consumer->next;
-+}
-+
-+/*
-+ * For uprobe @uprobe, delete the consumer @consumer.
-+ * Return true if the @consumer is deleted successfully
-+ * or return false.
-+ */
-+static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *consumer)
-+{
-+	struct uprobe_consumer **con;
-+	bool ret = false;
-+
-+	down_write(&uprobe->consumer_rwsem);
-+	for (con = &uprobe->consumers; *con; con = &(*con)->next) {
-+		if (*con == consumer) {
-+			*con = consumer->next;
-+			ret = true;
-+			break;
-+		}
-+	}
-+	up_write(&uprobe->consumer_rwsem);
-+
-+	return ret;
-+}
-+
-+static int __copy_insn(struct address_space *mapping,
-+			struct vm_area_struct *vma, char *insn,
-+			unsigned long nbytes, unsigned long offset)
-+{
-+	struct file *filp = vma->vm_file;
-+	struct page *page;
-+	void *vaddr;
-+	unsigned long off1;
-+	unsigned long idx;
-+
-+	if (!filp)
-+		return -EINVAL;
-+
-+	idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT);
-+	off1 = offset &= ~PAGE_MASK;
-+
-+	/*
-+	 * Ensure that the page that has the original instruction is
-+	 * populated and in page-cache.
-+	 */
-+	page = read_mapping_page(mapping, idx, filp);
-+	if (IS_ERR(page))
-+		return PTR_ERR(page);
-+
-+	vaddr = kmap_atomic(page);
-+	memcpy(insn, vaddr + off1, nbytes);
-+	kunmap_atomic(vaddr);
-+	page_cache_release(page);
-+
-+	return 0;
-+}
-+
-+static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
-+{
-+	struct address_space *mapping;
-+	unsigned long nbytes;
-+	int bytes;
-+
-+	addr &= ~PAGE_MASK;
-+	nbytes = PAGE_SIZE - addr;
-+	mapping = uprobe->inode->i_mapping;
-+
-+	/* Instruction at end of binary; copy only available bytes */
-+	if (uprobe->offset + MAX_UINSN_BYTES > uprobe->inode->i_size)
-+		bytes = uprobe->inode->i_size - uprobe->offset;
-+	else
-+		bytes = MAX_UINSN_BYTES;
-+
-+	/* Instruction at the page-boundary; copy bytes in second page */
-+	if (nbytes < bytes) {
-+		if (__copy_insn(mapping, vma, uprobe->insn + nbytes,
-+				bytes - nbytes, uprobe->offset + nbytes))
-+			return -ENOMEM;
-+
-+		bytes = nbytes;
-+	}
-+	return __copy_insn(mapping, vma, uprobe->insn, bytes, uprobe->offset);
-+}
-+
-+static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
-+				struct vm_area_struct *vma, loff_t vaddr)
-+{
-+	unsigned long addr;
-+	int ret;
-+
-+	/*
-+	 * If probe is being deleted, unregister thread could be done with
-+	 * the vma-rmap-walk through. Adding a probe now can be fatal since
-+	 * nobody will be able to cleanup. Also we could be from fork or
-+	 * mremap path, where the probe might have already been inserted.
-+	 * Hence behave as if probe already existed.
-+	 */
-+	if (!uprobe->consumers)
-+		return -EEXIST;
-+
-+	addr = (unsigned long)vaddr;
-+
-+	if (!(uprobe->flags & UPROBES_COPY_INSN)) {
-+		ret = copy_insn(uprobe, vma, addr);
-+		if (ret)
-+			return ret;
-+
-+		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn))
-+			return -EEXIST;
-+
-+		ret = arch_uprobes_analyze_insn(mm, uprobe);
-+		if (ret)
-+			return ret;
-+
-+		uprobe->flags |= UPROBES_COPY_INSN;
-+	}
-+	ret = set_bkpt(mm, uprobe, addr);
-+
-+	return ret;
-+}
-+
-+static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr)
-+{
-+	set_orig_insn(mm, uprobe, (unsigned long)vaddr, true);
-+}
-+
-+static void delete_uprobe(struct uprobe *uprobe)
-+{
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	rb_erase(&uprobe->rb_node, &uprobes_tree);
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+	iput(uprobe->inode);
-+	put_uprobe(uprobe);
-+	atomic_dec(&uprobe_events);
-+}
-+
-+static struct vma_info *__find_next_vma_info(struct list_head *head,
-+			loff_t offset, struct address_space *mapping,
-+			struct vma_info *vi, bool is_register)
-+{
-+	struct prio_tree_iter iter;
-+	struct vm_area_struct *vma;
-+	struct vma_info *tmpvi;
-+	unsigned long pgoff;
-+	int existing_vma;
-+	loff_t vaddr;
-+
-+	pgoff = offset >> PAGE_SHIFT;
-+
-+	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
-+		if (!valid_vma(vma, is_register))
-+			continue;
-+
-+		existing_vma = 0;
-+		vaddr = vma_address(vma, offset);
-+
-+		list_for_each_entry(tmpvi, head, probe_list) {
-+			if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) {
-+				existing_vma = 1;
-+				break;
-+			}
-+		}
-+
-+		/*
-+		 * Another vma needs a probe to be installed. However skip
-+		 * installing the probe if the vma is about to be unlinked.
-+		 */
-+		if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
-+			vi->mm = vma->vm_mm;
-+			vi->vaddr = vaddr;
-+			list_add(&vi->probe_list, head);
-+
-+			return vi;
-+		}
-+	}
-+
-+	return NULL;
-+}
-+
-+/*
-+ * Iterate in the rmap prio tree  and find a vma where a probe has not
-+ * yet been inserted.
-+ */
-+static struct vma_info *
-+find_next_vma_info(struct list_head *head, loff_t offset, struct address_space *mapping,
-+		   bool is_register)
-+{
-+	struct vma_info *vi, *retvi;
-+
-+	vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL);
-+	if (!vi)
-+		return ERR_PTR(-ENOMEM);
-+
-+	mutex_lock(&mapping->i_mmap_mutex);
-+	retvi = __find_next_vma_info(head, offset, mapping, vi, is_register);
-+	mutex_unlock(&mapping->i_mmap_mutex);
-+
-+	if (!retvi)
-+		kfree(vi);
-+
-+	return retvi;
-+}
-+
-+static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
-+{
-+	struct list_head try_list;
-+	struct vm_area_struct *vma;
-+	struct address_space *mapping;
-+	struct vma_info *vi, *tmpvi;
-+	struct mm_struct *mm;
-+	loff_t vaddr;
-+	int ret;
-+
-+	mapping = uprobe->inode->i_mapping;
-+	INIT_LIST_HEAD(&try_list);
-+
-+	ret = 0;
-+
-+	for (;;) {
-+		vi = find_next_vma_info(&try_list, uprobe->offset, mapping, is_register);
-+		if (!vi)
-+			break;
-+
-+		if (IS_ERR(vi)) {
-+			ret = PTR_ERR(vi);
-+			break;
-+		}
-+
-+		mm = vi->mm;
-+		down_read(&mm->mmap_sem);
-+		vma = find_vma(mm, (unsigned long)vi->vaddr);
-+		if (!vma || !valid_vma(vma, is_register)) {
-+			list_del(&vi->probe_list);
-+			kfree(vi);
-+			up_read(&mm->mmap_sem);
-+			mmput(mm);
-+			continue;
-+		}
-+		vaddr = vma_address(vma, uprobe->offset);
-+		if (vma->vm_file->f_mapping->host != uprobe->inode ||
-+						vaddr != vi->vaddr) {
-+			list_del(&vi->probe_list);
-+			kfree(vi);
-+			up_read(&mm->mmap_sem);
-+			mmput(mm);
-+			continue;
-+		}
-+
-+		if (is_register)
-+			ret = install_breakpoint(mm, uprobe, vma, vi->vaddr);
-+		else
-+			remove_breakpoint(mm, uprobe, vi->vaddr);
-+
-+		up_read(&mm->mmap_sem);
-+		mmput(mm);
-+		if (is_register) {
-+			if (ret && ret == -EEXIST)
-+				ret = 0;
-+			if (ret)
-+				break;
-+		}
-+	}
-+
-+	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
-+		list_del(&vi->probe_list);
-+		kfree(vi);
-+	}
-+
-+	return ret;
-+}
-+
-+static int __uprobe_register(struct uprobe *uprobe)
-+{
-+	return register_for_each_vma(uprobe, true);
-+}
-+
-+static void __uprobe_unregister(struct uprobe *uprobe)
-+{
-+	if (!register_for_each_vma(uprobe, false))
-+		delete_uprobe(uprobe);
-+
-+	/* TODO : cant unregister? schedule a worker thread */
-+}
-+
-+/*
-+ * uprobe_register - register a probe
-+ * @inode: the file in which the probe has to be placed.
-+ * @offset: offset from the start of the file.
-+ * @consumer: information on howto handle the probe..
-+ *
-+ * Apart from the access refcount, uprobe_register() takes a creation
-+ * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
-+ * inserted into the rbtree (i.e first consumer for a @inode:@offset
-+ * tuple).  Creation refcount stops uprobe_unregister from freeing the
-+ * @uprobe even before the register operation is complete. Creation
-+ * refcount is released when the last @consumer for the @uprobe
-+ * unregisters.
-+ *
-+ * Return errno if it cannot successully install probes
-+ * else return 0 (success)
-+ */
-+int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
-+{
-+	struct uprobe *uprobe;
-+	int ret;
-+
-+	if (!inode || !consumer || consumer->next)
-+		return -EINVAL;
-+
-+	if (offset > i_size_read(inode))
-+		return -EINVAL;
-+
-+	ret = 0;
-+	mutex_lock(uprobes_hash(inode));
-+	uprobe = alloc_uprobe(inode, offset);
-+
-+	if (uprobe && !consumer_add(uprobe, consumer)) {
-+		ret = __uprobe_register(uprobe);
-+		if (ret) {
-+			uprobe->consumers = NULL;
-+			__uprobe_unregister(uprobe);
-+		} else {
-+			uprobe->flags |= UPROBES_RUN_HANDLER;
-+		}
-+	}
-+
-+	mutex_unlock(uprobes_hash(inode));
-+	put_uprobe(uprobe);
-+
-+	return ret;
-+}
-+
-+/*
-+ * uprobe_unregister - unregister a already registered probe.
-+ * @inode: the file in which the probe has to be removed.
-+ * @offset: offset from the start of the file.
-+ * @consumer: identify which probe if multiple probes are colocated.
-+ */
-+void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
-+{
-+	struct uprobe *uprobe;
-+
-+	if (!inode || !consumer)
-+		return;
-+
-+	uprobe = find_uprobe(inode, offset);
-+	if (!uprobe)
-+		return;
-+
-+	mutex_lock(uprobes_hash(inode));
-+
-+	if (consumer_del(uprobe, consumer)) {
-+		if (!uprobe->consumers) {
-+			__uprobe_unregister(uprobe);
-+			uprobe->flags &= ~UPROBES_RUN_HANDLER;
-+		}
-+	}
-+
-+	mutex_unlock(uprobes_hash(inode));
-+	if (uprobe)
-+		put_uprobe(uprobe);
-+}
-+
-+/*
-+ * Of all the nodes that correspond to the given inode, return the node
-+ * with the least offset.
-+ */
-+static struct rb_node *find_least_offset_node(struct inode *inode)
-+{
-+	struct uprobe u = { .inode = inode, .offset = 0};
-+	struct rb_node *n = uprobes_tree.rb_node;
-+	struct rb_node *close_node = NULL;
-+	struct uprobe *uprobe;
-+	int match;
-+
-+	while (n) {
-+		uprobe = rb_entry(n, struct uprobe, rb_node);
-+		match = match_uprobe(&u, uprobe);
-+
-+		if (uprobe->inode == inode)
-+			close_node = n;
-+
-+		if (!match)
-+			return close_node;
-+
-+		if (match < 0)
-+			n = n->rb_left;
-+		else
-+			n = n->rb_right;
-+	}
-+
-+	return close_node;
-+}
-+
-+/*
-+ * For a given inode, build a list of probes that need to be inserted.
-+ */
-+static void build_probe_list(struct inode *inode, struct list_head *head)
-+{
-+	struct uprobe *uprobe;
-+	unsigned long flags;
-+	struct rb_node *n;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+
-+	n = find_least_offset_node(inode);
-+
-+	for (; n; n = rb_next(n)) {
-+		uprobe = rb_entry(n, struct uprobe, rb_node);
-+		if (uprobe->inode != inode)
-+			break;
-+
-+		list_add(&uprobe->pending_list, head);
-+		atomic_inc(&uprobe->ref);
-+	}
-+
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+}
-+
-+/*
-+ * Called from mmap_region.
-+ * called with mm->mmap_sem acquired.
-+ *
-+ * Return -ve no if we fail to insert probes and we cannot
-+ * bail-out.
-+ * Return 0 otherwise. i.e:
-+ *
-+ *	- successful insertion of probes
-+ *	- (or) no possible probes to be inserted.
-+ *	- (or) insertion of probes failed but we can bail-out.
-+ */
-+int uprobe_mmap(struct vm_area_struct *vma)
-+{
-+	struct list_head tmp_list;
-+	struct uprobe *uprobe, *u;
-+	struct inode *inode;
-+	int ret;
-+
-+	if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
-+		return 0;
-+
-+	inode = vma->vm_file->f_mapping->host;
-+	if (!inode)
-+		return 0;
-+
-+	INIT_LIST_HEAD(&tmp_list);
-+	mutex_lock(uprobes_mmap_hash(inode));
-+	build_probe_list(inode, &tmp_list);
-+
-+	ret = 0;
-+
-+	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
-+		loff_t vaddr;
-+
-+		list_del(&uprobe->pending_list);
-+		if (!ret) {
-+			vaddr = vma_address(vma, uprobe->offset);
-+			if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
-+				ret = install_breakpoint(vma->vm_mm, uprobe, vma, vaddr);
-+				/* Ignore double add: */
-+				if (ret == -EEXIST)
-+					ret = 0;
-+			}
-+		}
-+		put_uprobe(uprobe);
-+	}
-+
-+	mutex_unlock(uprobes_mmap_hash(inode));
-+
-+	return ret;
-+}
-+
-+static int __init init_uprobes(void)
-+{
-+	int i;
-+
-+	for (i = 0; i < UPROBES_HASH_SZ; i++) {
-+		mutex_init(&uprobes_mutex[i]);
-+		mutex_init(&uprobes_mmap_mutex[i]);
-+	}
-+	return 0;
-+}
-+
-+static void __exit exit_uprobes(void)
-+{
-+}
-+
-+module_init(init_uprobes);
-+module_exit(exit_uprobes);
-diff --git a/kernel/uprobes.c b/kernel/uprobes.c
-deleted file mode 100644
-index 884817f..0000000
---- a/kernel/uprobes.c
-+++ /dev/null
-@@ -1,1011 +0,0 @@
--/*
-- * User-space Probes (UProbes)
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License as published by
-- * the Free Software Foundation; either version 2 of the License, or
-- * (at your option) any later version.
-- *
-- * This program is distributed in the hope that 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.
-- *
-- * You should have received a copy of the GNU General Public License
-- * along with this program; if not, write to the Free Software
-- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-- *
-- * Copyright (C) IBM Corporation, 2008-2011
-- * Authors:
-- *	Srikar Dronamraju
-- *	Jim Keniston
-- */
--
--#include <linux/kernel.h>
--#include <linux/highmem.h>
--#include <linux/pagemap.h>	/* read_mapping_page */
--#include <linux/slab.h>
--#include <linux/sched.h>
--#include <linux/rmap.h>		/* anon_vma_prepare */
--#include <linux/mmu_notifier.h>	/* set_pte_at_notify */
--#include <linux/swap.h>		/* try_to_free_swap */
--
--#include <linux/uprobes.h>
--
--static struct rb_root uprobes_tree = RB_ROOT;
--
--static DEFINE_SPINLOCK(uprobes_treelock);	/* serialize rbtree access */
--
--#define UPROBES_HASH_SZ	13
--
--/* serialize (un)register */
--static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
--
--#define uprobes_hash(v)		(&uprobes_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
--
--/* serialize uprobe->pending_list */
--static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
--#define uprobes_mmap_hash(v)	(&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
--
--/*
-- * uprobe_events allows us to skip the uprobe_mmap if there are no uprobe
-- * events active at this time.  Probably a fine grained per inode count is
-- * better?
-- */
--static atomic_t uprobe_events = ATOMIC_INIT(0);
--
--/*
-- * Maintain a temporary per vma info that can be used to search if a vma
-- * has already been handled. This structure is introduced since extending
-- * vm_area_struct wasnt recommended.
-- */
--struct vma_info {
--	struct list_head	probe_list;
--	struct mm_struct	*mm;
--	loff_t			vaddr;
--};
--
--/*
-- * valid_vma: Verify if the specified vma is an executable vma
-- * Relax restrictions while unregistering: vm_flags might have
-- * changed after breakpoint was inserted.
-- *	- is_register: indicates if we are in register context.
-- *	- Return 1 if the specified virtual address is in an
-- *	  executable vma.
-- */
--static bool valid_vma(struct vm_area_struct *vma, bool is_register)
--{
--	if (!vma->vm_file)
--		return false;
--
--	if (!is_register)
--		return true;
--
--	if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC))
--		return true;
--
--	return false;
--}
--
--static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
--{
--	loff_t vaddr;
--
--	vaddr = vma->vm_start + offset;
--	vaddr -= vma->vm_pgoff << PAGE_SHIFT;
--
--	return vaddr;
--}
--
--/**
-- * __replace_page - replace page in vma by new page.
-- * based on replace_page in mm/ksm.c
-- *
-- * @vma:      vma that holds the pte pointing to page
-- * @page:     the cowed page we are replacing by kpage
-- * @kpage:    the modified page we replace page by
-- *
-- * Returns 0 on success, -EFAULT on failure.
-- */
--static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage)
--{
--	struct mm_struct *mm = vma->vm_mm;
--	pgd_t *pgd;
--	pud_t *pud;
--	pmd_t *pmd;
--	pte_t *ptep;
--	spinlock_t *ptl;
--	unsigned long addr;
--	int err = -EFAULT;
--
--	addr = page_address_in_vma(page, vma);
--	if (addr == -EFAULT)
--		goto out;
--
--	pgd = pgd_offset(mm, addr);
--	if (!pgd_present(*pgd))
--		goto out;
--
--	pud = pud_offset(pgd, addr);
--	if (!pud_present(*pud))
--		goto out;
--
--	pmd = pmd_offset(pud, addr);
--	if (!pmd_present(*pmd))
--		goto out;
--
--	ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
--	if (!ptep)
--		goto out;
--
--	get_page(kpage);
--	page_add_new_anon_rmap(kpage, vma, addr);
--
--	flush_cache_page(vma, addr, pte_pfn(*ptep));
--	ptep_clear_flush(vma, addr, ptep);
--	set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot));
--
--	page_remove_rmap(page);
--	if (!page_mapped(page))
--		try_to_free_swap(page);
--	put_page(page);
--	pte_unmap_unlock(ptep, ptl);
--	err = 0;
--
--out:
--	return err;
--}
--
--/**
-- * is_bkpt_insn - check if instruction is breakpoint instruction.
-- * @insn: instruction to be checked.
-- * Default implementation of is_bkpt_insn
-- * Returns true if @insn is a breakpoint instruction.
-- */
--bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
--{
--	return *insn == UPROBES_BKPT_INSN;
--}
--
--/*
-- * NOTE:
-- * Expect the breakpoint instruction to be the smallest size instruction for
-- * the architecture. If an arch has variable length instruction and the
-- * breakpoint instruction is not of the smallest length instruction
-- * supported by that architecture then we need to modify read_opcode /
-- * write_opcode accordingly. This would never be a problem for archs that
-- * have fixed length instructions.
-- */
--
--/*
-- * write_opcode - write the opcode at a given virtual address.
-- * @mm: the probed process address space.
-- * @uprobe: the breakpointing information.
-- * @vaddr: the virtual address to store the opcode.
-- * @opcode: opcode to be written at @vaddr.
-- *
-- * Called with mm->mmap_sem held (for read and with a reference to
-- * mm).
-- *
-- * For mm @mm, write the opcode at @vaddr.
-- * Return 0 (success) or a negative errno.
-- */
--static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
--			unsigned long vaddr, uprobe_opcode_t opcode)
--{
--	struct page *old_page, *new_page;
--	struct address_space *mapping;
--	void *vaddr_old, *vaddr_new;
--	struct vm_area_struct *vma;
--	loff_t addr;
--	int ret;
--
--	/* Read the page with vaddr into memory */
--	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
--	if (ret <= 0)
--		return ret;
--
--	ret = -EINVAL;
--
--	/*
--	 * We are interested in text pages only. Our pages of interest
--	 * should be mapped for read and execute only. We desist from
--	 * adding probes in write mapped pages since the breakpoints
--	 * might end up in the file copy.
--	 */
--	if (!valid_vma(vma, is_bkpt_insn(&opcode)))
--		goto put_out;
--
--	mapping = uprobe->inode->i_mapping;
--	if (mapping != vma->vm_file->f_mapping)
--		goto put_out;
--
--	addr = vma_address(vma, uprobe->offset);
--	if (vaddr != (unsigned long)addr)
--		goto put_out;
--
--	ret = -ENOMEM;
--	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
--	if (!new_page)
--		goto put_out;
--
--	__SetPageUptodate(new_page);
--
--	/*
--	 * lock page will serialize against do_wp_page()'s
--	 * PageAnon() handling
--	 */
--	lock_page(old_page);
--	/* copy the page now that we've got it stable */
--	vaddr_old = kmap_atomic(old_page);
--	vaddr_new = kmap_atomic(new_page);
--
--	memcpy(vaddr_new, vaddr_old, PAGE_SIZE);
--
--	/* poke the new insn in, ASSUMES we don't cross page boundary */
--	vaddr &= ~PAGE_MASK;
--	BUG_ON(vaddr + uprobe_opcode_sz > PAGE_SIZE);
--	memcpy(vaddr_new + vaddr, &opcode, uprobe_opcode_sz);
--
--	kunmap_atomic(vaddr_new);
--	kunmap_atomic(vaddr_old);
--
--	ret = anon_vma_prepare(vma);
--	if (ret)
--		goto unlock_out;
--
--	lock_page(new_page);
--	ret = __replace_page(vma, old_page, new_page);
--	unlock_page(new_page);
--
--unlock_out:
--	unlock_page(old_page);
--	page_cache_release(new_page);
--
--put_out:
--	put_page(old_page);
--
--	return ret;
--}
--
--/**
-- * read_opcode - read the opcode at a given virtual address.
-- * @mm: the probed process address space.
-- * @vaddr: the virtual address to read the opcode.
-- * @opcode: location to store the read opcode.
-- *
-- * Called with mm->mmap_sem held (for read and with a reference to
-- * mm.
-- *
-- * For mm @mm, read the opcode at @vaddr and store it in @opcode.
-- * Return 0 (success) or a negative errno.
-- */
--static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode)
--{
--	struct page *page;
--	void *vaddr_new;
--	int ret;
--
--	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL);
--	if (ret <= 0)
--		return ret;
--
--	lock_page(page);
--	vaddr_new = kmap_atomic(page);
--	vaddr &= ~PAGE_MASK;
--	memcpy(opcode, vaddr_new + vaddr, uprobe_opcode_sz);
--	kunmap_atomic(vaddr_new);
--	unlock_page(page);
--
--	put_page(page);
--
--	return 0;
--}
--
--static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
--{
--	uprobe_opcode_t opcode;
--	int result;
--
--	result = read_opcode(mm, vaddr, &opcode);
--	if (result)
--		return result;
--
--	if (is_bkpt_insn(&opcode))
--		return 1;
--
--	return 0;
--}
--
--/**
-- * set_bkpt - store breakpoint at a given address.
-- * @mm: the probed process address space.
-- * @uprobe: the probepoint information.
-- * @vaddr: the virtual address to insert the opcode.
-- *
-- * For mm @mm, store the breakpoint instruction at @vaddr.
-- * Return 0 (success) or a negative errno.
-- */
--int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr)
--{
--	int result;
--
--	result = is_bkpt_at_addr(mm, vaddr);
--	if (result == 1)
--		return -EEXIST;
--
--	if (result)
--		return result;
--
--	return write_opcode(mm, uprobe, vaddr, UPROBES_BKPT_INSN);
--}
--
--/**
-- * set_orig_insn - Restore the original instruction.
-- * @mm: the probed process address space.
-- * @uprobe: the probepoint information.
-- * @vaddr: the virtual address to insert the opcode.
-- * @verify: if true, verify existance of breakpoint instruction.
-- *
-- * For mm @mm, restore the original opcode (opcode) at @vaddr.
-- * Return 0 (success) or a negative errno.
-- */
--int __weak
--set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify)
--{
--	if (verify) {
--		int result;
--
--		result = is_bkpt_at_addr(mm, vaddr);
--		if (!result)
--			return -EINVAL;
--
--		if (result != 1)
--			return result;
--	}
--	return write_opcode(mm, uprobe, vaddr, *(uprobe_opcode_t *)uprobe->insn);
--}
--
--static int match_uprobe(struct uprobe *l, struct uprobe *r)
--{
--	if (l->inode < r->inode)
--		return -1;
--
--	if (l->inode > r->inode)
--		return 1;
--
--	if (l->offset < r->offset)
--		return -1;
--
--	if (l->offset > r->offset)
--		return 1;
--
--	return 0;
--}
--
--static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
--{
--	struct uprobe u = { .inode = inode, .offset = offset };
--	struct rb_node *n = uprobes_tree.rb_node;
--	struct uprobe *uprobe;
--	int match;
--
--	while (n) {
--		uprobe = rb_entry(n, struct uprobe, rb_node);
--		match = match_uprobe(&u, uprobe);
--		if (!match) {
--			atomic_inc(&uprobe->ref);
--			return uprobe;
--		}
--
--		if (match < 0)
--			n = n->rb_left;
--		else
--			n = n->rb_right;
--	}
--	return NULL;
--}
--
--/*
-- * Find a uprobe corresponding to a given inode:offset
-- * Acquires uprobes_treelock
-- */
--static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
--{
--	struct uprobe *uprobe;
--	unsigned long flags;
--
--	spin_lock_irqsave(&uprobes_treelock, flags);
--	uprobe = __find_uprobe(inode, offset);
--	spin_unlock_irqrestore(&uprobes_treelock, flags);
--
--	return uprobe;
--}
--
--static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
--{
--	struct rb_node **p = &uprobes_tree.rb_node;
--	struct rb_node *parent = NULL;
--	struct uprobe *u;
--	int match;
--
--	while (*p) {
--		parent = *p;
--		u = rb_entry(parent, struct uprobe, rb_node);
--		match = match_uprobe(uprobe, u);
--		if (!match) {
--			atomic_inc(&u->ref);
--			return u;
--		}
--
--		if (match < 0)
--			p = &parent->rb_left;
--		else
--			p = &parent->rb_right;
--
--	}
--
--	u = NULL;
--	rb_link_node(&uprobe->rb_node, parent, p);
--	rb_insert_color(&uprobe->rb_node, &uprobes_tree);
--	/* get access + creation ref */
--	atomic_set(&uprobe->ref, 2);
--
--	return u;
--}
--
--/*
-- * Acquire uprobes_treelock.
-- * Matching uprobe already exists in rbtree;
-- *	increment (access refcount) and return the matching uprobe.
-- *
-- * No matching uprobe; insert the uprobe in rb_tree;
-- *	get a double refcount (access + creation) and return NULL.
-- */
--static struct uprobe *insert_uprobe(struct uprobe *uprobe)
--{
--	unsigned long flags;
--	struct uprobe *u;
--
--	spin_lock_irqsave(&uprobes_treelock, flags);
--	u = __insert_uprobe(uprobe);
--	spin_unlock_irqrestore(&uprobes_treelock, flags);
--
--	return u;
--}
--
--static void put_uprobe(struct uprobe *uprobe)
--{
--	if (atomic_dec_and_test(&uprobe->ref))
--		kfree(uprobe);
--}
--
--static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
--{
--	struct uprobe *uprobe, *cur_uprobe;
--
--	uprobe = kzalloc(sizeof(struct uprobe), GFP_KERNEL);
--	if (!uprobe)
--		return NULL;
--
--	uprobe->inode = igrab(inode);
--	uprobe->offset = offset;
--	init_rwsem(&uprobe->consumer_rwsem);
--	INIT_LIST_HEAD(&uprobe->pending_list);
--
--	/* add to uprobes_tree, sorted on inode:offset */
--	cur_uprobe = insert_uprobe(uprobe);
--
--	/* a uprobe exists for this inode:offset combination */
--	if (cur_uprobe) {
--		kfree(uprobe);
--		uprobe = cur_uprobe;
--		iput(inode);
--	} else {
--		atomic_inc(&uprobe_events);
--	}
--
--	return uprobe;
--}
--
--/* Returns the previous consumer */
--static struct uprobe_consumer *
--consumer_add(struct uprobe *uprobe, struct uprobe_consumer *consumer)
--{
--	down_write(&uprobe->consumer_rwsem);
--	consumer->next = uprobe->consumers;
--	uprobe->consumers = consumer;
--	up_write(&uprobe->consumer_rwsem);
--
--	return consumer->next;
--}
--
--/*
-- * For uprobe @uprobe, delete the consumer @consumer.
-- * Return true if the @consumer is deleted successfully
-- * or return false.
-- */
--static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *consumer)
--{
--	struct uprobe_consumer **con;
--	bool ret = false;
--
--	down_write(&uprobe->consumer_rwsem);
--	for (con = &uprobe->consumers; *con; con = &(*con)->next) {
--		if (*con == consumer) {
--			*con = consumer->next;
--			ret = true;
--			break;
--		}
--	}
--	up_write(&uprobe->consumer_rwsem);
--
--	return ret;
--}
--
--static int __copy_insn(struct address_space *mapping,
--			struct vm_area_struct *vma, char *insn,
--			unsigned long nbytes, unsigned long offset)
--{
--	struct file *filp = vma->vm_file;
--	struct page *page;
--	void *vaddr;
--	unsigned long off1;
--	unsigned long idx;
--
--	if (!filp)
--		return -EINVAL;
--
--	idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT);
--	off1 = offset &= ~PAGE_MASK;
--
--	/*
--	 * Ensure that the page that has the original instruction is
--	 * populated and in page-cache.
--	 */
--	page = read_mapping_page(mapping, idx, filp);
--	if (IS_ERR(page))
--		return PTR_ERR(page);
--
--	vaddr = kmap_atomic(page);
--	memcpy(insn, vaddr + off1, nbytes);
--	kunmap_atomic(vaddr);
--	page_cache_release(page);
--
--	return 0;
--}
--
--static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
--{
--	struct address_space *mapping;
--	unsigned long nbytes;
--	int bytes;
--
--	addr &= ~PAGE_MASK;
--	nbytes = PAGE_SIZE - addr;
--	mapping = uprobe->inode->i_mapping;
--
--	/* Instruction at end of binary; copy only available bytes */
--	if (uprobe->offset + MAX_UINSN_BYTES > uprobe->inode->i_size)
--		bytes = uprobe->inode->i_size - uprobe->offset;
--	else
--		bytes = MAX_UINSN_BYTES;
--
--	/* Instruction at the page-boundary; copy bytes in second page */
--	if (nbytes < bytes) {
--		if (__copy_insn(mapping, vma, uprobe->insn + nbytes,
--				bytes - nbytes, uprobe->offset + nbytes))
--			return -ENOMEM;
--
--		bytes = nbytes;
--	}
--	return __copy_insn(mapping, vma, uprobe->insn, bytes, uprobe->offset);
--}
--
--static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
--				struct vm_area_struct *vma, loff_t vaddr)
--{
--	unsigned long addr;
--	int ret;
--
--	/*
--	 * If probe is being deleted, unregister thread could be done with
--	 * the vma-rmap-walk through. Adding a probe now can be fatal since
--	 * nobody will be able to cleanup. Also we could be from fork or
--	 * mremap path, where the probe might have already been inserted.
--	 * Hence behave as if probe already existed.
--	 */
--	if (!uprobe->consumers)
--		return -EEXIST;
--
--	addr = (unsigned long)vaddr;
--
--	if (!(uprobe->flags & UPROBES_COPY_INSN)) {
--		ret = copy_insn(uprobe, vma, addr);
--		if (ret)
--			return ret;
--
--		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn))
--			return -EEXIST;
--
--		ret = arch_uprobes_analyze_insn(mm, uprobe);
--		if (ret)
--			return ret;
--
--		uprobe->flags |= UPROBES_COPY_INSN;
--	}
--	ret = set_bkpt(mm, uprobe, addr);
--
--	return ret;
--}
--
--static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr)
--{
--	set_orig_insn(mm, uprobe, (unsigned long)vaddr, true);
--}
--
--static void delete_uprobe(struct uprobe *uprobe)
--{
--	unsigned long flags;
--
--	spin_lock_irqsave(&uprobes_treelock, flags);
--	rb_erase(&uprobe->rb_node, &uprobes_tree);
--	spin_unlock_irqrestore(&uprobes_treelock, flags);
--	iput(uprobe->inode);
--	put_uprobe(uprobe);
--	atomic_dec(&uprobe_events);
--}
--
--static struct vma_info *__find_next_vma_info(struct list_head *head,
--			loff_t offset, struct address_space *mapping,
--			struct vma_info *vi, bool is_register)
--{
--	struct prio_tree_iter iter;
--	struct vm_area_struct *vma;
--	struct vma_info *tmpvi;
--	unsigned long pgoff;
--	int existing_vma;
--	loff_t vaddr;
--
--	pgoff = offset >> PAGE_SHIFT;
--
--	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
--		if (!valid_vma(vma, is_register))
--			continue;
--
--		existing_vma = 0;
--		vaddr = vma_address(vma, offset);
--
--		list_for_each_entry(tmpvi, head, probe_list) {
--			if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) {
--				existing_vma = 1;
--				break;
--			}
--		}
--
--		/*
--		 * Another vma needs a probe to be installed. However skip
--		 * installing the probe if the vma is about to be unlinked.
--		 */
--		if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
--			vi->mm = vma->vm_mm;
--			vi->vaddr = vaddr;
--			list_add(&vi->probe_list, head);
--
--			return vi;
--		}
--	}
--
--	return NULL;
--}
--
--/*
-- * Iterate in the rmap prio tree  and find a vma where a probe has not
-- * yet been inserted.
-- */
--static struct vma_info *
--find_next_vma_info(struct list_head *head, loff_t offset, struct address_space *mapping,
--		   bool is_register)
--{
--	struct vma_info *vi, *retvi;
--
--	vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL);
--	if (!vi)
--		return ERR_PTR(-ENOMEM);
--
--	mutex_lock(&mapping->i_mmap_mutex);
--	retvi = __find_next_vma_info(head, offset, mapping, vi, is_register);
--	mutex_unlock(&mapping->i_mmap_mutex);
--
--	if (!retvi)
--		kfree(vi);
--
--	return retvi;
--}
--
--static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
--{
--	struct list_head try_list;
--	struct vm_area_struct *vma;
--	struct address_space *mapping;
--	struct vma_info *vi, *tmpvi;
--	struct mm_struct *mm;
--	loff_t vaddr;
--	int ret;
--
--	mapping = uprobe->inode->i_mapping;
--	INIT_LIST_HEAD(&try_list);
--
--	ret = 0;
--
--	for (;;) {
--		vi = find_next_vma_info(&try_list, uprobe->offset, mapping, is_register);
--		if (!vi)
--			break;
--
--		if (IS_ERR(vi)) {
--			ret = PTR_ERR(vi);
--			break;
--		}
--
--		mm = vi->mm;
--		down_read(&mm->mmap_sem);
--		vma = find_vma(mm, (unsigned long)vi->vaddr);
--		if (!vma || !valid_vma(vma, is_register)) {
--			list_del(&vi->probe_list);
--			kfree(vi);
--			up_read(&mm->mmap_sem);
--			mmput(mm);
--			continue;
--		}
--		vaddr = vma_address(vma, uprobe->offset);
--		if (vma->vm_file->f_mapping->host != uprobe->inode ||
--						vaddr != vi->vaddr) {
--			list_del(&vi->probe_list);
--			kfree(vi);
--			up_read(&mm->mmap_sem);
--			mmput(mm);
--			continue;
--		}
--
--		if (is_register)
--			ret = install_breakpoint(mm, uprobe, vma, vi->vaddr);
--		else
--			remove_breakpoint(mm, uprobe, vi->vaddr);
--
--		up_read(&mm->mmap_sem);
--		mmput(mm);
--		if (is_register) {
--			if (ret && ret == -EEXIST)
--				ret = 0;
--			if (ret)
--				break;
--		}
--	}
--
--	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
--		list_del(&vi->probe_list);
--		kfree(vi);
--	}
--
--	return ret;
--}
--
--static int __uprobe_register(struct uprobe *uprobe)
--{
--	return register_for_each_vma(uprobe, true);
--}
--
--static void __uprobe_unregister(struct uprobe *uprobe)
--{
--	if (!register_for_each_vma(uprobe, false))
--		delete_uprobe(uprobe);
--
--	/* TODO : cant unregister? schedule a worker thread */
--}
--
--/*
-- * uprobe_register - register a probe
-- * @inode: the file in which the probe has to be placed.
-- * @offset: offset from the start of the file.
-- * @consumer: information on howto handle the probe..
-- *
-- * Apart from the access refcount, uprobe_register() takes a creation
-- * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
-- * inserted into the rbtree (i.e first consumer for a @inode:@offset
-- * tuple).  Creation refcount stops uprobe_unregister from freeing the
-- * @uprobe even before the register operation is complete. Creation
-- * refcount is released when the last @consumer for the @uprobe
-- * unregisters.
-- *
-- * Return errno if it cannot successully install probes
-- * else return 0 (success)
-- */
--int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
--{
--	struct uprobe *uprobe;
--	int ret;
--
--	if (!inode || !consumer || consumer->next)
--		return -EINVAL;
--
--	if (offset > i_size_read(inode))
--		return -EINVAL;
--
--	ret = 0;
--	mutex_lock(uprobes_hash(inode));
--	uprobe = alloc_uprobe(inode, offset);
--
--	if (uprobe && !consumer_add(uprobe, consumer)) {
--		ret = __uprobe_register(uprobe);
--		if (ret) {
--			uprobe->consumers = NULL;
--			__uprobe_unregister(uprobe);
--		} else {
--			uprobe->flags |= UPROBES_RUN_HANDLER;
--		}
--	}
--
--	mutex_unlock(uprobes_hash(inode));
--	put_uprobe(uprobe);
--
--	return ret;
--}
--
--/*
-- * uprobe_unregister - unregister a already registered probe.
-- * @inode: the file in which the probe has to be removed.
-- * @offset: offset from the start of the file.
-- * @consumer: identify which probe if multiple probes are colocated.
-- */
--void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
--{
--	struct uprobe *uprobe;
--
--	if (!inode || !consumer)
--		return;
--
--	uprobe = find_uprobe(inode, offset);
--	if (!uprobe)
--		return;
--
--	mutex_lock(uprobes_hash(inode));
--
--	if (consumer_del(uprobe, consumer)) {
--		if (!uprobe->consumers) {
--			__uprobe_unregister(uprobe);
--			uprobe->flags &= ~UPROBES_RUN_HANDLER;
--		}
--	}
--
--	mutex_unlock(uprobes_hash(inode));
--	if (uprobe)
--		put_uprobe(uprobe);
--}
--
--/*
-- * Of all the nodes that correspond to the given inode, return the node
-- * with the least offset.
-- */
--static struct rb_node *find_least_offset_node(struct inode *inode)
--{
--	struct uprobe u = { .inode = inode, .offset = 0};
--	struct rb_node *n = uprobes_tree.rb_node;
--	struct rb_node *close_node = NULL;
--	struct uprobe *uprobe;
--	int match;
--
--	while (n) {
--		uprobe = rb_entry(n, struct uprobe, rb_node);
--		match = match_uprobe(&u, uprobe);
--
--		if (uprobe->inode == inode)
--			close_node = n;
--
--		if (!match)
--			return close_node;
--
--		if (match < 0)
--			n = n->rb_left;
--		else
--			n = n->rb_right;
--	}
--
--	return close_node;
--}
--
--/*
-- * For a given inode, build a list of probes that need to be inserted.
-- */
--static void build_probe_list(struct inode *inode, struct list_head *head)
--{
--	struct uprobe *uprobe;
--	unsigned long flags;
--	struct rb_node *n;
--
--	spin_lock_irqsave(&uprobes_treelock, flags);
--
--	n = find_least_offset_node(inode);
--
--	for (; n; n = rb_next(n)) {
--		uprobe = rb_entry(n, struct uprobe, rb_node);
--		if (uprobe->inode != inode)
--			break;
--
--		list_add(&uprobe->pending_list, head);
--		atomic_inc(&uprobe->ref);
--	}
--
--	spin_unlock_irqrestore(&uprobes_treelock, flags);
--}
--
--/*
-- * Called from mmap_region.
-- * called with mm->mmap_sem acquired.
-- *
-- * Return -ve no if we fail to insert probes and we cannot
-- * bail-out.
-- * Return 0 otherwise. i.e:
-- *
-- *	- successful insertion of probes
-- *	- (or) no possible probes to be inserted.
-- *	- (or) insertion of probes failed but we can bail-out.
-- */
--int uprobe_mmap(struct vm_area_struct *vma)
--{
--	struct list_head tmp_list;
--	struct uprobe *uprobe, *u;
--	struct inode *inode;
--	int ret;
--
--	if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
--		return 0;
--
--	inode = vma->vm_file->f_mapping->host;
--	if (!inode)
--		return 0;
--
--	INIT_LIST_HEAD(&tmp_list);
--	mutex_lock(uprobes_mmap_hash(inode));
--	build_probe_list(inode, &tmp_list);
--
--	ret = 0;
--
--	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
--		loff_t vaddr;
--
--		list_del(&uprobe->pending_list);
--		if (!ret) {
--			vaddr = vma_address(vma, uprobe->offset);
--			if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
--				ret = install_breakpoint(vma->vm_mm, uprobe, vma, vaddr);
--				/* Ignore double add: */
--				if (ret == -EEXIST)
--					ret = 0;
--			}
--		}
--		put_uprobe(uprobe);
--	}
--
--	mutex_unlock(uprobes_mmap_hash(inode));
--
--	return ret;
--}
--
--static int __init init_uprobes(void)
--{
--	int i;
--
--	for (i = 0; i < UPROBES_HASH_SZ; i++) {
--		mutex_init(&uprobes_mutex[i]);
--		mutex_init(&uprobes_mmap_mutex[i]);
--	}
--	return 0;
--}
--
--static void __exit exit_uprobes(void)
--{
--}
--
--module_init(init_uprobes);
--module_exit(exit_uprobes);
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-Update-copyright-notices.patch b/features/uprobe/uprobes-Update-copyright-notices.patch
deleted file mode 100644
index 046b94def26a9200865d6be79694de752da75981..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-Update-copyright-notices.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-From c4247f2d15fa6250ae4397687807396ff1246955 Mon Sep 17 00:00:00 2001
-From: Ingo Molnar <mingo@elte.hu>
-Date: Wed, 22 Feb 2012 11:37:29 +0100
-Subject: [PATCH 07/24] uprobes: Update copyright notices
-
-Add Peter Zijlstra's copyright to the uprobes code, whose
-contributions to the uprobes code are not visible in the Git
-history, because they were backmerged.
-
-Also update existing copyright notices to the year 2012.
-
-commit 35aa621b5ab9d08767f7bc8d209b696df281d715 upstream
-
-Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Link: http://lkml.kernel.org/n/tip-vjqxst502pc1efz7ah8cyht4@git.kernel.org
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/uprobes.h |    3 ++-
- kernel/events/uprobes.c |    3 ++-
- 2 files changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index 9c6be62..f85797e 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -17,10 +17,11 @@
-  * along with this program; if not, write to the Free Software
-  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-  *
-- * Copyright (C) IBM Corporation, 2008-2011
-+ * Copyright (C) IBM Corporation, 2008-2012
-  * Authors:
-  *	Srikar Dronamraju
-  *	Jim Keniston
-+ * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
-  */
- 
- #include <linux/errno.h>
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 13f1b59..5ce32e3 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -15,10 +15,11 @@
-  * along with this program; if not, write to the Free Software
-  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-  *
-- * Copyright (C) IBM Corporation, 2008-2011
-+ * Copyright (C) IBM Corporation, 2008-2012
-  * Authors:
-  *	Srikar Dronamraju
-  *	Jim Keniston
-+ * Copyright (C) 2011-2012 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
-  */
- 
- #include <linux/kernel.h>
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Allocate-XOL-slots-for-uprobes-use.patch b/features/uprobe/uprobes-core-Allocate-XOL-slots-for-uprobes-use.patch
deleted file mode 100644
index 41a6da421ed8380fecb00c1c804d41d679bb1adb..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Allocate-XOL-slots-for-uprobes-use.patch
+++ /dev/null
@@ -1,414 +0,0 @@
-From 20f3d76f4cb4bca02796181c4eedb2406fd1c2b7 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Fri, 30 Mar 2012 23:56:31 +0530
-Subject: [PATCH 12/24] uprobes/core: Allocate XOL slots for uprobes use
-
-Uprobes executes the original instruction at a probed location
-out of line. For this, we allocate a page (per mm) upon the
-first uprobe hit, in the process user address space, divide it
-into slots that are used to store the actual instructions to be
-singlestepped. These slots are known as xol (execution out of
-line) slots.
-
-Care is taken to ensure that the allocation is in an unmapped
-area as close to the top of the user address space as possible,
-with appropriate permission settings to keep selinux like
-frameworks happy.
-
-Upon a uprobe hit, a free slot is acquired, and is released
-after the singlestep completes.
-
-Lots of improvements courtesy suggestions/inputs from Peter and
-Oleg.
-
-[ Folded a fix for build issue on powerpc fixed and reported by
-  Stephen Rothwell. ]
-
-commit d4b3b6384f98f8692ad0209891ccdbc7e78bbefe upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120330182631.10018.48175.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/mm_types.h |    2 +
- include/linux/uprobes.h  |   34 +++++++
- kernel/events/uprobes.c  |  215 ++++++++++++++++++++++++++++++++++++++++++++++
- kernel/fork.c            |    2 +
- 4 files changed, 253 insertions(+), 0 deletions(-)
-
-diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
-index b35752f..f773215 100644
---- a/include/linux/mm_types.h
-+++ b/include/linux/mm_types.h
-@@ -12,6 +12,7 @@
- #include <linux/completion.h>
- #include <linux/cpumask.h>
- #include <linux/page-debug-flags.h>
-+#include <linux/uprobes.h>
- #include <asm/page.h>
- #include <asm/mmu.h>
- 
-@@ -398,6 +399,7 @@ struct mm_struct {
- #ifdef CONFIG_CPUMASK_OFFSTACK
- 	struct cpumask cpumask_allocation;
- #endif
-+	struct uprobes_state uprobes_state;
- };
- 
- static inline void mm_init_cpumask(struct mm_struct *mm)
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index 5ec778f..a111460 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -28,6 +28,8 @@
- #include <linux/rbtree.h>
- 
- struct vm_area_struct;
-+struct mm_struct;
-+struct inode;
- 
- #ifdef CONFIG_ARCH_SUPPORTS_UPROBES
- # include <asm/uprobes.h>
-@@ -76,6 +78,28 @@ struct uprobe_task {
- 	unsigned long			vaddr;
- };
- 
-+/*
-+ * On a breakpoint hit, thread contests for a slot.  It frees the
-+ * slot after singlestep. Currently a fixed number of slots are
-+ * allocated.
-+ */
-+struct xol_area {
-+	wait_queue_head_t 	wq;		/* if all slots are busy */
-+	atomic_t 		slot_count;	/* number of in-use slots */
-+	unsigned long 		*bitmap;	/* 0 = free slot */
-+	struct page 		*page;
-+
-+	/*
-+	 * We keep the vma's vm_start rather than a pointer to the vma
-+	 * itself.  The probed process or a naughty kernel module could make
-+	 * the vma go away, and we must handle that reasonably gracefully.
-+	 */
-+	unsigned long 		vaddr;		/* Page(s) of instruction slots */
-+};
-+
-+struct uprobes_state {
-+	struct xol_area		*xol_area;
-+};
- extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
- extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm,  unsigned long vaddr, bool verify);
- extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
-@@ -90,7 +114,11 @@ extern int uprobe_pre_sstep_notifier(struct pt_regs *regs);
- extern void uprobe_notify_resume(struct pt_regs *regs);
- extern bool uprobe_deny_signal(void);
- extern bool __weak arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs);
-+extern void uprobe_clear_state(struct mm_struct *mm);
-+extern void uprobe_reset_state(struct mm_struct *mm);
- #else /* !CONFIG_UPROBES */
-+struct uprobes_state {
-+};
- static inline int
- uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
- {
-@@ -121,5 +149,11 @@ static inline void uprobe_free_utask(struct task_struct *t)
- static inline void uprobe_copy_process(struct task_struct *t)
- {
- }
-+static inline void uprobe_clear_state(struct mm_struct *mm)
-+{
-+}
-+static inline void uprobe_reset_state(struct mm_struct *mm)
-+{
-+}
- #endif /* !CONFIG_UPROBES */
- #endif	/* _LINUX_UPROBES_H */
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index b807d15..b395edb 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -35,6 +35,9 @@
- 
- #include <linux/uprobes.h>
- 
-+#define UINSNS_PER_PAGE			(PAGE_SIZE/UPROBE_XOL_SLOT_BYTES)
-+#define MAX_UPROBE_XOL_SLOTS		UINSNS_PER_PAGE
-+
- static struct srcu_struct uprobes_srcu;
- static struct rb_root uprobes_tree = RB_ROOT;
- 
-@@ -1042,6 +1045,213 @@ int uprobe_mmap(struct vm_area_struct *vma)
- 	return ret;
- }
- 
-+/* Slot allocation for XOL */
-+static int xol_add_vma(struct xol_area *area)
-+{
-+	struct mm_struct *mm;
-+	int ret;
-+
-+	area->page = alloc_page(GFP_HIGHUSER);
-+	if (!area->page)
-+		return -ENOMEM;
-+
-+	ret = -EALREADY;
-+	mm = current->mm;
-+
-+	down_write(&mm->mmap_sem);
-+	if (mm->uprobes_state.xol_area)
-+		goto fail;
-+
-+	ret = -ENOMEM;
-+
-+	/* Try to map as high as possible, this is only a hint. */
-+	area->vaddr = get_unmapped_area(NULL, TASK_SIZE - PAGE_SIZE, PAGE_SIZE, 0, 0);
-+	if (area->vaddr & ~PAGE_MASK) {
-+		ret = area->vaddr;
-+		goto fail;
-+	}
-+
-+	ret = install_special_mapping(mm, area->vaddr, PAGE_SIZE,
-+				VM_EXEC|VM_MAYEXEC|VM_DONTCOPY|VM_IO, &area->page);
-+	if (ret)
-+		goto fail;
-+
-+	smp_wmb();	/* pairs with get_xol_area() */
-+	mm->uprobes_state.xol_area = area;
-+	ret = 0;
-+
-+fail:
-+	up_write(&mm->mmap_sem);
-+	if (ret)
-+		__free_page(area->page);
-+
-+	return ret;
-+}
-+
-+static struct xol_area *get_xol_area(struct mm_struct *mm)
-+{
-+	struct xol_area *area;
-+
-+	area = mm->uprobes_state.xol_area;
-+	smp_read_barrier_depends();	/* pairs with wmb in xol_add_vma() */
-+
-+	return area;
-+}
-+
-+/*
-+ * xol_alloc_area - Allocate process's xol_area.
-+ * This area will be used for storing instructions for execution out of
-+ * line.
-+ *
-+ * Returns the allocated area or NULL.
-+ */
-+static struct xol_area *xol_alloc_area(void)
-+{
-+	struct xol_area *area;
-+
-+	area = kzalloc(sizeof(*area), GFP_KERNEL);
-+	if (unlikely(!area))
-+		return NULL;
-+
-+	area->bitmap = kzalloc(BITS_TO_LONGS(UINSNS_PER_PAGE) * sizeof(long), GFP_KERNEL);
-+
-+	if (!area->bitmap)
-+		goto fail;
-+
-+	init_waitqueue_head(&area->wq);
-+	if (!xol_add_vma(area))
-+		return area;
-+
-+fail:
-+	kfree(area->bitmap);
-+	kfree(area);
-+
-+	return get_xol_area(current->mm);
-+}
-+
-+/*
-+ * uprobe_clear_state - Free the area allocated for slots.
-+ */
-+void uprobe_clear_state(struct mm_struct *mm)
-+{
-+	struct xol_area *area = mm->uprobes_state.xol_area;
-+
-+	if (!area)
-+		return;
-+
-+	put_page(area->page);
-+	kfree(area->bitmap);
-+	kfree(area);
-+}
-+
-+/*
-+ * uprobe_reset_state - Free the area allocated for slots.
-+ */
-+void uprobe_reset_state(struct mm_struct *mm)
-+{
-+	mm->uprobes_state.xol_area = NULL;
-+}
-+
-+/*
-+ *  - search for a free slot.
-+ */
-+static unsigned long xol_take_insn_slot(struct xol_area *area)
-+{
-+	unsigned long slot_addr;
-+	int slot_nr;
-+
-+	do {
-+		slot_nr = find_first_zero_bit(area->bitmap, UINSNS_PER_PAGE);
-+		if (slot_nr < UINSNS_PER_PAGE) {
-+			if (!test_and_set_bit(slot_nr, area->bitmap))
-+				break;
-+
-+			slot_nr = UINSNS_PER_PAGE;
-+			continue;
-+		}
-+		wait_event(area->wq, (atomic_read(&area->slot_count) < UINSNS_PER_PAGE));
-+	} while (slot_nr >= UINSNS_PER_PAGE);
-+
-+	slot_addr = area->vaddr + (slot_nr * UPROBE_XOL_SLOT_BYTES);
-+	atomic_inc(&area->slot_count);
-+
-+	return slot_addr;
-+}
-+
-+/*
-+ * xol_get_insn_slot - If was not allocated a slot, then
-+ * allocate a slot.
-+ * Returns the allocated slot address or 0.
-+ */
-+static unsigned long xol_get_insn_slot(struct uprobe *uprobe, unsigned long slot_addr)
-+{
-+	struct xol_area *area;
-+	unsigned long offset;
-+	void *vaddr;
-+
-+	area = get_xol_area(current->mm);
-+	if (!area) {
-+		area = xol_alloc_area();
-+		if (!area)
-+			return 0;
-+	}
-+	current->utask->xol_vaddr = xol_take_insn_slot(area);
-+
-+	/*
-+	 * Initialize the slot if xol_vaddr points to valid
-+	 * instruction slot.
-+	 */
-+	if (unlikely(!current->utask->xol_vaddr))
-+		return 0;
-+
-+	current->utask->vaddr = slot_addr;
-+	offset = current->utask->xol_vaddr & ~PAGE_MASK;
-+	vaddr = kmap_atomic(area->page);
-+	memcpy(vaddr + offset, uprobe->arch.insn, MAX_UINSN_BYTES);
-+	kunmap_atomic(vaddr);
-+
-+	return current->utask->xol_vaddr;
-+}
-+
-+/*
-+ * xol_free_insn_slot - If slot was earlier allocated by
-+ * @xol_get_insn_slot(), make the slot available for
-+ * subsequent requests.
-+ */
-+static void xol_free_insn_slot(struct task_struct *tsk)
-+{
-+	struct xol_area *area;
-+	unsigned long vma_end;
-+	unsigned long slot_addr;
-+
-+	if (!tsk->mm || !tsk->mm->uprobes_state.xol_area || !tsk->utask)
-+		return;
-+
-+	slot_addr = tsk->utask->xol_vaddr;
-+
-+	if (unlikely(!slot_addr || IS_ERR_VALUE(slot_addr)))
-+		return;
-+
-+	area = tsk->mm->uprobes_state.xol_area;
-+	vma_end = area->vaddr + PAGE_SIZE;
-+	if (area->vaddr <= slot_addr && slot_addr < vma_end) {
-+		unsigned long offset;
-+		int slot_nr;
-+
-+		offset = slot_addr - area->vaddr;
-+		slot_nr = offset / UPROBE_XOL_SLOT_BYTES;
-+		if (slot_nr >= UINSNS_PER_PAGE)
-+			return;
-+
-+		clear_bit(slot_nr, area->bitmap);
-+		atomic_dec(&area->slot_count);
-+		if (waitqueue_active(&area->wq))
-+			wake_up(&area->wq);
-+
-+		tsk->utask->xol_vaddr = 0;
-+	}
-+}
-+
- /**
-  * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
-  * @regs: Reflects the saved state of the task after it has hit a breakpoint
-@@ -1070,6 +1280,7 @@ void uprobe_free_utask(struct task_struct *t)
- 	if (utask->active_uprobe)
- 		put_uprobe(utask->active_uprobe);
- 
-+	xol_free_insn_slot(t);
- 	kfree(utask);
- 	t->utask = NULL;
- }
-@@ -1108,6 +1319,9 @@ static struct uprobe_task *add_utask(void)
- static int
- pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long vaddr)
- {
-+	if (xol_get_insn_slot(uprobe, vaddr) && !arch_uprobe_pre_xol(&uprobe->arch, regs))
-+		return 0;
-+
- 	return -EFAULT;
- }
- 
-@@ -1252,6 +1466,7 @@ static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
- 	utask->active_uprobe = NULL;
- 	utask->state = UTASK_RUNNING;
- 	user_disable_single_step(current);
-+	xol_free_insn_slot(current);
- 
- 	spin_lock_irq(&current->sighand->siglock);
- 	recalc_sigpending(); /* see uprobe_deny_signal() */
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 5be9230..5fa2cbf 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -574,6 +574,7 @@ void mmput(struct mm_struct *mm)
- 	might_sleep();
- 
- 	if (atomic_dec_and_test(&mm->mm_users)) {
-+		uprobe_clear_state(mm);
- 		exit_aio(mm);
- 		ksm_exit(mm);
- 		khugepaged_exit(mm); /* must run before exit_mmap */
-@@ -808,6 +809,7 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
- #ifdef CONFIG_TRANSPARENT_HUGEPAGE
- 	mm->pmd_huge_pte = NULL;
- #endif
-+	uprobe_reset_state(mm);
- 
- 	if (!mm_init(mm, tsk))
- 		goto fail_nomem;
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Clean-up-refactor-and-improve-the-code.patch b/features/uprobe/uprobes-core-Clean-up-refactor-and-improve-the-code.patch
deleted file mode 100644
index 7ef73ef9849576faed7edebd9cab6631a0488af2..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Clean-up-refactor-and-improve-the-code.patch
+++ /dev/null
@@ -1,1159 +0,0 @@
-From 0a7ad1cefe170125c2ee7cb04a03410848c4a48a Mon Sep 17 00:00:00 2001
-From: Ingo Molnar <mingo@elte.hu>
-Date: Fri, 17 Feb 2012 09:27:41 +0100
-Subject: [PATCH 02/24] uprobes/core: Clean up, refactor and improve the code
-
-Make the uprobes code readable to me:
-
- - improve the Kconfig text so that a mere mortal gets some idea
-   what CONFIG_UPROBES=y is really about
-
- - do trivial renames to standardize around the uprobes_*() namespace
-
- - clean up and simplify various code flow details
-
- - separate basic blocks of functionality
-
- - line break artifact and white space related removal
-
- - use standard local varible definition blocks
-
- - use vertical spacing to make things more readable
-
- - remove unnecessary volatile
-
- - restructure comment blocks to make them more uniform and
-   more readable in general
-
-commit 7b2d81d48a2d8e37efb6ce7b4d5ef58822b30d89 upstream
-
-Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Jim Keniston <jkenisto@us.ibm.com>
-Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Link: http://lkml.kernel.org/n/tip-ewbwhb8o6navvllsauu7k07p@git.kernel.org
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/Kconfig                   |   14 ++-
- arch/x86/include/asm/uprobes.h |   17 ++--
- arch/x86/kernel/uprobes.c      |  129 ++++++++++++-----------
- include/linux/uprobes.h        |   28 +++---
- kernel/uprobes.c               |  219 +++++++++++++++++++++++-----------------
- mm/mmap.c                      |   12 +-
- 6 files changed, 233 insertions(+), 186 deletions(-)
-
-diff --git a/arch/Kconfig b/arch/Kconfig
-index 5083bf2..b78bf33 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -77,13 +77,19 @@ config OPTPROBES
- 	depends on !PREEMPT
- 
- config UPROBES
--	bool "User-space probes (EXPERIMENTAL)"
-+	bool "Transparent user-space probes (EXPERIMENTAL)"
- 	depends on ARCH_SUPPORTS_UPROBES
- 	default n
- 	help
--	  Uprobes enables kernel subsystems to establish probepoints
--	  in user applications and execute handler functions when
--	  the probepoints are hit.
-+	  Uprobes is the user-space counterpart to kprobes: they
-+	  enable instrumentation applications (such as 'perf probe')
-+	  to establish unintrusive probes in user-space binaries and
-+	  libraries, by executing handler functions when the probes
-+	  are hit by user-space applications.
-+
-+	  ( These probes come in the form of single-byte breakpoints,
-+	    managed by the kernel and kept transparent to the probed
-+	    application. )
- 
- 	  If in doubt, say "N".
- 
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index 8208234..072df39 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -1,7 +1,7 @@
- #ifndef _ASM_UPROBES_H
- #define _ASM_UPROBES_H
- /*
-- * Userspace Probes (UProbes) for x86
-+ * User-space Probes (UProbes) for x86
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -24,19 +24,20 @@
-  */
- 
- typedef u8 uprobe_opcode_t;
--#define MAX_UINSN_BYTES 16
--#define UPROBES_XOL_SLOT_BYTES	128	/* to keep it cache aligned */
- 
--#define UPROBES_BKPT_INSN 0xcc
--#define UPROBES_BKPT_INSN_SIZE 1
-+#define MAX_UINSN_BYTES			  16
-+#define UPROBES_XOL_SLOT_BYTES		 128	/* to keep it cache aligned */
-+
-+#define UPROBES_BKPT_INSN		0xcc
-+#define UPROBES_BKPT_INSN_SIZE		   1
- 
- struct uprobe_arch_info {
--	u16			fixups;
-+	u16				fixups;
- #ifdef CONFIG_X86_64
--	unsigned long rip_rela_target_address;
-+	unsigned long			rip_rela_target_address;
- #endif
- };
- 
- struct uprobe;
--extern int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe);
-+extern int arch_uprobes_analyze_insn(struct mm_struct *mm, struct uprobe *uprobe);
- #endif	/* _ASM_UPROBES_H */
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index 2a301bb..cf2a184 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -1,5 +1,5 @@
- /*
-- * Userspace Probes (UProbes) for x86
-+ * User-space Probes (UProbes) for x86
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -20,7 +20,6 @@
-  *	Srikar Dronamraju
-  *	Jim Keniston
-  */
--
- #include <linux/kernel.h>
- #include <linux/sched.h>
- #include <linux/ptrace.h>
-@@ -42,10 +41,10 @@
- #define UPROBES_FIX_RIP_CX	0x4000
- 
- /* Adaptations for mhiramat x86 decoder v14. */
--#define OPCODE1(insn) ((insn)->opcode.bytes[0])
--#define OPCODE2(insn) ((insn)->opcode.bytes[1])
--#define OPCODE3(insn) ((insn)->opcode.bytes[2])
--#define MODRM_REG(insn) X86_MODRM_REG(insn->modrm.value)
-+#define OPCODE1(insn)		((insn)->opcode.bytes[0])
-+#define OPCODE2(insn)		((insn)->opcode.bytes[1])
-+#define OPCODE3(insn)		((insn)->opcode.bytes[2])
-+#define MODRM_REG(insn)		X86_MODRM_REG(insn->modrm.value)
- 
- #define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
- 	(((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) |   \
-@@ -55,7 +54,7 @@
- 	 << (row % 32))
- 
- #ifdef CONFIG_X86_64
--static volatile u32 good_insns_64[256 / 32] = {
-+static u32 good_insns_64[256 / 32] = {
- 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
- 	/*      ----------------------------------------------         */
- 	W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */
-@@ -81,7 +80,7 @@ static volatile u32 good_insns_64[256 / 32] = {
- 
- /* Good-instruction tables for 32-bit apps */
- 
--static volatile u32 good_insns_32[256 / 32] = {
-+static u32 good_insns_32[256 / 32] = {
- 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
- 	/*      ----------------------------------------------         */
- 	W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 00 */
-@@ -105,7 +104,7 @@ static volatile u32 good_insns_32[256 / 32] = {
- };
- 
- /* Using this for both 64-bit and 32-bit apps */
--static volatile u32 good_2byte_insns[256 / 32] = {
-+static u32 good_2byte_insns[256 / 32] = {
- 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
- 	/*      ----------------------------------------------         */
- 	W(0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) | /* 00 */
-@@ -132,42 +131,47 @@ static volatile u32 good_2byte_insns[256 / 32] = {
- 
- /*
-  * opcodes we'll probably never support:
-- * 6c-6d, e4-e5, ec-ed - in
-- * 6e-6f, e6-e7, ee-ef - out
-- * cc, cd - int3, int
-- * cf - iret
-- * d6 - illegal instruction
-- * f1 - int1/icebp
-- * f4 - hlt
-- * fa, fb - cli, sti
-- * 0f - lar, lsl, syscall, clts, sysret, sysenter, sysexit, invd, wbinvd, ud2
-+ *
-+ *  6c-6d, e4-e5, ec-ed - in
-+ *  6e-6f, e6-e7, ee-ef - out
-+ *  cc, cd - int3, int
-+ *  cf - iret
-+ *  d6 - illegal instruction
-+ *  f1 - int1/icebp
-+ *  f4 - hlt
-+ *  fa, fb - cli, sti
-+ *  0f - lar, lsl, syscall, clts, sysret, sysenter, sysexit, invd, wbinvd, ud2
-  *
-  * invalid opcodes in 64-bit mode:
-- * 06, 0e, 16, 1e, 27, 2f, 37, 3f, 60-62, 82, c4-c5, d4-d5
-  *
-- * 63 - we support this opcode in x86_64 but not in i386.
-+ *  06, 0e, 16, 1e, 27, 2f, 37, 3f, 60-62, 82, c4-c5, d4-d5
-+ *  63 - we support this opcode in x86_64 but not in i386.
-  *
-  * opcodes we may need to refine support for:
-- * 0f - 2-byte instructions: For many of these instructions, the validity
-- * depends on the prefix and/or the reg field.  On such instructions, we
-- * just consider the opcode combination valid if it corresponds to any
-- * valid instruction.
-- * 8f - Group 1 - only reg = 0 is OK
-- * c6-c7 - Group 11 - only reg = 0 is OK
-- * d9-df - fpu insns with some illegal encodings
-- * f2, f3 - repnz, repz prefixes.  These are also the first byte for
-- * certain floating-point instructions, such as addsd.
-- * fe - Group 4 - only reg = 0 or 1 is OK
-- * ff - Group 5 - only reg = 0-6 is OK
-+ *
-+ *  0f - 2-byte instructions: For many of these instructions, the validity
-+ *  depends on the prefix and/or the reg field.  On such instructions, we
-+ *  just consider the opcode combination valid if it corresponds to any
-+ *  valid instruction.
-+ *
-+ *  8f - Group 1 - only reg = 0 is OK
-+ *  c6-c7 - Group 11 - only reg = 0 is OK
-+ *  d9-df - fpu insns with some illegal encodings
-+ *  f2, f3 - repnz, repz prefixes.  These are also the first byte for
-+ *  certain floating-point instructions, such as addsd.
-+ *
-+ *  fe - Group 4 - only reg = 0 or 1 is OK
-+ *  ff - Group 5 - only reg = 0-6 is OK
-  *
-  * others -- Do we need to support these?
-- * 0f - (floating-point?) prefetch instructions
-- * 07, 17, 1f - pop es, pop ss, pop ds
-- * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes --
-+ *
-+ *  0f - (floating-point?) prefetch instructions
-+ *  07, 17, 1f - pop es, pop ss, pop ds
-+ *  26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes --
-  *	but 64 and 65 (fs: and gs:) seem to be used, so we support them
-- * 67 - addr16 prefix
-- * ce - into
-- * f0 - lock prefix
-+ *  67 - addr16 prefix
-+ *  ce - into
-+ *  f0 - lock prefix
-  */
- 
- /*
-@@ -182,11 +186,11 @@ static bool is_prefix_bad(struct insn *insn)
- 
- 	for (i = 0; i < insn->prefixes.nbytes; i++) {
- 		switch (insn->prefixes.bytes[i]) {
--		case 0x26:	/*INAT_PFX_ES   */
--		case 0x2E:	/*INAT_PFX_CS   */
--		case 0x36:	/*INAT_PFX_DS   */
--		case 0x3E:	/*INAT_PFX_SS   */
--		case 0xF0:	/*INAT_PFX_LOCK */
-+		case 0x26:	/* INAT_PFX_ES   */
-+		case 0x2E:	/* INAT_PFX_CS   */
-+		case 0x36:	/* INAT_PFX_DS   */
-+		case 0x3E:	/* INAT_PFX_SS   */
-+		case 0xF0:	/* INAT_PFX_LOCK */
- 			return true;
- 		}
- 	}
-@@ -201,12 +205,15 @@ static int validate_insn_32bits(struct uprobe *uprobe, struct insn *insn)
- 	insn_get_opcode(insn);
- 	if (is_prefix_bad(insn))
- 		return -ENOTSUPP;
-+
- 	if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_32))
- 		return 0;
-+
- 	if (insn->opcode.nbytes == 2) {
- 		if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
- 			return 0;
- 	}
-+
- 	return -ENOTSUPP;
- }
- 
-@@ -282,12 +289,12 @@ static void prepare_fixups(struct uprobe *uprobe, struct insn *insn)
-  * disastrous.
-  *
-  * Some useful facts about rip-relative instructions:
-- * - There's always a modrm byte.
-- * - There's never a SIB byte.
-- * - The displacement is always 4 bytes.
-+ *
-+ *  - There's always a modrm byte.
-+ *  - There's never a SIB byte.
-+ *  - The displacement is always 4 bytes.
-  */
--static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
--							struct insn *insn)
-+static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
- {
- 	u8 *cursor;
- 	u8 reg;
-@@ -342,13 +349,12 @@ static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
- 	}
- 
- 	/* Target address = address of next instruction + (signed) offset */
--	uprobe->arch_info.rip_rela_target_address = (long)insn->length
--					+ insn->displacement.value;
-+	uprobe->arch_info.rip_rela_target_address = (long)insn->length + insn->displacement.value;
-+
- 	/* Displacement field is gone; slide immediate field (if any) over. */
- 	if (insn->immediate.nbytes) {
- 		cursor++;
--		memmove(cursor, cursor + insn->displacement.nbytes,
--						insn->immediate.nbytes);
-+		memmove(cursor, cursor + insn->displacement.nbytes, insn->immediate.nbytes);
- 	}
- 	return;
- }
-@@ -361,8 +367,10 @@ static int validate_insn_64bits(struct uprobe *uprobe, struct insn *insn)
- 	insn_get_opcode(insn);
- 	if (is_prefix_bad(insn))
- 		return -ENOTSUPP;
-+
- 	if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_64))
- 		return 0;
-+
- 	if (insn->opcode.nbytes == 2) {
- 		if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
- 			return 0;
-@@ -370,34 +378,31 @@ static int validate_insn_64bits(struct uprobe *uprobe, struct insn *insn)
- 	return -ENOTSUPP;
- }
- 
--static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe,
--				struct insn *insn)
-+static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
- {
- 	if (mm->context.ia32_compat)
- 		return validate_insn_32bits(uprobe, insn);
- 	return validate_insn_64bits(uprobe, insn);
- }
--#else
--static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
--							struct insn *insn)
-+#else /* 32-bit: */
-+static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
- {
--	return;
-+	/* No RIP-relative addressing on 32-bit */
- }
- 
--static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe,
--				struct insn *insn)
-+static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
- {
- 	return validate_insn_32bits(uprobe, insn);
- }
- #endif /* CONFIG_X86_64 */
- 
- /**
-- * analyze_insn - instruction analysis including validity and fixups.
-+ * arch_uprobes_analyze_insn - instruction analysis including validity and fixups.
-  * @mm: the probed address space.
-  * @uprobe: the probepoint information.
-  * Return 0 on success or a -ve number on error.
-  */
--int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe)
-+int arch_uprobes_analyze_insn(struct mm_struct *mm, struct uprobe *uprobe)
- {
- 	int ret;
- 	struct insn insn;
-@@ -406,7 +411,9 @@ int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe)
- 	ret = validate_insn_bits(mm, uprobe, &insn);
- 	if (ret != 0)
- 		return ret;
-+
- 	handle_riprel_insn(mm, uprobe, &insn);
- 	prepare_fixups(uprobe, &insn);
-+
- 	return 0;
- }
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index f1d13fd..64e45f1 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -1,7 +1,7 @@
- #ifndef _LINUX_UPROBES_H
- #define _LINUX_UPROBES_H
- /*
-- * Userspace Probes (UProbes)
-+ * User-space Probes (UProbes)
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -40,8 +40,10 @@ struct uprobe_arch_info {};
- #define uprobe_opcode_sz sizeof(uprobe_opcode_t)
- 
- /* flags that denote/change uprobes behaviour */
-+
- /* Have a copy of original instruction */
- #define UPROBES_COPY_INSN	0x1
-+
- /* Dont run handlers when first register/ last unregister in progress*/
- #define UPROBES_RUN_HANDLER	0x2
- 
-@@ -70,27 +72,23 @@ struct uprobe {
- };
- 
- #ifdef CONFIG_UPROBES
--extern int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
--							unsigned long vaddr);
--extern int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe,
--					unsigned long vaddr, bool verify);
-+extern int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr);
-+extern int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify);
- extern bool __weak is_bkpt_insn(uprobe_opcode_t *insn);
--extern int register_uprobe(struct inode *inode, loff_t offset,
--				struct uprobe_consumer *consumer);
--extern void unregister_uprobe(struct inode *inode, loff_t offset,
--				struct uprobe_consumer *consumer);
--extern int mmap_uprobe(struct vm_area_struct *vma);
-+extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer);
-+extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer);
-+extern int uprobe_mmap(struct vm_area_struct *vma);
- #else /* CONFIG_UPROBES is not defined */
--static inline int register_uprobe(struct inode *inode, loff_t offset,
--				struct uprobe_consumer *consumer)
-+static inline int
-+uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
- {
- 	return -ENOSYS;
- }
--static inline void unregister_uprobe(struct inode *inode, loff_t offset,
--				struct uprobe_consumer *consumer)
-+static inline void
-+uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
- {
- }
--static inline int mmap_uprobe(struct vm_area_struct *vma)
-+static inline int uprobe_mmap(struct vm_area_struct *vma)
- {
- 	return 0;
- }
-diff --git a/kernel/uprobes.c b/kernel/uprobes.c
-index 72e8bb3..884817f 100644
---- a/kernel/uprobes.c
-+++ b/kernel/uprobes.c
-@@ -1,5 +1,5 @@
- /*
-- * Userspace Probes (UProbes)
-+ * User-space Probes (UProbes)
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -29,24 +29,26 @@
- #include <linux/rmap.h>		/* anon_vma_prepare */
- #include <linux/mmu_notifier.h>	/* set_pte_at_notify */
- #include <linux/swap.h>		/* try_to_free_swap */
-+
- #include <linux/uprobes.h>
- 
- static struct rb_root uprobes_tree = RB_ROOT;
-+
- static DEFINE_SPINLOCK(uprobes_treelock);	/* serialize rbtree access */
- 
- #define UPROBES_HASH_SZ	13
-+
- /* serialize (un)register */
- static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
--#define uprobes_hash(v)	(&uprobes_mutex[((unsigned long)(v)) %\
--						UPROBES_HASH_SZ])
-+
-+#define uprobes_hash(v)		(&uprobes_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
- 
- /* serialize uprobe->pending_list */
- static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
--#define uprobes_mmap_hash(v)	(&uprobes_mmap_mutex[((unsigned long)(v)) %\
--						UPROBES_HASH_SZ])
-+#define uprobes_mmap_hash(v)	(&uprobes_mmap_mutex[((unsigned long)(v)) % UPROBES_HASH_SZ])
- 
- /*
-- * uprobe_events allows us to skip the mmap_uprobe if there are no uprobe
-+ * uprobe_events allows us to skip the uprobe_mmap if there are no uprobe
-  * events active at this time.  Probably a fine grained per inode count is
-  * better?
-  */
-@@ -58,9 +60,9 @@ static atomic_t uprobe_events = ATOMIC_INIT(0);
-  * vm_area_struct wasnt recommended.
-  */
- struct vma_info {
--	struct list_head probe_list;
--	struct mm_struct *mm;
--	loff_t vaddr;
-+	struct list_head	probe_list;
-+	struct mm_struct	*mm;
-+	loff_t			vaddr;
- };
- 
- /*
-@@ -79,8 +81,7 @@ static bool valid_vma(struct vm_area_struct *vma, bool is_register)
- 	if (!is_register)
- 		return true;
- 
--	if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) ==
--						(VM_READ|VM_EXEC))
-+	if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) == (VM_READ|VM_EXEC))
- 		return true;
- 
- 	return false;
-@@ -92,6 +93,7 @@ static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
- 
- 	vaddr = vma->vm_start + offset;
- 	vaddr -= vma->vm_pgoff << PAGE_SHIFT;
-+
- 	return vaddr;
- }
- 
-@@ -105,8 +107,7 @@ static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
-  *
-  * Returns 0 on success, -EFAULT on failure.
-  */
--static int __replace_page(struct vm_area_struct *vma, struct page *page,
--					struct page *kpage)
-+static int __replace_page(struct vm_area_struct *vma, struct page *page, struct page *kpage)
- {
- 	struct mm_struct *mm = vma->vm_mm;
- 	pgd_t *pgd;
-@@ -163,7 +164,7 @@ out:
-  */
- bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
- {
--	return (*insn == UPROBES_BKPT_INSN);
-+	return *insn == UPROBES_BKPT_INSN;
- }
- 
- /*
-@@ -203,6 +204,7 @@ static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
- 	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
- 	if (ret <= 0)
- 		return ret;
-+
- 	ret = -EINVAL;
- 
- 	/*
-@@ -239,6 +241,7 @@ static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
- 	vaddr_new = kmap_atomic(new_page);
- 
- 	memcpy(vaddr_new, vaddr_old, PAGE_SIZE);
-+
- 	/* poke the new insn in, ASSUMES we don't cross page boundary */
- 	vaddr &= ~PAGE_MASK;
- 	BUG_ON(vaddr + uprobe_opcode_sz > PAGE_SIZE);
-@@ -260,7 +263,8 @@ unlock_out:
- 	page_cache_release(new_page);
- 
- put_out:
--	put_page(old_page);	/* we did a get_page in the beginning */
-+	put_page(old_page);
-+
- 	return ret;
- }
- 
-@@ -276,8 +280,7 @@ put_out:
-  * For mm @mm, read the opcode at @vaddr and store it in @opcode.
-  * Return 0 (success) or a negative errno.
-  */
--static int read_opcode(struct mm_struct *mm, unsigned long vaddr,
--						uprobe_opcode_t *opcode)
-+static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_t *opcode)
- {
- 	struct page *page;
- 	void *vaddr_new;
-@@ -293,15 +296,18 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr,
- 	memcpy(opcode, vaddr_new + vaddr, uprobe_opcode_sz);
- 	kunmap_atomic(vaddr_new);
- 	unlock_page(page);
--	put_page(page);		/* we did a get_user_pages in the beginning */
-+
-+	put_page(page);
-+
- 	return 0;
- }
- 
- static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
- {
- 	uprobe_opcode_t opcode;
--	int result = read_opcode(mm, vaddr, &opcode);
-+	int result;
- 
-+	result = read_opcode(mm, vaddr, &opcode);
- 	if (result)
- 		return result;
- 
-@@ -320,11 +326,11 @@ static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
-  * For mm @mm, store the breakpoint instruction at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
--						unsigned long vaddr)
-+int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr)
- {
--	int result = is_bkpt_at_addr(mm, vaddr);
-+	int result;
- 
-+	result = is_bkpt_at_addr(mm, vaddr);
- 	if (result == 1)
- 		return -EEXIST;
- 
-@@ -344,35 +350,35 @@ int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
-  * For mm @mm, restore the original opcode (opcode) at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe,
--					unsigned long vaddr, bool verify)
-+int __weak
-+set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify)
- {
- 	if (verify) {
--		int result = is_bkpt_at_addr(mm, vaddr);
-+		int result;
- 
-+		result = is_bkpt_at_addr(mm, vaddr);
- 		if (!result)
- 			return -EINVAL;
- 
- 		if (result != 1)
- 			return result;
- 	}
--	return write_opcode(mm, uprobe, vaddr,
--				*(uprobe_opcode_t *)uprobe->insn);
-+	return write_opcode(mm, uprobe, vaddr, *(uprobe_opcode_t *)uprobe->insn);
- }
- 
- static int match_uprobe(struct uprobe *l, struct uprobe *r)
- {
- 	if (l->inode < r->inode)
- 		return -1;
-+
- 	if (l->inode > r->inode)
- 		return 1;
--	else {
--		if (l->offset < r->offset)
--			return -1;
- 
--		if (l->offset > r->offset)
--			return 1;
--	}
-+	if (l->offset < r->offset)
-+		return -1;
-+
-+	if (l->offset > r->offset)
-+		return 1;
- 
- 	return 0;
- }
-@@ -391,6 +397,7 @@ static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
- 			atomic_inc(&uprobe->ref);
- 			return uprobe;
- 		}
-+
- 		if (match < 0)
- 			n = n->rb_left;
- 		else
-@@ -411,6 +418,7 @@ static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
- 	spin_lock_irqsave(&uprobes_treelock, flags);
- 	uprobe = __find_uprobe(inode, offset);
- 	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+
- 	return uprobe;
- }
- 
-@@ -436,16 +444,18 @@ static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
- 			p = &parent->rb_right;
- 
- 	}
-+
- 	u = NULL;
- 	rb_link_node(&uprobe->rb_node, parent, p);
- 	rb_insert_color(&uprobe->rb_node, &uprobes_tree);
- 	/* get access + creation ref */
- 	atomic_set(&uprobe->ref, 2);
-+
- 	return u;
- }
- 
- /*
-- * Acquires uprobes_treelock.
-+ * Acquire uprobes_treelock.
-  * Matching uprobe already exists in rbtree;
-  *	increment (access refcount) and return the matching uprobe.
-  *
-@@ -460,6 +470,7 @@ static struct uprobe *insert_uprobe(struct uprobe *uprobe)
- 	spin_lock_irqsave(&uprobes_treelock, flags);
- 	u = __insert_uprobe(uprobe);
- 	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+
- 	return u;
- }
- 
-@@ -490,19 +501,22 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
- 		kfree(uprobe);
- 		uprobe = cur_uprobe;
- 		iput(inode);
--	} else
-+	} else {
- 		atomic_inc(&uprobe_events);
-+	}
-+
- 	return uprobe;
- }
- 
- /* Returns the previous consumer */
--static struct uprobe_consumer *add_consumer(struct uprobe *uprobe,
--				struct uprobe_consumer *consumer)
-+static struct uprobe_consumer *
-+consumer_add(struct uprobe *uprobe, struct uprobe_consumer *consumer)
- {
- 	down_write(&uprobe->consumer_rwsem);
- 	consumer->next = uprobe->consumers;
- 	uprobe->consumers = consumer;
- 	up_write(&uprobe->consumer_rwsem);
-+
- 	return consumer->next;
- }
- 
-@@ -511,8 +525,7 @@ static struct uprobe_consumer *add_consumer(struct uprobe *uprobe,
-  * Return true if the @consumer is deleted successfully
-  * or return false.
-  */
--static bool del_consumer(struct uprobe *uprobe,
--				struct uprobe_consumer *consumer)
-+static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *consumer)
- {
- 	struct uprobe_consumer **con;
- 	bool ret = false;
-@@ -526,6 +539,7 @@ static bool del_consumer(struct uprobe *uprobe,
- 		}
- 	}
- 	up_write(&uprobe->consumer_rwsem);
-+
- 	return ret;
- }
- 
-@@ -557,15 +571,15 @@ static int __copy_insn(struct address_space *mapping,
- 	memcpy(insn, vaddr + off1, nbytes);
- 	kunmap_atomic(vaddr);
- 	page_cache_release(page);
-+
- 	return 0;
- }
- 
--static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma,
--					unsigned long addr)
-+static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
- {
- 	struct address_space *mapping;
--	int bytes;
- 	unsigned long nbytes;
-+	int bytes;
- 
- 	addr &= ~PAGE_MASK;
- 	nbytes = PAGE_SIZE - addr;
-@@ -605,6 +619,7 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 		return -EEXIST;
- 
- 	addr = (unsigned long)vaddr;
-+
- 	if (!(uprobe->flags & UPROBES_COPY_INSN)) {
- 		ret = copy_insn(uprobe, vma, addr);
- 		if (ret)
-@@ -613,7 +628,7 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn))
- 			return -EEXIST;
- 
--		ret = analyze_insn(mm, uprobe);
-+		ret = arch_uprobes_analyze_insn(mm, uprobe);
- 		if (ret)
- 			return ret;
- 
-@@ -624,8 +639,7 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 	return ret;
- }
- 
--static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
--							loff_t vaddr)
-+static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr)
- {
- 	set_orig_insn(mm, uprobe, (unsigned long)vaddr, true);
- }
-@@ -649,9 +663,11 @@ static struct vma_info *__find_next_vma_info(struct list_head *head,
- 	struct prio_tree_iter iter;
- 	struct vm_area_struct *vma;
- 	struct vma_info *tmpvi;
--	loff_t vaddr;
--	unsigned long pgoff = offset >> PAGE_SHIFT;
-+	unsigned long pgoff;
- 	int existing_vma;
-+	loff_t vaddr;
-+
-+	pgoff = offset >> PAGE_SHIFT;
- 
- 	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
- 		if (!valid_vma(vma, is_register))
-@@ -659,6 +675,7 @@ static struct vma_info *__find_next_vma_info(struct list_head *head,
- 
- 		existing_vma = 0;
- 		vaddr = vma_address(vma, offset);
-+
- 		list_for_each_entry(tmpvi, head, probe_list) {
- 			if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) {
- 				existing_vma = 1;
-@@ -670,14 +687,15 @@ static struct vma_info *__find_next_vma_info(struct list_head *head,
- 		 * Another vma needs a probe to be installed. However skip
- 		 * installing the probe if the vma is about to be unlinked.
- 		 */
--		if (!existing_vma &&
--				atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
-+		if (!existing_vma && atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
- 			vi->mm = vma->vm_mm;
- 			vi->vaddr = vaddr;
- 			list_add(&vi->probe_list, head);
-+
- 			return vi;
- 		}
- 	}
-+
- 	return NULL;
- }
- 
-@@ -685,11 +703,12 @@ static struct vma_info *__find_next_vma_info(struct list_head *head,
-  * Iterate in the rmap prio tree  and find a vma where a probe has not
-  * yet been inserted.
-  */
--static struct vma_info *find_next_vma_info(struct list_head *head,
--			loff_t offset, struct address_space *mapping,
--			bool is_register)
-+static struct vma_info *
-+find_next_vma_info(struct list_head *head, loff_t offset, struct address_space *mapping,
-+		   bool is_register)
- {
- 	struct vma_info *vi, *retvi;
-+
- 	vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL);
- 	if (!vi)
- 		return ERR_PTR(-ENOMEM);
-@@ -700,6 +719,7 @@ static struct vma_info *find_next_vma_info(struct list_head *head,
- 
- 	if (!retvi)
- 		kfree(vi);
-+
- 	return retvi;
- }
- 
-@@ -711,16 +731,23 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
- 	struct vma_info *vi, *tmpvi;
- 	struct mm_struct *mm;
- 	loff_t vaddr;
--	int ret = 0;
-+	int ret;
- 
- 	mapping = uprobe->inode->i_mapping;
- 	INIT_LIST_HEAD(&try_list);
--	while ((vi = find_next_vma_info(&try_list, uprobe->offset,
--					mapping, is_register)) != NULL) {
-+
-+	ret = 0;
-+
-+	for (;;) {
-+		vi = find_next_vma_info(&try_list, uprobe->offset, mapping, is_register);
-+		if (!vi)
-+			break;
-+
- 		if (IS_ERR(vi)) {
- 			ret = PTR_ERR(vi);
- 			break;
- 		}
-+
- 		mm = vi->mm;
- 		down_read(&mm->mmap_sem);
- 		vma = find_vma(mm, (unsigned long)vi->vaddr);
-@@ -755,19 +782,21 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
- 				break;
- 		}
- 	}
-+
- 	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
- 		list_del(&vi->probe_list);
- 		kfree(vi);
- 	}
-+
- 	return ret;
- }
- 
--static int __register_uprobe(struct uprobe *uprobe)
-+static int __uprobe_register(struct uprobe *uprobe)
- {
- 	return register_for_each_vma(uprobe, true);
- }
- 
--static void __unregister_uprobe(struct uprobe *uprobe)
-+static void __uprobe_unregister(struct uprobe *uprobe)
- {
- 	if (!register_for_each_vma(uprobe, false))
- 		delete_uprobe(uprobe);
-@@ -776,15 +805,15 @@ static void __unregister_uprobe(struct uprobe *uprobe)
- }
- 
- /*
-- * register_uprobe - register a probe
-+ * uprobe_register - register a probe
-  * @inode: the file in which the probe has to be placed.
-  * @offset: offset from the start of the file.
-  * @consumer: information on howto handle the probe..
-  *
-- * Apart from the access refcount, register_uprobe() takes a creation
-+ * Apart from the access refcount, uprobe_register() takes a creation
-  * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
-  * inserted into the rbtree (i.e first consumer for a @inode:@offset
-- * tuple).  Creation refcount stops unregister_uprobe from freeing the
-+ * tuple).  Creation refcount stops uprobe_unregister from freeing the
-  * @uprobe even before the register operation is complete. Creation
-  * refcount is released when the last @consumer for the @uprobe
-  * unregisters.
-@@ -792,28 +821,29 @@ static void __unregister_uprobe(struct uprobe *uprobe)
-  * Return errno if it cannot successully install probes
-  * else return 0 (success)
-  */
--int register_uprobe(struct inode *inode, loff_t offset,
--				struct uprobe_consumer *consumer)
-+int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
- {
- 	struct uprobe *uprobe;
--	int ret = -EINVAL;
-+	int ret;
- 
- 	if (!inode || !consumer || consumer->next)
--		return ret;
-+		return -EINVAL;
- 
- 	if (offset > i_size_read(inode))
--		return ret;
-+		return -EINVAL;
- 
- 	ret = 0;
- 	mutex_lock(uprobes_hash(inode));
- 	uprobe = alloc_uprobe(inode, offset);
--	if (uprobe && !add_consumer(uprobe, consumer)) {
--		ret = __register_uprobe(uprobe);
-+
-+	if (uprobe && !consumer_add(uprobe, consumer)) {
-+		ret = __uprobe_register(uprobe);
- 		if (ret) {
- 			uprobe->consumers = NULL;
--			__unregister_uprobe(uprobe);
--		} else
-+			__uprobe_unregister(uprobe);
-+		} else {
- 			uprobe->flags |= UPROBES_RUN_HANDLER;
-+		}
- 	}
- 
- 	mutex_unlock(uprobes_hash(inode));
-@@ -823,15 +853,14 @@ int register_uprobe(struct inode *inode, loff_t offset,
- }
- 
- /*
-- * unregister_uprobe - unregister a already registered probe.
-+ * uprobe_unregister - unregister a already registered probe.
-  * @inode: the file in which the probe has to be removed.
-  * @offset: offset from the start of the file.
-  * @consumer: identify which probe if multiple probes are colocated.
-  */
--void unregister_uprobe(struct inode *inode, loff_t offset,
--				struct uprobe_consumer *consumer)
-+void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
- {
--	struct uprobe *uprobe = NULL;
-+	struct uprobe *uprobe;
- 
- 	if (!inode || !consumer)
- 		return;
-@@ -841,15 +870,14 @@ void unregister_uprobe(struct inode *inode, loff_t offset,
- 		return;
- 
- 	mutex_lock(uprobes_hash(inode));
--	if (!del_consumer(uprobe, consumer))
--		goto unreg_out;
- 
--	if (!uprobe->consumers) {
--		__unregister_uprobe(uprobe);
--		uprobe->flags &= ~UPROBES_RUN_HANDLER;
-+	if (consumer_del(uprobe, consumer)) {
-+		if (!uprobe->consumers) {
-+			__uprobe_unregister(uprobe);
-+			uprobe->flags &= ~UPROBES_RUN_HANDLER;
-+		}
- 	}
- 
--unreg_out:
- 	mutex_unlock(uprobes_hash(inode));
- 	if (uprobe)
- 		put_uprobe(uprobe);
-@@ -870,6 +898,7 @@ static struct rb_node *find_least_offset_node(struct inode *inode)
- 	while (n) {
- 		uprobe = rb_entry(n, struct uprobe, rb_node);
- 		match = match_uprobe(&u, uprobe);
-+
- 		if (uprobe->inode == inode)
- 			close_node = n;
- 
-@@ -881,6 +910,7 @@ static struct rb_node *find_least_offset_node(struct inode *inode)
- 		else
- 			n = n->rb_right;
- 	}
-+
- 	return close_node;
- }
- 
-@@ -890,11 +920,13 @@ static struct rb_node *find_least_offset_node(struct inode *inode)
- static void build_probe_list(struct inode *inode, struct list_head *head)
- {
- 	struct uprobe *uprobe;
--	struct rb_node *n;
- 	unsigned long flags;
-+	struct rb_node *n;
- 
- 	spin_lock_irqsave(&uprobes_treelock, flags);
-+
- 	n = find_least_offset_node(inode);
-+
- 	for (; n; n = rb_next(n)) {
- 		uprobe = rb_entry(n, struct uprobe, rb_node);
- 		if (uprobe->inode != inode)
-@@ -903,6 +935,7 @@ static void build_probe_list(struct inode *inode, struct list_head *head)
- 		list_add(&uprobe->pending_list, head);
- 		atomic_inc(&uprobe->ref);
- 	}
-+
- 	spin_unlock_irqrestore(&uprobes_treelock, flags);
- }
- 
-@@ -912,42 +945,44 @@ static void build_probe_list(struct inode *inode, struct list_head *head)
-  *
-  * Return -ve no if we fail to insert probes and we cannot
-  * bail-out.
-- * Return 0 otherwise. i.e :
-+ * Return 0 otherwise. i.e:
-+ *
-  *	- successful insertion of probes
-  *	- (or) no possible probes to be inserted.
-  *	- (or) insertion of probes failed but we can bail-out.
-  */
--int mmap_uprobe(struct vm_area_struct *vma)
-+int uprobe_mmap(struct vm_area_struct *vma)
- {
- 	struct list_head tmp_list;
- 	struct uprobe *uprobe, *u;
- 	struct inode *inode;
--	int ret = 0;
-+	int ret;
- 
- 	if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
--		return ret;	/* Bail-out */
-+		return 0;
- 
- 	inode = vma->vm_file->f_mapping->host;
- 	if (!inode)
--		return ret;
-+		return 0;
- 
- 	INIT_LIST_HEAD(&tmp_list);
- 	mutex_lock(uprobes_mmap_hash(inode));
- 	build_probe_list(inode, &tmp_list);
-+
-+	ret = 0;
-+
- 	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
- 		loff_t vaddr;
- 
- 		list_del(&uprobe->pending_list);
- 		if (!ret) {
- 			vaddr = vma_address(vma, uprobe->offset);
--			if (vaddr < vma->vm_start || vaddr >= vma->vm_end) {
--				put_uprobe(uprobe);
--				continue;
-+			if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
-+				ret = install_breakpoint(vma->vm_mm, uprobe, vma, vaddr);
-+				/* Ignore double add: */
-+				if (ret == -EEXIST)
-+					ret = 0;
- 			}
--			ret = install_breakpoint(vma->vm_mm, uprobe, vma,
--								vaddr);
--			if (ret == -EEXIST)
--				ret = 0;
- 		}
- 		put_uprobe(uprobe);
- 	}
-diff --git a/mm/mmap.c b/mm/mmap.c
-index f6ea842..397bcb5 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -619,10 +619,10 @@ again:			remove_next = 1 + (end > next->vm_end);
- 		mutex_unlock(&mapping->i_mmap_mutex);
- 
- 	if (root) {
--		mmap_uprobe(vma);
-+		uprobe_mmap(vma);
- 
- 		if (adjust_next)
--			mmap_uprobe(next);
-+			uprobe_mmap(next);
- 	}
- 
- 	if (remove_next) {
-@@ -647,7 +647,7 @@ again:			remove_next = 1 + (end > next->vm_end);
- 		}
- 	}
- 	if (insert && file)
--		mmap_uprobe(insert);
-+		uprobe_mmap(insert);
- 
- 	validate_mm(mm);
- 
-@@ -1382,7 +1382,7 @@ out:
- 	} else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
- 		make_pages_present(addr, addr + len);
- 
--	if (file && mmap_uprobe(vma))
-+	if (file && uprobe_mmap(vma))
- 		/* matching probes but cannot insert */
- 		goto unmap_and_free_vma;
- 
-@@ -2368,7 +2368,7 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
- 	     security_vm_enough_memory_mm(mm, vma_pages(vma)))
- 		return -ENOMEM;
- 
--	if (vma->vm_file && mmap_uprobe(vma))
-+	if (vma->vm_file && uprobe_mmap(vma))
- 		return -EINVAL;
- 
- 	vma_link(mm, vma, prev, rb_link, rb_parent);
-@@ -2441,7 +2441,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
- 			if (new_vma->vm_file) {
- 				get_file(new_vma->vm_file);
- 
--				if (mmap_uprobe(new_vma))
-+				if (uprobe_mmap(new_vma))
- 					goto out_free_mempol;
- 
- 				if (vma->vm_flags & VM_EXECUTABLE)
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Decrement-uprobe-count-before-the-pages.patch b/features/uprobe/uprobes-core-Decrement-uprobe-count-before-the-pages.patch
deleted file mode 100644
index 64e5242fe81d533e93547fc5c5d289646bd02d6d..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Decrement-uprobe-count-before-the-pages.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From a8600f2e9c62613ca4073a25be14c50039f50ad7 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Wed, 11 Apr 2012 16:05:27 +0530
-Subject: [PATCH 15/24] uprobes/core: Decrement uprobe count before the pages
- are unmapped
-
-Uprobes has a callback (uprobe_munmap()) in the unmap path to
-maintain the uprobes count.
-
-In the exit path this callback gets called in unlink_file_vma().
-However by the time unlink_file_vma() is called, the pages would
-have been unmapped (in unmap_vmas()) and the task->rss_stat counts
-accounted (in zap_pte_range()).
-
-If the exiting process has probepoints, uprobe_munmap() checks if
-the breakpoint instruction was around before decrementing the probe
-count.
-
-This results in a file backed page being reread by uprobe_munmap()
-and hence it does not find the breakpoint.
-
-This patch fixes this problem by moving the callback to
-unmap_single_vma(). Since unmap_single_vma() may not unmap the
-complete vma, add start and end parameters to uprobe_munmap().
-
-This bug became apparent courtesy of commit c3f0327f8e9d
-("mm: add rss counters consistency check").
-
-commit cbc91f71b51b8335f1fc7ccfca8011f31a717367 upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120411103527.23245.9835.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/uprobes.h |    5 +++--
- kernel/events/uprobes.c |    4 ++--
- mm/memory.c             |    3 +++
- mm/mmap.c               |    8 ++++----
- 4 files changed, 12 insertions(+), 8 deletions(-)
-
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index d594d3b..efe4b33 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -107,7 +107,7 @@ extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
- extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern int uprobe_mmap(struct vm_area_struct *vma);
--extern void uprobe_munmap(struct vm_area_struct *vma);
-+extern void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end);
- extern void uprobe_free_utask(struct task_struct *t);
- extern void uprobe_copy_process(struct task_struct *t);
- extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
-@@ -134,7 +134,8 @@ static inline int uprobe_mmap(struct vm_area_struct *vma)
- {
- 	return 0;
- }
--static inline void uprobe_munmap(struct vm_area_struct *vma)
-+static inline void
-+uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
- {
- }
- static inline void uprobe_notify_resume(struct pt_regs *regs)
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index c5caeec..985be4d 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -1112,7 +1112,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
- /*
-  * Called in context of a munmap of a vma.
-  */
--void uprobe_munmap(struct vm_area_struct *vma)
-+void uprobe_munmap(struct vm_area_struct *vma, unsigned long start, unsigned long end)
- {
- 	struct list_head tmp_list;
- 	struct uprobe *uprobe, *u;
-@@ -1138,7 +1138,7 @@ void uprobe_munmap(struct vm_area_struct *vma)
- 		list_del(&uprobe->pending_list);
- 		vaddr = vma_address(vma, uprobe->offset);
- 
--		if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
-+		if (vaddr >= start && vaddr < end) {
- 			/*
- 			 * An unregister could have removed the probe before
- 			 * unmap. So check before we decrement the count.
-diff --git a/mm/memory.c b/mm/memory.c
-index 6105f47..bf8b403 100644
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -1307,6 +1307,9 @@ static void unmap_single_vma(struct mmu_gather *tlb,
- 	if (end <= vma->vm_start)
- 		return;
- 
-+	if (vma->vm_file)
-+		uprobe_munmap(vma, start, end);
-+
- 	if (vma->vm_flags & VM_ACCOUNT)
- 		*nr_accounted += (end - start) >> PAGE_SHIFT;
- 
-diff --git a/mm/mmap.c b/mm/mmap.c
-index b0b1691..b8c4072 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -218,7 +218,6 @@ void unlink_file_vma(struct vm_area_struct *vma)
- 		mutex_lock(&mapping->i_mmap_mutex);
- 		__remove_shared_vm_struct(vma, file, mapping);
- 		mutex_unlock(&mapping->i_mmap_mutex);
--		uprobe_munmap(vma);
- 	}
- }
- 
-@@ -550,10 +549,11 @@ again:			remove_next = 1 + (end > next->vm_end);
- 		mapping = file->f_mapping;
- 		if (!(vma->vm_flags & VM_NONLINEAR)) {
- 			root = &mapping->i_mmap;
--			uprobe_munmap(vma);
-+			uprobe_munmap(vma, vma->vm_start, vma->vm_end);
- 
- 			if (adjust_next)
--				uprobe_munmap(next);
-+				uprobe_munmap(next, next->vm_start,
-+							next->vm_end);
- 		}
- 
- 		mutex_lock(&mapping->i_mmap_mutex);
-@@ -634,7 +634,7 @@ again:			remove_next = 1 + (end > next->vm_end);
- 
- 	if (remove_next) {
- 		if (file) {
--			uprobe_munmap(next);
-+			uprobe_munmap(next, next->vm_start, next->vm_end);
- 			fput(file);
- 			if (next->vm_flags & VM_EXECUTABLE)
- 				removed_exe_file_vma(mm);
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Handle-breakpoint-and-singlestep-except.patch b/features/uprobe/uprobes-core-Handle-breakpoint-and-singlestep-except.patch
deleted file mode 100644
index 2a9e35d69d2ff6057224dd20b60766c0c1fd20a9..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Handle-breakpoint-and-singlestep-except.patch
+++ /dev/null
@@ -1,1018 +0,0 @@
-From 77bfad8317b99fdb2f5a7e01991692e60800dddd Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Tue, 13 Mar 2012 23:30:11 +0530
-Subject: [PATCH 11/24] uprobes/core: Handle breakpoint and singlestep
- exceptions
-
-Uprobes uses exception notifiers to get to know if a thread hit
-a breakpoint or a singlestep exception.
-
-When a thread hits a uprobe or is singlestepping post a uprobe
-hit, the uprobe exception notifier sets its TIF_UPROBE bit,
-which will then be checked on its return to userspace path
-(do_notify_resume() ->uprobe_notify_resume()), where the
-consumers handlers are run (in task context) based on the
-defined filters.
-
-Uprobe hits are thread specific and hence we need to maintain
-information about if a task hit a uprobe, what uprobe was hit,
-the slot where the original instruction was copied for xol so
-that it can be singlestepped with appropriate fixups.
-
-In some cases, special care is needed for instructions that are
-executed out of line (xol). These are architecture specific
-artefacts, such as handling RIP relative instructions on x86_64.
-
-Since the instruction at which the uprobe was inserted is
-executed out of line, architecture specific fixups are added so
-that the thread continues normal execution in the presence of a
-uprobe.
-
-Postpone the signals until we execute the probed insn.
-post_xol() path does a recalc_sigpending() before return to
-user-mode, this ensures the signal can't be lost.
-
-Uprobes relies on DIE_DEBUG notification to notify if a
-singlestep is complete.
-
-Adds x86 specific uprobe exception notifiers and appropriate
-hooks needed to determine a uprobe hit and subsequent post
-processing.
-
-Add requisite x86 fixups for xol for uprobes. Specific cases
-needing fixups include relative jumps (x86_64), calls, etc.
-
-Where possible, we check and skip singlestepping the
-breakpointed instructions. For now we skip single byte as well
-as few multibyte nop instructions. However this can be extended
-to other instructions too.
-
-Credits to Oleg Nesterov for suggestions/patches related to
-signal, breakpoint, singlestep handling code.
-
-commit 0326f5a94ddea33fa331b2519f4172f4fb387baa upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120313180011.29771.89027.sendpatchset@srdronam.in.ibm.com
-[ Performed various cleanliness edits ]
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/include/asm/thread_info.h |    2 +
- arch/x86/include/asm/uprobes.h     |   16 ++-
- arch/x86/kernel/signal.c           |    6 +
- arch/x86/kernel/uprobes.c          |  265 ++++++++++++++++++++++++++++-
- include/linux/sched.h              |    4 +
- include/linux/uprobes.h            |   55 ++++++-
- kernel/events/uprobes.c            |  323 +++++++++++++++++++++++++++++++++++-
- kernel/fork.c                      |    4 +
- kernel/signal.c                    |    4 +
- 9 files changed, 664 insertions(+), 15 deletions(-)
-
-diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
-index ad6df8c..0710c11 100644
---- a/arch/x86/include/asm/thread_info.h
-+++ b/arch/x86/include/asm/thread_info.h
-@@ -85,6 +85,7 @@ struct thread_info {
- #define TIF_SECCOMP		8	/* secure computing */
- #define TIF_MCE_NOTIFY		10	/* notify userspace of an MCE */
- #define TIF_USER_RETURN_NOTIFY	11	/* notify kernel of userspace return */
-+#define TIF_UPROBE		12	/* breakpointed or singlestepping */
- #define TIF_NOTSC		16	/* TSC is not accessible in userland */
- #define TIF_IA32		17	/* IA32 compatibility process */
- #define TIF_FORK		18	/* ret_from_fork */
-@@ -109,6 +110,7 @@ struct thread_info {
- #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
- #define _TIF_MCE_NOTIFY		(1 << TIF_MCE_NOTIFY)
- #define _TIF_USER_RETURN_NOTIFY	(1 << TIF_USER_RETURN_NOTIFY)
-+#define _TIF_UPROBE		(1 << TIF_UPROBE)
- #define _TIF_NOTSC		(1 << TIF_NOTSC)
- #define _TIF_IA32		(1 << TIF_IA32)
- #define _TIF_FORK		(1 << TIF_FORK)
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index 0500391..1e9bed1 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -23,6 +23,8 @@
-  *	Jim Keniston
-  */
- 
-+#include <linux/notifier.h>
-+
- typedef u8 uprobe_opcode_t;
- 
- #define MAX_UINSN_BYTES			  16
-@@ -39,5 +41,17 @@ struct arch_uprobe {
- #endif
- };
- 
--extern int arch_uprobes_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm);
-+struct arch_uprobe_task {
-+	unsigned long			saved_trap_nr;
-+#ifdef CONFIG_X86_64
-+	unsigned long			saved_scratch_register;
-+#endif
-+};
-+
-+extern int  arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm);
-+extern int  arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-+extern int  arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs);
-+extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk);
-+extern int  arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data);
-+extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs);
- #endif	/* _ASM_UPROBES_H */
-diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
-index 115eac4..041af2f 100644
---- a/arch/x86/kernel/signal.c
-+++ b/arch/x86/kernel/signal.c
-@@ -18,6 +18,7 @@
- #include <linux/personality.h>
- #include <linux/uaccess.h>
- #include <linux/user-return-notifier.h>
-+#include <linux/uprobes.h>
- 
- #include <asm/processor.h>
- #include <asm/ucontext.h>
-@@ -824,6 +825,11 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
- 		mce_notify_process();
- #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
- 
-+	if (thread_info_flags & _TIF_UPROBE) {
-+		clear_thread_flag(TIF_UPROBE);
-+		uprobe_notify_resume(regs);
-+	}
-+
- 	/* deal with pending signal delivery */
- 	if (thread_info_flags & _TIF_SIGPENDING)
- 		do_signal(regs);
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index 851a11b..dc4e910 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -24,22 +24,28 @@
- #include <linux/sched.h>
- #include <linux/ptrace.h>
- #include <linux/uprobes.h>
-+#include <linux/uaccess.h>
- 
- #include <linux/kdebug.h>
-+#include <asm/processor.h>
- #include <asm/insn.h>
- 
- /* Post-execution fixups. */
- 
- /* No fixup needed */
--#define UPROBE_FIX_NONE	0x0
-+#define UPROBE_FIX_NONE		0x0
-+
- /* Adjust IP back to vicinity of actual insn */
- #define UPROBE_FIX_IP		0x1
-+
- /* Adjust the return address of a call insn */
- #define UPROBE_FIX_CALL	0x2
- 
- #define UPROBE_FIX_RIP_AX	0x8000
- #define UPROBE_FIX_RIP_CX	0x4000
- 
-+#define	UPROBE_TRAP_NR		UINT_MAX
-+
- /* Adaptations for mhiramat x86 decoder v14. */
- #define OPCODE1(insn)		((insn)->opcode.bytes[0])
- #define OPCODE2(insn)		((insn)->opcode.bytes[1])
-@@ -221,10 +227,9 @@ static int validate_insn_32bits(struct arch_uprobe *auprobe, struct insn *insn)
- }
- 
- /*
-- * Figure out which fixups post_xol() will need to perform, and annotate
-- * arch_uprobe->fixups accordingly.  To start with,
-- * arch_uprobe->fixups is either zero or it reflects rip-related
-- * fixups.
-+ * Figure out which fixups arch_uprobe_post_xol() will need to perform, and
-+ * annotate arch_uprobe->fixups accordingly.  To start with,
-+ * arch_uprobe->fixups is either zero or it reflects rip-related fixups.
-  */
- static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn)
- {
-@@ -401,12 +406,12 @@ static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm,
- #endif /* CONFIG_X86_64 */
- 
- /**
-- * arch_uprobes_analyze_insn - instruction analysis including validity and fixups.
-+ * arch_uprobe_analyze_insn - instruction analysis including validity and fixups.
-  * @mm: the probed address space.
-  * @arch_uprobe: the probepoint information.
-  * Return 0 on success or a -ve number on error.
-  */
--int arch_uprobes_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm)
-+int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm)
- {
- 	int ret;
- 	struct insn insn;
-@@ -421,3 +426,249 @@ int arch_uprobes_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm)
- 
- 	return 0;
- }
-+
-+#ifdef CONFIG_X86_64
-+/*
-+ * If we're emulating a rip-relative instruction, save the contents
-+ * of the scratch register and store the target address in that register.
-+ */
-+static void
-+pre_xol_rip_insn(struct arch_uprobe *auprobe, struct pt_regs *regs,
-+				struct arch_uprobe_task *autask)
-+{
-+	if (auprobe->fixups & UPROBE_FIX_RIP_AX) {
-+		autask->saved_scratch_register = regs->ax;
-+		regs->ax = current->utask->vaddr;
-+		regs->ax += auprobe->rip_rela_target_address;
-+	} else if (auprobe->fixups & UPROBE_FIX_RIP_CX) {
-+		autask->saved_scratch_register = regs->cx;
-+		regs->cx = current->utask->vaddr;
-+		regs->cx += auprobe->rip_rela_target_address;
-+	}
-+}
-+#else
-+static void
-+pre_xol_rip_insn(struct arch_uprobe *auprobe, struct pt_regs *regs,
-+				struct arch_uprobe_task *autask)
-+{
-+	/* No RIP-relative addressing on 32-bit */
-+}
-+#endif
-+
-+/*
-+ * arch_uprobe_pre_xol - prepare to execute out of line.
-+ * @auprobe: the probepoint information.
-+ * @regs: reflects the saved user state of current task.
-+ */
-+int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	struct arch_uprobe_task *autask;
-+
-+	autask = &current->utask->autask;
-+	autask->saved_trap_nr = current->thread.trap_nr;
-+	current->thread.trap_nr = UPROBE_TRAP_NR;
-+	regs->ip = current->utask->xol_vaddr;
-+	pre_xol_rip_insn(auprobe, regs, autask);
-+
-+	return 0;
-+}
-+
-+/*
-+ * This function is called by arch_uprobe_post_xol() to adjust the return
-+ * address pushed by a call instruction executed out of line.
-+ */
-+static int adjust_ret_addr(unsigned long sp, long correction)
-+{
-+	int rasize, ncopied;
-+	long ra = 0;
-+
-+	if (is_ia32_task())
-+		rasize = 4;
-+	else
-+		rasize = 8;
-+
-+	ncopied = copy_from_user(&ra, (void __user *)sp, rasize);
-+	if (unlikely(ncopied))
-+		return -EFAULT;
-+
-+	ra += correction;
-+	ncopied = copy_to_user((void __user *)sp, &ra, rasize);
-+	if (unlikely(ncopied))
-+		return -EFAULT;
-+
-+	return 0;
-+}
-+
-+#ifdef CONFIG_X86_64
-+static bool is_riprel_insn(struct arch_uprobe *auprobe)
-+{
-+	return ((auprobe->fixups & (UPROBE_FIX_RIP_AX | UPROBE_FIX_RIP_CX)) != 0);
-+}
-+
-+static void
-+handle_riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs, long *correction)
-+{
-+	if (is_riprel_insn(auprobe)) {
-+		struct arch_uprobe_task *autask;
-+
-+		autask = &current->utask->autask;
-+		if (auprobe->fixups & UPROBE_FIX_RIP_AX)
-+			regs->ax = autask->saved_scratch_register;
-+		else
-+			regs->cx = autask->saved_scratch_register;
-+
-+		/*
-+		 * The original instruction includes a displacement, and so
-+		 * is 4 bytes longer than what we've just single-stepped.
-+		 * Fall through to handle stuff like "jmpq *...(%rip)" and
-+		 * "callq *...(%rip)".
-+		 */
-+		if (correction)
-+			*correction += 4;
-+	}
-+}
-+#else
-+static void
-+handle_riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs, long *correction)
-+{
-+	/* No RIP-relative addressing on 32-bit */
-+}
-+#endif
-+
-+/*
-+ * If xol insn itself traps and generates a signal(Say,
-+ * SIGILL/SIGSEGV/etc), then detect the case where a singlestepped
-+ * instruction jumps back to its own address. It is assumed that anything
-+ * like do_page_fault/do_trap/etc sets thread.trap_nr != -1.
-+ *
-+ * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr,
-+ * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to
-+ * UPROBE_TRAP_NR == -1 set by arch_uprobe_pre_xol().
-+ */
-+bool arch_uprobe_xol_was_trapped(struct task_struct *t)
-+{
-+	if (t->thread.trap_nr != UPROBE_TRAP_NR)
-+		return true;
-+
-+	return false;
-+}
-+
-+/*
-+ * Called after single-stepping. To avoid the SMP problems that can
-+ * occur when we temporarily put back the original opcode to
-+ * single-step, we single-stepped a copy of the instruction.
-+ *
-+ * This function prepares to resume execution after the single-step.
-+ * We have to fix things up as follows:
-+ *
-+ * Typically, the new ip is relative to the copied instruction.  We need
-+ * to make it relative to the original instruction (FIX_IP).  Exceptions
-+ * are return instructions and absolute or indirect jump or call instructions.
-+ *
-+ * If the single-stepped instruction was a call, the return address that
-+ * is atop the stack is the address following the copied instruction.  We
-+ * need to make it the address following the original instruction (FIX_CALL).
-+ *
-+ * If the original instruction was a rip-relative instruction such as
-+ * "movl %edx,0xnnnn(%rip)", we have instead executed an equivalent
-+ * instruction using a scratch register -- e.g., "movl %edx,(%rax)".
-+ * We need to restore the contents of the scratch register and adjust
-+ * the ip, keeping in mind that the instruction we executed is 4 bytes
-+ * shorter than the original instruction (since we squeezed out the offset
-+ * field).  (FIX_RIP_AX or FIX_RIP_CX)
-+ */
-+int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask;
-+	long correction;
-+	int result = 0;
-+
-+	WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR);
-+
-+	utask = current->utask;
-+	current->thread.trap_nr = utask->autask.saved_trap_nr;
-+	correction = (long)(utask->vaddr - utask->xol_vaddr);
-+	handle_riprel_post_xol(auprobe, regs, &correction);
-+	if (auprobe->fixups & UPROBE_FIX_IP)
-+		regs->ip += correction;
-+
-+	if (auprobe->fixups & UPROBE_FIX_CALL)
-+		result = adjust_ret_addr(regs->sp, correction);
-+
-+	return result;
-+}
-+
-+/* callback routine for handling exceptions. */
-+int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data)
-+{
-+	struct die_args *args = data;
-+	struct pt_regs *regs = args->regs;
-+	int ret = NOTIFY_DONE;
-+
-+	/* We are only interested in userspace traps */
-+	if (regs && !user_mode_vm(regs))
-+		return NOTIFY_DONE;
-+
-+	switch (val) {
-+	case DIE_INT3:
-+		if (uprobe_pre_sstep_notifier(regs))
-+			ret = NOTIFY_STOP;
-+
-+		break;
-+
-+	case DIE_DEBUG:
-+		if (uprobe_post_sstep_notifier(regs))
-+			ret = NOTIFY_STOP;
-+
-+	default:
-+		break;
-+	}
-+
-+	return ret;
-+}
-+
-+/*
-+ * This function gets called when XOL instruction either gets trapped or
-+ * the thread has a fatal signal, so reset the instruction pointer to its
-+ * probed address.
-+ */
-+void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask = current->utask;
-+
-+	current->thread.trap_nr = utask->autask.saved_trap_nr;
-+	handle_riprel_post_xol(auprobe, regs, NULL);
-+	instruction_pointer_set(regs, utask->vaddr);
-+}
-+
-+/*
-+ * Skip these instructions as per the currently known x86 ISA.
-+ * 0x66* { 0x90 | 0x0f 0x1f | 0x0f 0x19 | 0x87 0xc0 }
-+ */
-+bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
-+{
-+	int i;
-+
-+	for (i = 0; i < MAX_UINSN_BYTES; i++) {
-+		if ((auprobe->insn[i] == 0x66))
-+			continue;
-+
-+		if (auprobe->insn[i] == 0x90)
-+			return true;
-+
-+		if (i == (MAX_UINSN_BYTES - 1))
-+			break;
-+
-+		if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x1f))
-+			return true;
-+
-+		if ((auprobe->insn[i] == 0x0f) && (auprobe->insn[i+1] == 0x19))
-+			return true;
-+
-+		if ((auprobe->insn[i] == 0x87) && (auprobe->insn[i+1] == 0xc0))
-+			return true;
-+
-+		break;
-+	}
-+	return false;
-+}
-diff --git a/include/linux/sched.h b/include/linux/sched.h
-index a862c23..7bcc634 100644
---- a/include/linux/sched.h
-+++ b/include/linux/sched.h
-@@ -1619,6 +1619,10 @@ struct task_struct {
- #ifdef CONFIG_HAVE_HW_BREAKPOINT
- 	atomic_t ptrace_bp_refcnt;
- #endif
-+#ifdef CONFIG_UPROBES
-+	struct uprobe_task *utask;
-+	int uprobe_srcu_id;
-+#endif
- };
- 
- /* Future-safe accessor for struct task_struct's cpus_allowed. */
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index eac525f..5ec778f 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -28,8 +28,9 @@
- #include <linux/rbtree.h>
- 
- struct vm_area_struct;
-+
- #ifdef CONFIG_ARCH_SUPPORTS_UPROBES
--#include <asm/uprobes.h>
-+# include <asm/uprobes.h>
- #endif
- 
- /* flags that denote/change uprobes behaviour */
-@@ -39,6 +40,8 @@ struct vm_area_struct;
- 
- /* Dont run handlers when first register/ last unregister in progress*/
- #define UPROBE_RUN_HANDLER	0x2
-+/* Can skip singlestep */
-+#define UPROBE_SKIP_SSTEP	0x4
- 
- struct uprobe_consumer {
- 	int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
-@@ -52,13 +55,42 @@ struct uprobe_consumer {
- };
- 
- #ifdef CONFIG_UPROBES
-+enum uprobe_task_state {
-+	UTASK_RUNNING,
-+	UTASK_BP_HIT,
-+	UTASK_SSTEP,
-+	UTASK_SSTEP_ACK,
-+	UTASK_SSTEP_TRAPPED,
-+};
-+
-+/*
-+ * uprobe_task: Metadata of a task while it singlesteps.
-+ */
-+struct uprobe_task {
-+	enum uprobe_task_state		state;
-+	struct arch_uprobe_task		autask;
-+
-+	struct uprobe			*active_uprobe;
-+
-+	unsigned long			xol_vaddr;
-+	unsigned long			vaddr;
-+};
-+
- extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
- extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm,  unsigned long vaddr, bool verify);
- extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
- extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern int uprobe_mmap(struct vm_area_struct *vma);
--#else /* CONFIG_UPROBES is not defined */
-+extern void uprobe_free_utask(struct task_struct *t);
-+extern void uprobe_copy_process(struct task_struct *t);
-+extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
-+extern int uprobe_post_sstep_notifier(struct pt_regs *regs);
-+extern int uprobe_pre_sstep_notifier(struct pt_regs *regs);
-+extern void uprobe_notify_resume(struct pt_regs *regs);
-+extern bool uprobe_deny_signal(void);
-+extern bool __weak arch_uprobe_skip_sstep(struct arch_uprobe *aup, struct pt_regs *regs);
-+#else /* !CONFIG_UPROBES */
- static inline int
- uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
- {
-@@ -72,5 +104,22 @@ static inline int uprobe_mmap(struct vm_area_struct *vma)
- {
- 	return 0;
- }
--#endif /* CONFIG_UPROBES */
-+static inline void uprobe_notify_resume(struct pt_regs *regs)
-+{
-+}
-+static inline bool uprobe_deny_signal(void)
-+{
-+	return false;
-+}
-+static inline unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
-+{
-+	return 0;
-+}
-+static inline void uprobe_free_utask(struct task_struct *t)
-+{
-+}
-+static inline void uprobe_copy_process(struct task_struct *t)
-+{
-+}
-+#endif /* !CONFIG_UPROBES */
- #endif	/* _LINUX_UPROBES_H */
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index e56e56a..b807d15 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -30,9 +30,12 @@
- #include <linux/rmap.h>		/* anon_vma_prepare */
- #include <linux/mmu_notifier.h>	/* set_pte_at_notify */
- #include <linux/swap.h>		/* try_to_free_swap */
-+#include <linux/ptrace.h>	/* user_enable_single_step */
-+#include <linux/kdebug.h>	/* notifier mechanism */
- 
- #include <linux/uprobes.h>
- 
-+static struct srcu_struct uprobes_srcu;
- static struct rb_root uprobes_tree = RB_ROOT;
- 
- static DEFINE_SPINLOCK(uprobes_treelock);	/* serialize rbtree access */
-@@ -486,6 +489,9 @@ static struct uprobe *insert_uprobe(struct uprobe *uprobe)
- 	u = __insert_uprobe(uprobe);
- 	spin_unlock_irqrestore(&uprobes_treelock, flags);
- 
-+	/* For now assume that the instruction need not be single-stepped */
-+	uprobe->flags |= UPROBE_SKIP_SSTEP;
-+
- 	return u;
- }
- 
-@@ -523,6 +529,21 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
- 	return uprobe;
- }
- 
-+static void handler_chain(struct uprobe *uprobe, struct pt_regs *regs)
-+{
-+	struct uprobe_consumer *uc;
-+
-+	if (!(uprobe->flags & UPROBE_RUN_HANDLER))
-+		return;
-+
-+	down_read(&uprobe->consumer_rwsem);
-+	for (uc = uprobe->consumers; uc; uc = uc->next) {
-+		if (!uc->filter || uc->filter(uc, current))
-+			uc->handler(uc, regs);
-+	}
-+	up_read(&uprobe->consumer_rwsem);
-+}
-+
- /* Returns the previous consumer */
- static struct uprobe_consumer *
- consumer_add(struct uprobe *uprobe, struct uprobe_consumer *uc)
-@@ -645,7 +666,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- 		if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
- 			return -EEXIST;
- 
--		ret = arch_uprobes_analyze_insn(&uprobe->arch, mm);
-+		ret = arch_uprobe_analyze_insn(&uprobe->arch, mm);
- 		if (ret)
- 			return ret;
- 
-@@ -662,10 +683,21 @@ remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr)
- 	set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true);
- }
- 
-+/*
-+ * There could be threads that have hit the breakpoint and are entering the
-+ * notifier code and trying to acquire the uprobes_treelock. The thread
-+ * calling delete_uprobe() that is removing the uprobe from the rb_tree can
-+ * race with these threads and might acquire the uprobes_treelock compared
-+ * to some of the breakpoint hit threads. In such a case, the breakpoint
-+ * hit threads will not find the uprobe. The current unregistering thread
-+ * waits till all other threads have hit a breakpoint, to acquire the
-+ * uprobes_treelock before the uprobe is removed from the rbtree.
-+ */
- static void delete_uprobe(struct uprobe *uprobe)
- {
- 	unsigned long flags;
- 
-+	synchronize_srcu(&uprobes_srcu);
- 	spin_lock_irqsave(&uprobes_treelock, flags);
- 	rb_erase(&uprobe->rb_node, &uprobes_tree);
- 	spin_unlock_irqrestore(&uprobes_treelock, flags);
-@@ -1010,6 +1042,288 @@ int uprobe_mmap(struct vm_area_struct *vma)
- 	return ret;
- }
- 
-+/**
-+ * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs
-+ * @regs: Reflects the saved state of the task after it has hit a breakpoint
-+ * instruction.
-+ * Return the address of the breakpoint instruction.
-+ */
-+unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs)
-+{
-+	return instruction_pointer(regs) - UPROBE_SWBP_INSN_SIZE;
-+}
-+
-+/*
-+ * Called with no locks held.
-+ * Called in context of a exiting or a exec-ing thread.
-+ */
-+void uprobe_free_utask(struct task_struct *t)
-+{
-+	struct uprobe_task *utask = t->utask;
-+
-+	if (t->uprobe_srcu_id != -1)
-+		srcu_read_unlock_raw(&uprobes_srcu, t->uprobe_srcu_id);
-+
-+	if (!utask)
-+		return;
-+
-+	if (utask->active_uprobe)
-+		put_uprobe(utask->active_uprobe);
-+
-+	kfree(utask);
-+	t->utask = NULL;
-+}
-+
-+/*
-+ * Called in context of a new clone/fork from copy_process.
-+ */
-+void uprobe_copy_process(struct task_struct *t)
-+{
-+	t->utask = NULL;
-+	t->uprobe_srcu_id = -1;
-+}
-+
-+/*
-+ * Allocate a uprobe_task object for the task.
-+ * Called when the thread hits a breakpoint for the first time.
-+ *
-+ * Returns:
-+ * - pointer to new uprobe_task on success
-+ * - NULL otherwise
-+ */
-+static struct uprobe_task *add_utask(void)
-+{
-+	struct uprobe_task *utask;
-+
-+	utask = kzalloc(sizeof *utask, GFP_KERNEL);
-+	if (unlikely(!utask))
-+		return NULL;
-+
-+	utask->active_uprobe = NULL;
-+	current->utask = utask;
-+	return utask;
-+}
-+
-+/* Prepare to single-step probed instruction out of line. */
-+static int
-+pre_ssout(struct uprobe *uprobe, struct pt_regs *regs, unsigned long vaddr)
-+{
-+	return -EFAULT;
-+}
-+
-+/*
-+ * If we are singlestepping, then ensure this thread is not connected to
-+ * non-fatal signals until completion of singlestep.  When xol insn itself
-+ * triggers the signal,  restart the original insn even if the task is
-+ * already SIGKILL'ed (since coredump should report the correct ip).  This
-+ * is even more important if the task has a handler for SIGSEGV/etc, The
-+ * _same_ instruction should be repeated again after return from the signal
-+ * handler, and SSTEP can never finish in this case.
-+ */
-+bool uprobe_deny_signal(void)
-+{
-+	struct task_struct *t = current;
-+	struct uprobe_task *utask = t->utask;
-+
-+	if (likely(!utask || !utask->active_uprobe))
-+		return false;
-+
-+	WARN_ON_ONCE(utask->state != UTASK_SSTEP);
-+
-+	if (signal_pending(t)) {
-+		spin_lock_irq(&t->sighand->siglock);
-+		clear_tsk_thread_flag(t, TIF_SIGPENDING);
-+		spin_unlock_irq(&t->sighand->siglock);
-+
-+		if (__fatal_signal_pending(t) || arch_uprobe_xol_was_trapped(t)) {
-+			utask->state = UTASK_SSTEP_TRAPPED;
-+			set_tsk_thread_flag(t, TIF_UPROBE);
-+			set_tsk_thread_flag(t, TIF_NOTIFY_RESUME);
-+		}
-+	}
-+
-+	return true;
-+}
-+
-+/*
-+ * Avoid singlestepping the original instruction if the original instruction
-+ * is a NOP or can be emulated.
-+ */
-+static bool can_skip_sstep(struct uprobe *uprobe, struct pt_regs *regs)
-+{
-+	if (arch_uprobe_skip_sstep(&uprobe->arch, regs))
-+		return true;
-+
-+	uprobe->flags &= ~UPROBE_SKIP_SSTEP;
-+	return false;
-+}
-+
-+/*
-+ * Run handler and ask thread to singlestep.
-+ * Ensure all non-fatal signals cannot interrupt thread while it singlesteps.
-+ */
-+static void handle_swbp(struct pt_regs *regs)
-+{
-+	struct vm_area_struct *vma;
-+	struct uprobe_task *utask;
-+	struct uprobe *uprobe;
-+	struct mm_struct *mm;
-+	unsigned long bp_vaddr;
-+
-+	uprobe = NULL;
-+	bp_vaddr = uprobe_get_swbp_addr(regs);
-+	mm = current->mm;
-+	down_read(&mm->mmap_sem);
-+	vma = find_vma(mm, bp_vaddr);
-+
-+	if (vma && vma->vm_start <= bp_vaddr && valid_vma(vma, false)) {
-+		struct inode *inode;
-+		loff_t offset;
-+
-+		inode = vma->vm_file->f_mapping->host;
-+		offset = bp_vaddr - vma->vm_start;
-+		offset += (vma->vm_pgoff << PAGE_SHIFT);
-+		uprobe = find_uprobe(inode, offset);
-+	}
-+
-+	srcu_read_unlock_raw(&uprobes_srcu, current->uprobe_srcu_id);
-+	current->uprobe_srcu_id = -1;
-+	up_read(&mm->mmap_sem);
-+
-+	if (!uprobe) {
-+		/* No matching uprobe; signal SIGTRAP. */
-+		send_sig(SIGTRAP, current, 0);
-+		return;
-+	}
-+
-+	utask = current->utask;
-+	if (!utask) {
-+		utask = add_utask();
-+		/* Cannot allocate; re-execute the instruction. */
-+		if (!utask)
-+			goto cleanup_ret;
-+	}
-+	utask->active_uprobe = uprobe;
-+	handler_chain(uprobe, regs);
-+	if (uprobe->flags & UPROBE_SKIP_SSTEP && can_skip_sstep(uprobe, regs))
-+		goto cleanup_ret;
-+
-+	utask->state = UTASK_SSTEP;
-+	if (!pre_ssout(uprobe, regs, bp_vaddr)) {
-+		user_enable_single_step(current);
-+		return;
-+	}
-+
-+cleanup_ret:
-+	if (utask) {
-+		utask->active_uprobe = NULL;
-+		utask->state = UTASK_RUNNING;
-+	}
-+	if (uprobe) {
-+		if (!(uprobe->flags & UPROBE_SKIP_SSTEP))
-+
-+			/*
-+			 * cannot singlestep; cannot skip instruction;
-+			 * re-execute the instruction.
-+			 */
-+			instruction_pointer_set(regs, bp_vaddr);
-+
-+		put_uprobe(uprobe);
-+	}
-+}
-+
-+/*
-+ * Perform required fix-ups and disable singlestep.
-+ * Allow pending signals to take effect.
-+ */
-+static void handle_singlestep(struct uprobe_task *utask, struct pt_regs *regs)
-+{
-+	struct uprobe *uprobe;
-+
-+	uprobe = utask->active_uprobe;
-+	if (utask->state == UTASK_SSTEP_ACK)
-+		arch_uprobe_post_xol(&uprobe->arch, regs);
-+	else if (utask->state == UTASK_SSTEP_TRAPPED)
-+		arch_uprobe_abort_xol(&uprobe->arch, regs);
-+	else
-+		WARN_ON_ONCE(1);
-+
-+	put_uprobe(uprobe);
-+	utask->active_uprobe = NULL;
-+	utask->state = UTASK_RUNNING;
-+	user_disable_single_step(current);
-+
-+	spin_lock_irq(&current->sighand->siglock);
-+	recalc_sigpending(); /* see uprobe_deny_signal() */
-+	spin_unlock_irq(&current->sighand->siglock);
-+}
-+
-+/*
-+ * On breakpoint hit, breakpoint notifier sets the TIF_UPROBE flag.  (and on
-+ * subsequent probe hits on the thread sets the state to UTASK_BP_HIT) and
-+ * allows the thread to return from interrupt.
-+ *
-+ * On singlestep exception, singlestep notifier sets the TIF_UPROBE flag and
-+ * also sets the state to UTASK_SSTEP_ACK and allows the thread to return from
-+ * interrupt.
-+ *
-+ * While returning to userspace, thread notices the TIF_UPROBE flag and calls
-+ * uprobe_notify_resume().
-+ */
-+void uprobe_notify_resume(struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask;
-+
-+	utask = current->utask;
-+	if (!utask || utask->state == UTASK_BP_HIT)
-+		handle_swbp(regs);
-+	else
-+		handle_singlestep(utask, regs);
-+}
-+
-+/*
-+ * uprobe_pre_sstep_notifier gets called from interrupt context as part of
-+ * notifier mechanism. Set TIF_UPROBE flag and indicate breakpoint hit.
-+ */
-+int uprobe_pre_sstep_notifier(struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask;
-+
-+	if (!current->mm)
-+		return 0;
-+
-+	utask = current->utask;
-+	if (utask)
-+		utask->state = UTASK_BP_HIT;
-+
-+	set_thread_flag(TIF_UPROBE);
-+	current->uprobe_srcu_id = srcu_read_lock_raw(&uprobes_srcu);
-+
-+	return 1;
-+}
-+
-+/*
-+ * uprobe_post_sstep_notifier gets called in interrupt context as part of notifier
-+ * mechanism. Set TIF_UPROBE flag and indicate completion of singlestep.
-+ */
-+int uprobe_post_sstep_notifier(struct pt_regs *regs)
-+{
-+	struct uprobe_task *utask = current->utask;
-+
-+	if (!current->mm || !utask || !utask->active_uprobe)
-+		/* task is currently not uprobed */
-+		return 0;
-+
-+	utask->state = UTASK_SSTEP_ACK;
-+	set_thread_flag(TIF_UPROBE);
-+	return 1;
-+}
-+
-+static struct notifier_block uprobe_exception_nb = {
-+	.notifier_call		= arch_uprobe_exception_notify,
-+	.priority		= INT_MAX-1,	/* notified after kprobes, kgdb */
-+};
-+
- static int __init init_uprobes(void)
- {
- 	int i;
-@@ -1018,12 +1332,13 @@ static int __init init_uprobes(void)
- 		mutex_init(&uprobes_mutex[i]);
- 		mutex_init(&uprobes_mmap_mutex[i]);
- 	}
--	return 0;
-+	init_srcu_struct(&uprobes_srcu);
-+
-+	return register_die_notifier(&uprobe_exception_nb);
- }
-+module_init(init_uprobes);
- 
- static void __exit exit_uprobes(void)
- {
- }
--
--module_init(init_uprobes);
- module_exit(exit_uprobes);
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 9faa812..5be9230 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -69,6 +69,7 @@
- #include <linux/oom.h>
- #include <linux/khugepaged.h>
- #include <linux/signalfd.h>
-+#include <linux/uprobes.h>
- 
- #include <asm/pgtable.h>
- #include <asm/pgalloc.h>
-@@ -751,6 +752,8 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
- 		exit_pi_state_list(tsk);
- #endif
- 
-+	uprobe_free_utask(tsk);
-+
- 	/* Get rid of any cached register state */
- 	deactivate_mm(tsk, mm);
- 
-@@ -1347,6 +1350,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
- 	INIT_LIST_HEAD(&p->pi_state_list);
- 	p->pi_state_cache = NULL;
- #endif
-+	uprobe_copy_process(p);
- 	/*
- 	 * sigaltstack should be cleared when sharing the same VM
- 	 */
-diff --git a/kernel/signal.c b/kernel/signal.c
-index 1a006b5..9da710c 100644
---- a/kernel/signal.c
-+++ b/kernel/signal.c
-@@ -29,6 +29,7 @@
- #include <linux/pid_namespace.h>
- #include <linux/nsproxy.h>
- #include <linux/user_namespace.h>
-+#include <linux/uprobes.h>
- #define CREATE_TRACE_POINTS
- #include <trace/events/signal.h>
- 
-@@ -2202,6 +2203,9 @@ int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka,
- 	struct signal_struct *signal = current->signal;
- 	int signr;
- 
-+	if (unlikely(uprobe_deny_signal()))
-+		return 0;
-+
- relock:
- 	/*
- 	 * We'll jump back here after any time we were stopped in TASK_STOPPED.
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Make-background-page-replacement-logic-.patch b/features/uprobe/uprobes-core-Make-background-page-replacement-logic-.patch
deleted file mode 100644
index d4d812441311a901bb12716e7a85e25809fdb1f0..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Make-background-page-replacement-logic-.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-From a25205633f0b98c88dceb56cd61adeda54f41390 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Wed, 11 Apr 2012 16:05:16 +0530
-Subject: [PATCH 14/24] uprobes/core: Make background page replacement logic
- account for rss_stat counters
-
-Background page replacement logic adds a new anonymous page
-instead of a file backed (while inserting a breakpoint) /
-anonymous page (while removing a breakpoint).
-
-Hence the uprobes logic should take care to update the
-task->ss_stat counters accordingly.
-
-This bug became apparent courtesy of commit c3f0327f8e9d
-("mm: add rss counters consistency check").
-
-commit 7396fa818d6278694a44840f389ddc40a3269a9a upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120411103516.23245.2700.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- kernel/events/uprobes.c |    5 +++++
- 1 files changed, 5 insertions(+), 0 deletions(-)
-
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 29e881b..c5caeec 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -160,6 +160,11 @@ static int __replace_page(struct vm_area_struct *vma, struct page *page, struct
- 	get_page(kpage);
- 	page_add_new_anon_rmap(kpage, vma, addr);
- 
-+	if (!PageAnon(page)) {
-+		dec_mm_counter(mm, MM_FILEPAGES);
-+		inc_mm_counter(mm, MM_ANONPAGES);
-+	}
-+
- 	flush_cache_page(vma, addr, pte_pfn(*ptep));
- 	ptep_clear_flush(vma, addr, ptep);
- 	set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot));
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Make-instruction-tables-volatile.patch b/features/uprobe/uprobes-core-Make-instruction-tables-volatile.patch
deleted file mode 100644
index c1bb7308f7ff098e834d0ddf1744cdcf28efdfcd..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Make-instruction-tables-volatile.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From 942b91cb42642479bd074388bf25881a3c3ca450 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Wed, 22 Feb 2012 14:45:35 +0530
-Subject: [PATCH 04/24] uprobes/core: Make instruction tables volatile
-
-Some versions of gcc spits a warning about the asm operand for
-test_bit and also causes the first long of the instruction table
-to be output.
-
-Fix is similar to 7115e3fc on arch/x86/kernel/kprobes.c
-
-commit 04a3d984d32e47983770d314cdb4e4d8f38fccb7 upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Jiri Olsa <jolsa@redhat.com>
-Cc: Josh Stone <jistone@redhat.com>
-Link: http://lkml.kernel.org/r/20120222091535.15880.12502.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/kernel/uprobes.c |   61 +++++++++++++++++++++++---------------------
- 1 files changed, 32 insertions(+), 29 deletions(-)
-
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index cf2a184..13d616d 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -53,34 +53,12 @@
- 	  (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf))    \
- 	 << (row % 32))
- 
--#ifdef CONFIG_X86_64
--static u32 good_insns_64[256 / 32] = {
--	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
--	/*      ----------------------------------------------         */
--	W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */
--	W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */
--	W(0x20, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 20 */
--	W(0x30, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 30 */
--	W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
--	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
--	W(0x60, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
--	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
--	W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
--	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
--	W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
--	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
--	W(0xc0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
--	W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
--	W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
--	W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1)   /* f0 */
--	/*      ----------------------------------------------         */
--	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
--};
--#endif
--
--/* Good-instruction tables for 32-bit apps */
--
--static u32 good_insns_32[256 / 32] = {
-+/*
-+ * Good-instruction tables for 32-bit apps.  This is non-const and volatile
-+ * to keep gcc from statically optimizing it out, as variable_test_bit makes
-+ * some versions of gcc to think only *(unsigned long*) is used.
-+ */
-+static volatile u32 good_insns_32[256 / 32] = {
- 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
- 	/*      ----------------------------------------------         */
- 	W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 00 */
-@@ -104,7 +82,7 @@ static u32 good_insns_32[256 / 32] = {
- };
- 
- /* Using this for both 64-bit and 32-bit apps */
--static u32 good_2byte_insns[256 / 32] = {
-+static volatile u32 good_2byte_insns[256 / 32] = {
- 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
- 	/*      ----------------------------------------------         */
- 	W(0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) | /* 00 */
-@@ -127,6 +105,31 @@ static u32 good_2byte_insns[256 / 32] = {
- 	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
- };
- 
-+#ifdef CONFIG_X86_64
-+/* Good-instruction tables for 64-bit apps */
-+static volatile u32 good_insns_64[256 / 32] = {
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+	/*      ----------------------------------------------         */
-+	W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */
-+	W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */
-+	W(0x20, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 20 */
-+	W(0x30, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 30 */
-+	W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
-+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
-+	W(0x60, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
-+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
-+	W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
-+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
-+	W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
-+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
-+	W(0xc0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
-+	W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
-+	W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
-+	W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1)   /* f0 */
-+	/*      ----------------------------------------------         */
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+};
-+#endif
- #undef W
- 
- /*
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Make-macro-names-consistent.patch b/features/uprobe/uprobes-core-Make-macro-names-consistent.patch
deleted file mode 100644
index d72b37d379330627a4819a1166bd0eecf4df712b..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Make-macro-names-consistent.patch
+++ /dev/null
@@ -1,201 +0,0 @@
-From 7e9be9963c8b594bfe07145d3fe56549377f0bc4 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 12 Mar 2012 14:55:14 +0530
-Subject: [PATCH 08/24] uprobes/core: Make macro names consistent
-
-Rename macros that refer to individual uprobe to start with
-UPROBE_ instead of UPROBES_.
-
-This is pure cleanup, no functional change intended.
-
-commit 900771a483ef28915a48066d7895d8252315607a upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120312092514.5379.36595.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/include/asm/uprobes.h |    6 +++---
- arch/x86/kernel/uprobes.c      |   18 +++++++++---------
- include/linux/uprobes.h        |    4 ++--
- kernel/events/uprobes.c        |   18 +++++++++---------
- 4 files changed, 23 insertions(+), 23 deletions(-)
-
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index f7ce310..5c399e4 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -26,10 +26,10 @@
- typedef u8 uprobe_opcode_t;
- 
- #define MAX_UINSN_BYTES			  16
--#define UPROBES_XOL_SLOT_BYTES		 128	/* to keep it cache aligned */
-+#define UPROBE_XOL_SLOT_BYTES		 128	/* to keep it cache aligned */
- 
--#define UPROBES_BKPT_INSN		0xcc
--#define UPROBES_BKPT_INSN_SIZE		   1
-+#define UPROBE_BKPT_INSN		0xcc
-+#define UPROBE_BKPT_INSN_SIZE		   1
- 
- struct arch_uprobe {
- 	u16				fixups;
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index 04dfcef..6dfa89e 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -31,14 +31,14 @@
- /* Post-execution fixups. */
- 
- /* No fixup needed */
--#define UPROBES_FIX_NONE	0x0
-+#define UPROBE_FIX_NONE	0x0
- /* Adjust IP back to vicinity of actual insn */
--#define UPROBES_FIX_IP		0x1
-+#define UPROBE_FIX_IP		0x1
- /* Adjust the return address of a call insn */
--#define UPROBES_FIX_CALL	0x2
-+#define UPROBE_FIX_CALL	0x2
- 
--#define UPROBES_FIX_RIP_AX	0x8000
--#define UPROBES_FIX_RIP_CX	0x4000
-+#define UPROBE_FIX_RIP_AX	0x8000
-+#define UPROBE_FIX_RIP_CX	0x4000
- 
- /* Adaptations for mhiramat x86 decoder v14. */
- #define OPCODE1(insn)		((insn)->opcode.bytes[0])
-@@ -269,9 +269,9 @@ static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn)
- 		break;
- 	}
- 	if (fix_ip)
--		auprobe->fixups |= UPROBES_FIX_IP;
-+		auprobe->fixups |= UPROBE_FIX_IP;
- 	if (fix_call)
--		auprobe->fixups |= UPROBES_FIX_CALL;
-+		auprobe->fixups |= UPROBE_FIX_CALL;
- }
- 
- #ifdef CONFIG_X86_64
-@@ -341,12 +341,12 @@ static void handle_riprel_insn(struct mm_struct *mm, struct arch_uprobe *auprobe
- 		 * is NOT the register operand, so we use %rcx (register
- 		 * #1) for the scratch register.
- 		 */
--		auprobe->fixups = UPROBES_FIX_RIP_CX;
-+		auprobe->fixups = UPROBE_FIX_RIP_CX;
- 		/* Change modrm from 00 000 101 to 00 000 001. */
- 		*cursor = 0x1;
- 	} else {
- 		/* Use %rax (register #0) for the scratch register. */
--		auprobe->fixups = UPROBES_FIX_RIP_AX;
-+		auprobe->fixups = UPROBE_FIX_RIP_AX;
- 		/* Change modrm from 00 xxx 101 to 00 xxx 000 */
- 		*cursor = (reg << 3);
- 	}
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index f85797e..838fb31 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -35,10 +35,10 @@ struct vm_area_struct;
- /* flags that denote/change uprobes behaviour */
- 
- /* Have a copy of original instruction */
--#define UPROBES_COPY_INSN	0x1
-+#define UPROBE_COPY_INSN	0x1
- 
- /* Dont run handlers when first register/ last unregister in progress*/
--#define UPROBES_RUN_HANDLER	0x2
-+#define UPROBE_RUN_HANDLER	0x2
- 
- struct uprobe_consumer {
- 	int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 5ce32e3..0d36bf3 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -177,7 +177,7 @@ out:
-  */
- bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
- {
--	return *insn == UPROBES_BKPT_INSN;
-+	return *insn == UPROBE_BKPT_INSN;
- }
- 
- /*
-@@ -259,8 +259,8 @@ static int write_opcode(struct mm_struct *mm, struct arch_uprobe *auprobe,
- 
- 	/* poke the new insn in, ASSUMES we don't cross page boundary */
- 	vaddr &= ~PAGE_MASK;
--	BUG_ON(vaddr + UPROBES_BKPT_INSN_SIZE > PAGE_SIZE);
--	memcpy(vaddr_new + vaddr, &opcode, UPROBES_BKPT_INSN_SIZE);
-+	BUG_ON(vaddr + UPROBE_BKPT_INSN_SIZE > PAGE_SIZE);
-+	memcpy(vaddr_new + vaddr, &opcode, UPROBE_BKPT_INSN_SIZE);
- 
- 	kunmap_atomic(vaddr_new);
- 	kunmap_atomic(vaddr_old);
-@@ -308,7 +308,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_
- 	lock_page(page);
- 	vaddr_new = kmap_atomic(page);
- 	vaddr &= ~PAGE_MASK;
--	memcpy(opcode, vaddr_new + vaddr, UPROBES_BKPT_INSN_SIZE);
-+	memcpy(opcode, vaddr_new + vaddr, UPROBE_BKPT_INSN_SIZE);
- 	kunmap_atomic(vaddr_new);
- 	unlock_page(page);
- 
-@@ -352,7 +352,7 @@ int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned
- 	if (result)
- 		return result;
- 
--	return write_opcode(mm, auprobe, vaddr, UPROBES_BKPT_INSN);
-+	return write_opcode(mm, auprobe, vaddr, UPROBE_BKPT_INSN);
- }
- 
- /**
-@@ -635,7 +635,7 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 
- 	addr = (unsigned long)vaddr;
- 
--	if (!(uprobe->flags & UPROBES_COPY_INSN)) {
-+	if (!(uprobe->flags & UPROBE_COPY_INSN)) {
- 		ret = copy_insn(uprobe, vma, addr);
- 		if (ret)
- 			return ret;
-@@ -647,7 +647,7 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 		if (ret)
- 			return ret;
- 
--		uprobe->flags |= UPROBES_COPY_INSN;
-+		uprobe->flags |= UPROBE_COPY_INSN;
- 	}
- 	ret = set_bkpt(mm, &uprobe->arch, addr);
- 
-@@ -857,7 +857,7 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
- 			uprobe->consumers = NULL;
- 			__uprobe_unregister(uprobe);
- 		} else {
--			uprobe->flags |= UPROBES_RUN_HANDLER;
-+			uprobe->flags |= UPROBE_RUN_HANDLER;
- 		}
- 	}
- 
-@@ -889,7 +889,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
- 	if (consumer_del(uprobe, consumer)) {
- 		if (!uprobe->consumers) {
- 			__uprobe_unregister(uprobe);
--			uprobe->flags &= ~UPROBES_RUN_HANDLER;
-+			uprobe->flags &= ~UPROBE_RUN_HANDLER;
- 		}
- 	}
- 
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Make-order-of-function-parameters-consi.patch b/features/uprobe/uprobes-core-Make-order-of-function-parameters-consi.patch
deleted file mode 100644
index dc1b0bc594e25409584ba0a27065934751369602..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Make-order-of-function-parameters-consi.patch
+++ /dev/null
@@ -1,439 +0,0 @@
-From c99bc182fd0d61937402f87fdf0a29cc54ab1369 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 12 Mar 2012 14:55:30 +0530
-Subject: [PATCH 09/24] uprobes/core: Make order of function parameters
- consistent across functions
-
-If a function takes struct uprobe or struct arch_uprobe, then it
-is passed as the first parameter.
-
-This is pure cleanup, no functional change intended.
-
-commit e3343e6a2819ff5d0dfc4bb5c9fb7f9a4d04da73 upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120312092530.5379.18394.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/include/asm/uprobes.h |    2 +-
- arch/x86/kernel/uprobes.c      |   15 +++---
- include/linux/uprobes.h        |   12 +++---
- kernel/events/uprobes.c        |   93 ++++++++++++++++++++-------------------
- 4 files changed, 63 insertions(+), 59 deletions(-)
-
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index 5c399e4..384f1be 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -39,5 +39,5 @@ struct arch_uprobe {
- #endif
- };
- 
--extern int arch_uprobes_analyze_insn(struct mm_struct *mm, struct arch_uprobe *arch_uprobe);
-+extern int arch_uprobes_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm);
- #endif	/* _ASM_UPROBES_H */
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index 6dfa89e..851a11b 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -297,7 +297,8 @@ static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn)
-  *  - There's never a SIB byte.
-  *  - The displacement is always 4 bytes.
-  */
--static void handle_riprel_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
-+static void
-+handle_riprel_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn)
- {
- 	u8 *cursor;
- 	u8 reg;
-@@ -381,19 +382,19 @@ static int validate_insn_64bits(struct arch_uprobe *auprobe, struct insn *insn)
- 	return -ENOTSUPP;
- }
- 
--static int validate_insn_bits(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
-+static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn)
- {
- 	if (mm->context.ia32_compat)
- 		return validate_insn_32bits(auprobe, insn);
- 	return validate_insn_64bits(auprobe, insn);
- }
- #else /* 32-bit: */
--static void handle_riprel_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
-+static void handle_riprel_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, struct insn *insn)
- {
- 	/* No RIP-relative addressing on 32-bit */
- }
- 
--static int validate_insn_bits(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
-+static int validate_insn_bits(struct arch_uprobe *auprobe, struct mm_struct *mm,  struct insn *insn)
- {
- 	return validate_insn_32bits(auprobe, insn);
- }
-@@ -405,17 +406,17 @@ static int validate_insn_bits(struct mm_struct *mm, struct arch_uprobe *auprobe,
-  * @arch_uprobe: the probepoint information.
-  * Return 0 on success or a -ve number on error.
-  */
--int arch_uprobes_analyze_insn(struct mm_struct *mm, struct arch_uprobe *auprobe)
-+int arch_uprobes_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm)
- {
- 	int ret;
- 	struct insn insn;
- 
- 	auprobe->fixups = 0;
--	ret = validate_insn_bits(mm, auprobe, &insn);
-+	ret = validate_insn_bits(auprobe, mm, &insn);
- 	if (ret != 0)
- 		return ret;
- 
--	handle_riprel_insn(mm, auprobe, &insn);
-+	handle_riprel_insn(auprobe, mm, &insn);
- 	prepare_fixups(auprobe, &insn);
- 
- 	return 0;
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index 838fb31..5869918 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -52,20 +52,20 @@ struct uprobe_consumer {
- };
- 
- #ifdef CONFIG_UPROBES
--extern int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr);
--extern int __weak set_orig_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr, bool verify);
-+extern int __weak set_bkpt(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
-+extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm,  unsigned long vaddr, bool verify);
- extern bool __weak is_bkpt_insn(uprobe_opcode_t *insn);
--extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer);
--extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer);
-+extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
-+extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern int uprobe_mmap(struct vm_area_struct *vma);
- #else /* CONFIG_UPROBES is not defined */
- static inline int
--uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
-+uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
- {
- 	return -ENOSYS;
- }
- static inline void
--uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
-+uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
- {
- }
- static inline int uprobe_mmap(struct vm_area_struct *vma)
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 0d36bf3..9c5ddff 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -192,8 +192,8 @@ bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
- 
- /*
-  * write_opcode - write the opcode at a given virtual address.
-+ * @auprobe: arch breakpointing information.
-  * @mm: the probed process address space.
-- * @arch_uprobe: the breakpointing information.
-  * @vaddr: the virtual address to store the opcode.
-  * @opcode: opcode to be written at @vaddr.
-  *
-@@ -203,7 +203,7 @@ bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
-  * For mm @mm, write the opcode at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--static int write_opcode(struct mm_struct *mm, struct arch_uprobe *auprobe,
-+static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
- 			unsigned long vaddr, uprobe_opcode_t opcode)
- {
- 	struct page *old_page, *new_page;
-@@ -334,14 +334,14 @@ static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
- 
- /**
-  * set_bkpt - store breakpoint at a given address.
-+ * @auprobe: arch specific probepoint information.
-  * @mm: the probed process address space.
-- * @uprobe: the probepoint information.
-  * @vaddr: the virtual address to insert the opcode.
-  *
-  * For mm @mm, store the breakpoint instruction at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr)
-+int __weak set_bkpt(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
- {
- 	int result;
- 
-@@ -352,13 +352,13 @@ int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned
- 	if (result)
- 		return result;
- 
--	return write_opcode(mm, auprobe, vaddr, UPROBE_BKPT_INSN);
-+	return write_opcode(auprobe, mm, vaddr, UPROBE_BKPT_INSN);
- }
- 
- /**
-  * set_orig_insn - Restore the original instruction.
-  * @mm: the probed process address space.
-- * @uprobe: the probepoint information.
-+ * @auprobe: arch specific probepoint information.
-  * @vaddr: the virtual address to insert the opcode.
-  * @verify: if true, verify existance of breakpoint instruction.
-  *
-@@ -366,7 +366,7 @@ int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned
-  * Return 0 (success) or a negative errno.
-  */
- int __weak
--set_orig_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr, bool verify)
-+set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr, bool verify)
- {
- 	if (verify) {
- 		int result;
-@@ -378,7 +378,7 @@ set_orig_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long v
- 		if (result != 1)
- 			return result;
- 	}
--	return write_opcode(mm, auprobe, vaddr, *(uprobe_opcode_t *)auprobe->insn);
-+	return write_opcode(auprobe, mm, vaddr, *(uprobe_opcode_t *)auprobe->insn);
- }
- 
- static int match_uprobe(struct uprobe *l, struct uprobe *r)
-@@ -525,30 +525,30 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
- 
- /* Returns the previous consumer */
- static struct uprobe_consumer *
--consumer_add(struct uprobe *uprobe, struct uprobe_consumer *consumer)
-+consumer_add(struct uprobe *uprobe, struct uprobe_consumer *uc)
- {
- 	down_write(&uprobe->consumer_rwsem);
--	consumer->next = uprobe->consumers;
--	uprobe->consumers = consumer;
-+	uc->next = uprobe->consumers;
-+	uprobe->consumers = uc;
- 	up_write(&uprobe->consumer_rwsem);
- 
--	return consumer->next;
-+	return uc->next;
- }
- 
- /*
-- * For uprobe @uprobe, delete the consumer @consumer.
-- * Return true if the @consumer is deleted successfully
-+ * For uprobe @uprobe, delete the consumer @uc.
-+ * Return true if the @uc is deleted successfully
-  * or return false.
-  */
--static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *consumer)
-+static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *uc)
- {
- 	struct uprobe_consumer **con;
- 	bool ret = false;
- 
- 	down_write(&uprobe->consumer_rwsem);
- 	for (con = &uprobe->consumers; *con; con = &(*con)->next) {
--		if (*con == consumer) {
--			*con = consumer->next;
-+		if (*con == uc) {
-+			*con = uc->next;
- 			ret = true;
- 			break;
- 		}
-@@ -558,8 +558,8 @@ static bool consumer_del(struct uprobe *uprobe, struct uprobe_consumer *consumer
- 	return ret;
- }
- 
--static int __copy_insn(struct address_space *mapping,
--			struct vm_area_struct *vma, char *insn,
-+static int
-+__copy_insn(struct address_space *mapping, struct vm_area_struct *vma, char *insn,
- 			unsigned long nbytes, unsigned long offset)
- {
- 	struct file *filp = vma->vm_file;
-@@ -590,7 +590,8 @@ static int __copy_insn(struct address_space *mapping,
- 	return 0;
- }
- 
--static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
-+static int
-+copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
- {
- 	struct address_space *mapping;
- 	unsigned long nbytes;
-@@ -617,8 +618,9 @@ static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned
- 	return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset);
- }
- 
--static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
--				struct vm_area_struct *vma, loff_t vaddr)
-+static int
-+install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
-+			struct vm_area_struct *vma, loff_t vaddr)
- {
- 	unsigned long addr;
- 	int ret;
-@@ -643,20 +645,21 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->arch.insn))
- 			return -EEXIST;
- 
--		ret = arch_uprobes_analyze_insn(mm, &uprobe->arch);
-+		ret = arch_uprobes_analyze_insn(&uprobe->arch, mm);
- 		if (ret)
- 			return ret;
- 
- 		uprobe->flags |= UPROBE_COPY_INSN;
- 	}
--	ret = set_bkpt(mm, &uprobe->arch, addr);
-+	ret = set_bkpt(&uprobe->arch, mm, addr);
- 
- 	return ret;
- }
- 
--static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr)
-+static void
-+remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr)
- {
--	set_orig_insn(mm, &uprobe->arch, (unsigned long)vaddr, true);
-+	set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true);
- }
- 
- static void delete_uprobe(struct uprobe *uprobe)
-@@ -671,9 +674,9 @@ static void delete_uprobe(struct uprobe *uprobe)
- 	atomic_dec(&uprobe_events);
- }
- 
--static struct vma_info *__find_next_vma_info(struct list_head *head,
--			loff_t offset, struct address_space *mapping,
--			struct vma_info *vi, bool is_register)
-+static struct vma_info *
-+__find_next_vma_info(struct address_space *mapping, struct list_head *head,
-+			struct vma_info *vi, loff_t offset, bool is_register)
- {
- 	struct prio_tree_iter iter;
- 	struct vm_area_struct *vma;
-@@ -719,8 +722,8 @@ static struct vma_info *__find_next_vma_info(struct list_head *head,
-  * yet been inserted.
-  */
- static struct vma_info *
--find_next_vma_info(struct list_head *head, loff_t offset, struct address_space *mapping,
--		   bool is_register)
-+find_next_vma_info(struct address_space *mapping, struct list_head *head,
-+		loff_t offset, bool is_register)
- {
- 	struct vma_info *vi, *retvi;
- 
-@@ -729,7 +732,7 @@ find_next_vma_info(struct list_head *head, loff_t offset, struct address_space *
- 		return ERR_PTR(-ENOMEM);
- 
- 	mutex_lock(&mapping->i_mmap_mutex);
--	retvi = __find_next_vma_info(head, offset, mapping, vi, is_register);
-+	retvi = __find_next_vma_info(mapping, head, vi, offset, is_register);
- 	mutex_unlock(&mapping->i_mmap_mutex);
- 
- 	if (!retvi)
-@@ -754,7 +757,7 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
- 	ret = 0;
- 
- 	for (;;) {
--		vi = find_next_vma_info(&try_list, uprobe->offset, mapping, is_register);
-+		vi = find_next_vma_info(mapping, &try_list, uprobe->offset, is_register);
- 		if (!vi)
- 			break;
- 
-@@ -784,9 +787,9 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
- 		}
- 
- 		if (is_register)
--			ret = install_breakpoint(mm, uprobe, vma, vi->vaddr);
-+			ret = install_breakpoint(uprobe, mm, vma, vi->vaddr);
- 		else
--			remove_breakpoint(mm, uprobe, vi->vaddr);
-+			remove_breakpoint(uprobe, mm, vi->vaddr);
- 
- 		up_read(&mm->mmap_sem);
- 		mmput(mm);
-@@ -823,25 +826,25 @@ static void __uprobe_unregister(struct uprobe *uprobe)
-  * uprobe_register - register a probe
-  * @inode: the file in which the probe has to be placed.
-  * @offset: offset from the start of the file.
-- * @consumer: information on howto handle the probe..
-+ * @uc: information on howto handle the probe..
-  *
-  * Apart from the access refcount, uprobe_register() takes a creation
-  * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
-  * inserted into the rbtree (i.e first consumer for a @inode:@offset
-  * tuple).  Creation refcount stops uprobe_unregister from freeing the
-  * @uprobe even before the register operation is complete. Creation
-- * refcount is released when the last @consumer for the @uprobe
-+ * refcount is released when the last @uc for the @uprobe
-  * unregisters.
-  *
-  * Return errno if it cannot successully install probes
-  * else return 0 (success)
-  */
--int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
-+int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
- {
- 	struct uprobe *uprobe;
- 	int ret;
- 
--	if (!inode || !consumer || consumer->next)
-+	if (!inode || !uc || uc->next)
- 		return -EINVAL;
- 
- 	if (offset > i_size_read(inode))
-@@ -851,7 +854,7 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
- 	mutex_lock(uprobes_hash(inode));
- 	uprobe = alloc_uprobe(inode, offset);
- 
--	if (uprobe && !consumer_add(uprobe, consumer)) {
-+	if (uprobe && !consumer_add(uprobe, uc)) {
- 		ret = __uprobe_register(uprobe);
- 		if (ret) {
- 			uprobe->consumers = NULL;
-@@ -871,13 +874,13 @@ int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *
-  * uprobe_unregister - unregister a already registered probe.
-  * @inode: the file in which the probe has to be removed.
-  * @offset: offset from the start of the file.
-- * @consumer: identify which probe if multiple probes are colocated.
-+ * @uc: identify which probe if multiple probes are colocated.
-  */
--void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer)
-+void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
- {
- 	struct uprobe *uprobe;
- 
--	if (!inode || !consumer)
-+	if (!inode || !uc)
- 		return;
- 
- 	uprobe = find_uprobe(inode, offset);
-@@ -886,7 +889,7 @@ void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consume
- 
- 	mutex_lock(uprobes_hash(inode));
- 
--	if (consumer_del(uprobe, consumer)) {
-+	if (consumer_del(uprobe, uc)) {
- 		if (!uprobe->consumers) {
- 			__uprobe_unregister(uprobe);
- 			uprobe->flags &= ~UPROBE_RUN_HANDLER;
-@@ -993,7 +996,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
- 		if (!ret) {
- 			vaddr = vma_address(vma, uprobe->offset);
- 			if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
--				ret = install_breakpoint(vma->vm_mm, uprobe, vma, vaddr);
-+				ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
- 				/* Ignore double add: */
- 				if (ret == -EEXIST)
- 					ret = 0;
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Move-insn-to-arch-specific-structure.patch b/features/uprobe/uprobes-core-Move-insn-to-arch-specific-structure.patch
deleted file mode 100644
index 2f0dcf531a82a009376efe3bc8aa6512c3179b3c..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Move-insn-to-arch-specific-structure.patch
+++ /dev/null
@@ -1,418 +0,0 @@
-From f066ff9cd2dc1e58a967f1847c780b90bfdf4a05 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Wed, 22 Feb 2012 14:46:02 +0530
-Subject: [PATCH 06/24] uprobes/core: Move insn to arch specific structure
-
-Few cleanups suggested by Ingo Molnar.
-
-- Rename struct uprobe_arch_info to struct arch_uprobe.
-- Move insn from struct uprobe to struct arch_uprobe.
-- Make arch specific uprobe functions to accept struct arch_uprobe
-  instead of  struct uprobe.
-- Move struct uprobe to kernel/uprobes.c from include/linux/uprobes.h
-
-commit 3ff54efdfaace9e9b2b7c1959a865be6b91de96c upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Jiri Olsa <jolsa@redhat.com>
-Cc: Josh Stone <jistone@redhat.com>
-Link: http://lkml.kernel.org/r/20120222091602.15880.40249.sendpatchset@srdronam.in.ibm.com
-[ Made various small improvements ]
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/include/asm/uprobes.h |    6 ++--
- arch/x86/kernel/uprobes.c      |   60 ++++++++++++++++++++--------------------
- include/linux/uprobes.h        |   23 +--------------
- kernel/events/uprobes.c        |   38 +++++++++++++++++--------
- 4 files changed, 61 insertions(+), 66 deletions(-)
-
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index 072df39..f7ce310 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -31,13 +31,13 @@ typedef u8 uprobe_opcode_t;
- #define UPROBES_BKPT_INSN		0xcc
- #define UPROBES_BKPT_INSN_SIZE		   1
- 
--struct uprobe_arch_info {
-+struct arch_uprobe {
- 	u16				fixups;
-+	u8				insn[MAX_UINSN_BYTES];
- #ifdef CONFIG_X86_64
- 	unsigned long			rip_rela_target_address;
- #endif
- };
- 
--struct uprobe;
--extern int arch_uprobes_analyze_insn(struct mm_struct *mm, struct uprobe *uprobe);
-+extern int arch_uprobes_analyze_insn(struct mm_struct *mm, struct arch_uprobe *arch_uprobe);
- #endif	/* _ASM_UPROBES_H */
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-index 13d616d..04dfcef 100644
---- a/arch/x86/kernel/uprobes.c
-+++ b/arch/x86/kernel/uprobes.c
-@@ -200,9 +200,9 @@ static bool is_prefix_bad(struct insn *insn)
- 	return false;
- }
- 
--static int validate_insn_32bits(struct uprobe *uprobe, struct insn *insn)
-+static int validate_insn_32bits(struct arch_uprobe *auprobe, struct insn *insn)
- {
--	insn_init(insn, uprobe->insn, false);
-+	insn_init(insn, auprobe->insn, false);
- 
- 	/* Skip good instruction prefixes; reject "bad" ones. */
- 	insn_get_opcode(insn);
-@@ -222,11 +222,11 @@ static int validate_insn_32bits(struct uprobe *uprobe, struct insn *insn)
- 
- /*
-  * Figure out which fixups post_xol() will need to perform, and annotate
-- * uprobe->arch_info.fixups accordingly.  To start with,
-- * uprobe->arch_info.fixups is either zero or it reflects rip-related
-+ * arch_uprobe->fixups accordingly.  To start with,
-+ * arch_uprobe->fixups is either zero or it reflects rip-related
-  * fixups.
-  */
--static void prepare_fixups(struct uprobe *uprobe, struct insn *insn)
-+static void prepare_fixups(struct arch_uprobe *auprobe, struct insn *insn)
- {
- 	bool fix_ip = true, fix_call = false;	/* defaults */
- 	int reg;
-@@ -269,17 +269,17 @@ static void prepare_fixups(struct uprobe *uprobe, struct insn *insn)
- 		break;
- 	}
- 	if (fix_ip)
--		uprobe->arch_info.fixups |= UPROBES_FIX_IP;
-+		auprobe->fixups |= UPROBES_FIX_IP;
- 	if (fix_call)
--		uprobe->arch_info.fixups |= UPROBES_FIX_CALL;
-+		auprobe->fixups |= UPROBES_FIX_CALL;
- }
- 
- #ifdef CONFIG_X86_64
- /*
-- * If uprobe->insn doesn't use rip-relative addressing, return
-+ * If arch_uprobe->insn doesn't use rip-relative addressing, return
-  * immediately.  Otherwise, rewrite the instruction so that it accesses
-  * its memory operand indirectly through a scratch register.  Set
-- * uprobe->arch_info.fixups and uprobe->arch_info.rip_rela_target_address
-+ * arch_uprobe->fixups and arch_uprobe->rip_rela_target_address
-  * accordingly.  (The contents of the scratch register will be saved
-  * before we single-step the modified instruction, and restored
-  * afterward.)
-@@ -297,7 +297,7 @@ static void prepare_fixups(struct uprobe *uprobe, struct insn *insn)
-  *  - There's never a SIB byte.
-  *  - The displacement is always 4 bytes.
-  */
--static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
-+static void handle_riprel_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
- {
- 	u8 *cursor;
- 	u8 reg;
-@@ -305,7 +305,7 @@ static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, stru
- 	if (mm->context.ia32_compat)
- 		return;
- 
--	uprobe->arch_info.rip_rela_target_address = 0x0;
-+	auprobe->rip_rela_target_address = 0x0;
- 	if (!insn_rip_relative(insn))
- 		return;
- 
-@@ -315,7 +315,7 @@ static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, stru
- 	 * we want to encode rax/rcx, not r8/r9.
- 	 */
- 	if (insn->rex_prefix.nbytes) {
--		cursor = uprobe->insn + insn_offset_rex_prefix(insn);
-+		cursor = auprobe->insn + insn_offset_rex_prefix(insn);
- 		*cursor &= 0xfe;	/* Clearing REX.B bit */
- 	}
- 
-@@ -324,7 +324,7 @@ static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, stru
- 	 * displacement.  Beyond the displacement, for some instructions,
- 	 * is the immediate operand.
- 	 */
--	cursor = uprobe->insn + insn_offset_modrm(insn);
-+	cursor = auprobe->insn + insn_offset_modrm(insn);
- 	insn_get_length(insn);
- 
- 	/*
-@@ -341,18 +341,18 @@ static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, stru
- 		 * is NOT the register operand, so we use %rcx (register
- 		 * #1) for the scratch register.
- 		 */
--		uprobe->arch_info.fixups = UPROBES_FIX_RIP_CX;
-+		auprobe->fixups = UPROBES_FIX_RIP_CX;
- 		/* Change modrm from 00 000 101 to 00 000 001. */
- 		*cursor = 0x1;
- 	} else {
- 		/* Use %rax (register #0) for the scratch register. */
--		uprobe->arch_info.fixups = UPROBES_FIX_RIP_AX;
-+		auprobe->fixups = UPROBES_FIX_RIP_AX;
- 		/* Change modrm from 00 xxx 101 to 00 xxx 000 */
- 		*cursor = (reg << 3);
- 	}
- 
- 	/* Target address = address of next instruction + (signed) offset */
--	uprobe->arch_info.rip_rela_target_address = (long)insn->length + insn->displacement.value;
-+	auprobe->rip_rela_target_address = (long)insn->length + insn->displacement.value;
- 
- 	/* Displacement field is gone; slide immediate field (if any) over. */
- 	if (insn->immediate.nbytes) {
-@@ -362,9 +362,9 @@ static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, stru
- 	return;
- }
- 
--static int validate_insn_64bits(struct uprobe *uprobe, struct insn *insn)
-+static int validate_insn_64bits(struct arch_uprobe *auprobe, struct insn *insn)
- {
--	insn_init(insn, uprobe->insn, true);
-+	insn_init(insn, auprobe->insn, true);
- 
- 	/* Skip good instruction prefixes; reject "bad" ones. */
- 	insn_get_opcode(insn);
-@@ -381,42 +381,42 @@ static int validate_insn_64bits(struct uprobe *uprobe, struct insn *insn)
- 	return -ENOTSUPP;
- }
- 
--static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
-+static int validate_insn_bits(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
- {
- 	if (mm->context.ia32_compat)
--		return validate_insn_32bits(uprobe, insn);
--	return validate_insn_64bits(uprobe, insn);
-+		return validate_insn_32bits(auprobe, insn);
-+	return validate_insn_64bits(auprobe, insn);
- }
- #else /* 32-bit: */
--static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
-+static void handle_riprel_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
- {
- 	/* No RIP-relative addressing on 32-bit */
- }
- 
--static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe, struct insn *insn)
-+static int validate_insn_bits(struct mm_struct *mm, struct arch_uprobe *auprobe, struct insn *insn)
- {
--	return validate_insn_32bits(uprobe, insn);
-+	return validate_insn_32bits(auprobe, insn);
- }
- #endif /* CONFIG_X86_64 */
- 
- /**
-  * arch_uprobes_analyze_insn - instruction analysis including validity and fixups.
-  * @mm: the probed address space.
-- * @uprobe: the probepoint information.
-+ * @arch_uprobe: the probepoint information.
-  * Return 0 on success or a -ve number on error.
-  */
--int arch_uprobes_analyze_insn(struct mm_struct *mm, struct uprobe *uprobe)
-+int arch_uprobes_analyze_insn(struct mm_struct *mm, struct arch_uprobe *auprobe)
- {
- 	int ret;
- 	struct insn insn;
- 
--	uprobe->arch_info.fixups = 0;
--	ret = validate_insn_bits(mm, uprobe, &insn);
-+	auprobe->fixups = 0;
-+	ret = validate_insn_bits(mm, auprobe, &insn);
- 	if (ret != 0)
- 		return ret;
- 
--	handle_riprel_insn(mm, uprobe, &insn);
--	prepare_fixups(uprobe, &insn);
-+	handle_riprel_insn(mm, auprobe, &insn);
-+	prepare_fixups(auprobe, &insn);
- 
- 	return 0;
- }
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index fd45b70..9c6be62 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -29,12 +29,6 @@
- struct vm_area_struct;
- #ifdef CONFIG_ARCH_SUPPORTS_UPROBES
- #include <asm/uprobes.h>
--#else
--
--typedef u8 uprobe_opcode_t;
--struct uprobe_arch_info {};
--
--#define MAX_UINSN_BYTES 4
- #endif
- 
- /* flags that denote/change uprobes behaviour */
-@@ -56,22 +50,9 @@ struct uprobe_consumer {
- 	struct uprobe_consumer *next;
- };
- 
--struct uprobe {
--	struct rb_node		rb_node;	/* node in the rb tree */
--	atomic_t		ref;
--	struct rw_semaphore	consumer_rwsem;
--	struct list_head	pending_list;
--	struct uprobe_arch_info arch_info;
--	struct uprobe_consumer	*consumers;
--	struct inode		*inode;		/* Also hold a ref to inode */
--	loff_t			offset;
--	int			flags;
--	u8			insn[MAX_UINSN_BYTES];
--};
--
- #ifdef CONFIG_UPROBES
--extern int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr);
--extern int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify);
-+extern int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr);
-+extern int __weak set_orig_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr, bool verify);
- extern bool __weak is_bkpt_insn(uprobe_opcode_t *insn);
- extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer);
- extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *consumer);
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index ee496ad..13f1b59 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -65,6 +65,18 @@ struct vma_info {
- 	loff_t			vaddr;
- };
- 
-+struct uprobe {
-+	struct rb_node		rb_node;	/* node in the rb tree */
-+	atomic_t		ref;
-+	struct rw_semaphore	consumer_rwsem;
-+	struct list_head	pending_list;
-+	struct uprobe_consumer	*consumers;
-+	struct inode		*inode;		/* Also hold a ref to inode */
-+	loff_t			offset;
-+	int			flags;
-+	struct arch_uprobe	arch;
-+};
-+
- /*
-  * valid_vma: Verify if the specified vma is an executable vma
-  * Relax restrictions while unregistering: vm_flags might have
-@@ -180,7 +192,7 @@ bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
- /*
-  * write_opcode - write the opcode at a given virtual address.
-  * @mm: the probed process address space.
-- * @uprobe: the breakpointing information.
-+ * @arch_uprobe: the breakpointing information.
-  * @vaddr: the virtual address to store the opcode.
-  * @opcode: opcode to be written at @vaddr.
-  *
-@@ -190,13 +202,14 @@ bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
-  * For mm @mm, write the opcode at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
-+static int write_opcode(struct mm_struct *mm, struct arch_uprobe *auprobe,
- 			unsigned long vaddr, uprobe_opcode_t opcode)
- {
- 	struct page *old_page, *new_page;
- 	struct address_space *mapping;
- 	void *vaddr_old, *vaddr_new;
- 	struct vm_area_struct *vma;
-+	struct uprobe *uprobe;
- 	loff_t addr;
- 	int ret;
- 
-@@ -216,6 +229,7 @@ static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
- 	if (!valid_vma(vma, is_bkpt_insn(&opcode)))
- 		goto put_out;
- 
-+	uprobe = container_of(auprobe, struct uprobe, arch);
- 	mapping = uprobe->inode->i_mapping;
- 	if (mapping != vma->vm_file->f_mapping)
- 		goto put_out;
-@@ -326,7 +340,7 @@ static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
-  * For mm @mm, store the breakpoint instruction at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr)
-+int __weak set_bkpt(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr)
- {
- 	int result;
- 
-@@ -337,7 +351,7 @@ int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long v
- 	if (result)
- 		return result;
- 
--	return write_opcode(mm, uprobe, vaddr, UPROBES_BKPT_INSN);
-+	return write_opcode(mm, auprobe, vaddr, UPROBES_BKPT_INSN);
- }
- 
- /**
-@@ -351,7 +365,7 @@ int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe, unsigned long v
-  * Return 0 (success) or a negative errno.
-  */
- int __weak
--set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr, bool verify)
-+set_orig_insn(struct mm_struct *mm, struct arch_uprobe *auprobe, unsigned long vaddr, bool verify)
- {
- 	if (verify) {
- 		int result;
-@@ -363,7 +377,7 @@ set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe, unsigned long vaddr,
- 		if (result != 1)
- 			return result;
- 	}
--	return write_opcode(mm, uprobe, vaddr, *(uprobe_opcode_t *)uprobe->insn);
-+	return write_opcode(mm, auprobe, vaddr, *(uprobe_opcode_t *)auprobe->insn);
- }
- 
- static int match_uprobe(struct uprobe *l, struct uprobe *r)
-@@ -593,13 +607,13 @@ static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned
- 
- 	/* Instruction at the page-boundary; copy bytes in second page */
- 	if (nbytes < bytes) {
--		if (__copy_insn(mapping, vma, uprobe->insn + nbytes,
-+		if (__copy_insn(mapping, vma, uprobe->arch.insn + nbytes,
- 				bytes - nbytes, uprobe->offset + nbytes))
- 			return -ENOMEM;
- 
- 		bytes = nbytes;
- 	}
--	return __copy_insn(mapping, vma, uprobe->insn, bytes, uprobe->offset);
-+	return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset);
- }
- 
- static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
-@@ -625,23 +639,23 @@ static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
- 		if (ret)
- 			return ret;
- 
--		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn))
-+		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->arch.insn))
- 			return -EEXIST;
- 
--		ret = arch_uprobes_analyze_insn(mm, uprobe);
-+		ret = arch_uprobes_analyze_insn(mm, &uprobe->arch);
- 		if (ret)
- 			return ret;
- 
- 		uprobe->flags |= UPROBES_COPY_INSN;
- 	}
--	ret = set_bkpt(mm, uprobe, addr);
-+	ret = set_bkpt(mm, &uprobe->arch, addr);
- 
- 	return ret;
- }
- 
- static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe, loff_t vaddr)
- {
--	set_orig_insn(mm, uprobe, (unsigned long)vaddr, true);
-+	set_orig_insn(mm, &uprobe->arch, (unsigned long)vaddr, true);
- }
- 
- static void delete_uprobe(struct uprobe *uprobe)
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Optimize-probe-hits-with-the-help-of-a-.patch b/features/uprobe/uprobes-core-Optimize-probe-hits-with-the-help-of-a-.patch
deleted file mode 100644
index 229b44f2992cc1c61d6c143d7ab38344aeeb08b2..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Optimize-probe-hits-with-the-help-of-a-.patch
+++ /dev/null
@@ -1,334 +0,0 @@
-From 3efc15b8288e32ad40ce0f45b7e9a40c43f9f048 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Fri, 30 Mar 2012 23:56:46 +0530
-Subject: [PATCH 13/24] uprobes/core: Optimize probe hits with the help of a
- counter
-
-Maintain a per-mm counter: number of uprobes that are inserted
-on this process address space.
-
-This counter can be used at probe hit time to determine if we
-need a lookup in the uprobes rbtree. Everytime a probe gets
-inserted successfully, the probe count is incremented and
-everytime a probe gets removed, the probe count is decremented.
-
-The new uprobe_munmap hook ensures the count is correct on a
-unmap or remap of a region. We expect that once a
-uprobe_munmap() is called, the vma goes away.  So
-uprobe_unregister() finding a probe to unregister would either
-mean unmap event hasnt occurred yet or a mmap event on the same
-executable file occured after a unmap event.
-
-Additionally, uprobe_mmap hook now also gets called:
-
- a. on every executable vma that is COWed at fork.
- b. a vma of interest is newly mapped; breakpoint insertion also
-    happens at the required address.
-
-On process creation, make sure the probes count in the child is
-set correctly.
-
-Special cases that are taken care include:
-
- a. mremap
- b. VM_DONTCOPY vmas on fork()
- c. insertion/removal races in the parent during fork().
-
-commit 682968e0c425c60f0dde37977e5beb2b12ddc4cc upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120330182646.10018.85805.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@kernel.org>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/uprobes.h |    5 ++
- kernel/events/uprobes.c |  119 +++++++++++++++++++++++++++++++++++++++++++---
- kernel/fork.c           |    3 +
- mm/mmap.c               |   10 ++++-
- 4 files changed, 128 insertions(+), 9 deletions(-)
-
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index a111460..d594d3b 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -99,6 +99,7 @@ struct xol_area {
- 
- struct uprobes_state {
- 	struct xol_area		*xol_area;
-+	atomic_t		count;
- };
- extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
- extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm,  unsigned long vaddr, bool verify);
-@@ -106,6 +107,7 @@ extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
- extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern int uprobe_mmap(struct vm_area_struct *vma);
-+extern void uprobe_munmap(struct vm_area_struct *vma);
- extern void uprobe_free_utask(struct task_struct *t);
- extern void uprobe_copy_process(struct task_struct *t);
- extern unsigned long __weak uprobe_get_swbp_addr(struct pt_regs *regs);
-@@ -132,6 +134,9 @@ static inline int uprobe_mmap(struct vm_area_struct *vma)
- {
- 	return 0;
- }
-+static inline void uprobe_munmap(struct vm_area_struct *vma)
-+{
-+}
- static inline void uprobe_notify_resume(struct pt_regs *regs)
- {
- }
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index b395edb..29e881b 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -642,6 +642,29 @@ copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma, unsigned long addr)
- 	return __copy_insn(mapping, vma, uprobe->arch.insn, bytes, uprobe->offset);
- }
- 
-+/*
-+ * How mm->uprobes_state.count gets updated
-+ * uprobe_mmap() increments the count if
-+ * 	- it successfully adds a breakpoint.
-+ * 	- it cannot add a breakpoint, but sees that there is a underlying
-+ * 	  breakpoint (via a is_swbp_at_addr()).
-+ *
-+ * uprobe_munmap() decrements the count if
-+ * 	- it sees a underlying breakpoint, (via is_swbp_at_addr)
-+ * 	  (Subsequent uprobe_unregister wouldnt find the breakpoint
-+ * 	  unless a uprobe_mmap kicks in, since the old vma would be
-+ * 	  dropped just after uprobe_munmap.)
-+ *
-+ * uprobe_register increments the count if:
-+ * 	- it successfully adds a breakpoint.
-+ *
-+ * uprobe_unregister decrements the count if:
-+ * 	- it sees a underlying breakpoint and removes successfully.
-+ * 	  (via is_swbp_at_addr)
-+ * 	  (Subsequent uprobe_munmap wouldnt find the breakpoint
-+ * 	  since there is no underlying breakpoint after the
-+ * 	  breakpoint removal.)
-+ */
- static int
- install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- 			struct vm_area_struct *vma, loff_t vaddr)
-@@ -675,7 +698,19 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- 
- 		uprobe->flags |= UPROBE_COPY_INSN;
- 	}
-+
-+	/*
-+	 * Ideally, should be updating the probe count after the breakpoint
-+	 * has been successfully inserted. However a thread could hit the
-+	 * breakpoint we just inserted even before the probe count is
-+	 * incremented. If this is the first breakpoint placed, breakpoint
-+	 * notifier might ignore uprobes and pass the trap to the thread.
-+	 * Hence increment before and decrement on failure.
-+	 */
-+	atomic_inc(&mm->uprobes_state.count);
- 	ret = set_swbp(&uprobe->arch, mm, addr);
-+	if (ret)
-+		atomic_dec(&mm->uprobes_state.count);
- 
- 	return ret;
- }
-@@ -683,7 +718,8 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- static void
- remove_breakpoint(struct uprobe *uprobe, struct mm_struct *mm, loff_t vaddr)
- {
--	set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true);
-+	if (!set_orig_insn(&uprobe->arch, mm, (unsigned long)vaddr, true))
-+		atomic_dec(&mm->uprobes_state.count);
- }
- 
- /*
-@@ -1009,7 +1045,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
- 	struct list_head tmp_list;
- 	struct uprobe *uprobe, *u;
- 	struct inode *inode;
--	int ret;
-+	int ret, count;
- 
- 	if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
- 		return 0;
-@@ -1023,6 +1059,7 @@ int uprobe_mmap(struct vm_area_struct *vma)
- 	build_probe_list(inode, &tmp_list);
- 
- 	ret = 0;
-+	count = 0;
- 
- 	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
- 		loff_t vaddr;
-@@ -1030,21 +1067,85 @@ int uprobe_mmap(struct vm_area_struct *vma)
- 		list_del(&uprobe->pending_list);
- 		if (!ret) {
- 			vaddr = vma_address(vma, uprobe->offset);
--			if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
--				ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
--				/* Ignore double add: */
--				if (ret == -EEXIST)
--					ret = 0;
-+
-+			if (vaddr < vma->vm_start || vaddr >= vma->vm_end) {
-+				put_uprobe(uprobe);
-+				continue;
- 			}
-+
-+			ret = install_breakpoint(uprobe, vma->vm_mm, vma, vaddr);
-+
-+			/* Ignore double add: */
-+			if (ret == -EEXIST) {
-+				ret = 0;
-+
-+				if (!is_swbp_at_addr(vma->vm_mm, vaddr))
-+					continue;
-+
-+				/*
-+				 * Unable to insert a breakpoint, but
-+				 * breakpoint lies underneath. Increment the
-+				 * probe count.
-+				 */
-+				atomic_inc(&vma->vm_mm->uprobes_state.count);
-+			}
-+
-+			if (!ret)
-+				count++;
- 		}
- 		put_uprobe(uprobe);
- 	}
- 
- 	mutex_unlock(uprobes_mmap_hash(inode));
- 
-+	if (ret)
-+		atomic_sub(count, &vma->vm_mm->uprobes_state.count);
-+
- 	return ret;
- }
- 
-+/*
-+ * Called in context of a munmap of a vma.
-+ */
-+void uprobe_munmap(struct vm_area_struct *vma)
-+{
-+	struct list_head tmp_list;
-+	struct uprobe *uprobe, *u;
-+	struct inode *inode;
-+
-+	if (!atomic_read(&uprobe_events) || !valid_vma(vma, false))
-+		return;
-+
-+	if (!atomic_read(&vma->vm_mm->uprobes_state.count))
-+		return;
-+
-+	inode = vma->vm_file->f_mapping->host;
-+	if (!inode)
-+		return;
-+
-+	INIT_LIST_HEAD(&tmp_list);
-+	mutex_lock(uprobes_mmap_hash(inode));
-+	build_probe_list(inode, &tmp_list);
-+
-+	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
-+		loff_t vaddr;
-+
-+		list_del(&uprobe->pending_list);
-+		vaddr = vma_address(vma, uprobe->offset);
-+
-+		if (vaddr >= vma->vm_start && vaddr < vma->vm_end) {
-+			/*
-+			 * An unregister could have removed the probe before
-+			 * unmap. So check before we decrement the count.
-+			 */
-+			if (is_swbp_at_addr(vma->vm_mm, vaddr) == 1)
-+				atomic_dec(&vma->vm_mm->uprobes_state.count);
-+		}
-+		put_uprobe(uprobe);
-+	}
-+	mutex_unlock(uprobes_mmap_hash(inode));
-+}
-+
- /* Slot allocation for XOL */
- static int xol_add_vma(struct xol_area *area)
- {
-@@ -1150,6 +1251,7 @@ void uprobe_clear_state(struct mm_struct *mm)
- void uprobe_reset_state(struct mm_struct *mm)
- {
- 	mm->uprobes_state.xol_area = NULL;
-+	atomic_set(&mm->uprobes_state.count, 0);
- }
- 
- /*
-@@ -1504,7 +1606,8 @@ int uprobe_pre_sstep_notifier(struct pt_regs *regs)
- {
- 	struct uprobe_task *utask;
- 
--	if (!current->mm)
-+	if (!current->mm || !atomic_read(&current->mm->uprobes_state.count))
-+		/* task is currently not uprobed */
- 		return 0;
- 
- 	utask = current->utask;
-diff --git a/kernel/fork.c b/kernel/fork.c
-index 5fa2cbf..764efe3 100644
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -426,6 +426,9 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
- 
- 		if (retval)
- 			goto out;
-+
-+		if (file && uprobe_mmap(tmp))
-+			goto out;
- 	}
- 	/* a new mm has just been created */
- 	arch_dup_mmap(oldmm, mm);
-diff --git a/mm/mmap.c b/mm/mmap.c
-index 397bcb5..b0b1691 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -218,6 +218,7 @@ void unlink_file_vma(struct vm_area_struct *vma)
- 		mutex_lock(&mapping->i_mmap_mutex);
- 		__remove_shared_vm_struct(vma, file, mapping);
- 		mutex_unlock(&mapping->i_mmap_mutex);
-+		uprobe_munmap(vma);
- 	}
- }
- 
-@@ -547,8 +548,14 @@ again:			remove_next = 1 + (end > next->vm_end);
- 
- 	if (file) {
- 		mapping = file->f_mapping;
--		if (!(vma->vm_flags & VM_NONLINEAR))
-+		if (!(vma->vm_flags & VM_NONLINEAR)) {
- 			root = &mapping->i_mmap;
-+			uprobe_munmap(vma);
-+
-+			if (adjust_next)
-+				uprobe_munmap(next);
-+		}
-+
- 		mutex_lock(&mapping->i_mmap_mutex);
- 		if (insert) {
- 			/*
-@@ -627,6 +634,7 @@ again:			remove_next = 1 + (end > next->vm_end);
- 
- 	if (remove_next) {
- 		if (file) {
-+			uprobe_munmap(next);
- 			fput(file);
- 			if (next->vm_flags & VM_EXECUTABLE)
- 				removed_exe_file_vma(mm);
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Remove-uprobe_opcode_sz.patch b/features/uprobe/uprobes-core-Remove-uprobe_opcode_sz.patch
deleted file mode 100644
index 2880a171629414825735c1c081ff1db6464bf903..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Remove-uprobe_opcode_sz.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-From e91cf65d77f259c00ecf8e345004dff2e6c4f67a Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Wed, 22 Feb 2012 14:45:49 +0530
-Subject: [PATCH 05/24] uprobes/core: Remove uprobe_opcode_sz
-
-uprobe_opcode_sz refers to the smallest instruction size for
-that architecture. UPROBES_BKPT_INSN_SIZE refers to the size of
-the breakpoint instruction for that architecture.
-
-For now we are assuming that both uprobe_opcode_sz and
-UPROBES_BKPT_INSN_SIZE are the same for all archs and hence
-removing uprobe_opcode_sz in favour of UPROBES_BKPT_INSN_SIZE.
-
-However if we have to support architectures where the smallest
-instruction size is different from the size of breakpoint
-instruction, we may have to re-introduce uprobe_opcode_sz.
-
-commit 96379f60075c75b261328aa7830ef8aa158247ac upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Jiri Olsa <jolsa@redhat.com>
-Cc: Josh Stone <jistone@redhat.com>
-Link: http://lkml.kernel.org/r/20120222091549.15880.67020.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- include/linux/uprobes.h |    2 --
- kernel/events/uprobes.c |    6 +++---
- 2 files changed, 3 insertions(+), 5 deletions(-)
-
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index 64e45f1..fd45b70 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -37,8 +37,6 @@ struct uprobe_arch_info {};
- #define MAX_UINSN_BYTES 4
- #endif
- 
--#define uprobe_opcode_sz sizeof(uprobe_opcode_t)
--
- /* flags that denote/change uprobes behaviour */
- 
- /* Have a copy of original instruction */
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 884817f..ee496ad 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -244,8 +244,8 @@ static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
- 
- 	/* poke the new insn in, ASSUMES we don't cross page boundary */
- 	vaddr &= ~PAGE_MASK;
--	BUG_ON(vaddr + uprobe_opcode_sz > PAGE_SIZE);
--	memcpy(vaddr_new + vaddr, &opcode, uprobe_opcode_sz);
-+	BUG_ON(vaddr + UPROBES_BKPT_INSN_SIZE > PAGE_SIZE);
-+	memcpy(vaddr_new + vaddr, &opcode, UPROBES_BKPT_INSN_SIZE);
- 
- 	kunmap_atomic(vaddr_new);
- 	kunmap_atomic(vaddr_old);
-@@ -293,7 +293,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_
- 	lock_page(page);
- 	vaddr_new = kmap_atomic(page);
- 	vaddr &= ~PAGE_MASK;
--	memcpy(opcode, vaddr_new + vaddr, uprobe_opcode_sz);
-+	memcpy(opcode, vaddr_new + vaddr, UPROBES_BKPT_INSN_SIZE);
- 	kunmap_atomic(vaddr_new);
- 	unlock_page(page);
- 
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-core-Rename-bkpt-to-swbp.patch b/features/uprobe/uprobes-core-Rename-bkpt-to-swbp.patch
deleted file mode 100644
index 4453ed1094d0e9949c1cc5cbe02a1bf881514c93..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-core-Rename-bkpt-to-swbp.patch
+++ /dev/null
@@ -1,195 +0,0 @@
-From 7196d9a3a208e63063325b5c91fbeae703e5b5f3 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Mon, 12 Mar 2012 14:55:45 +0530
-Subject: [PATCH 10/24] uprobes/core: Rename bkpt to swbp
-
-bkpt doesnt seem to be a correct abbrevation for breakpoint.
-Choice was between bp and breakpoint. Since bp can refer to
-things other than breakpoint, use swbp to refer to breakpoints.
-
-This is pure cleanup, no functional change intended.
-
-commit 5cb4ac3a583d4ee18c8682ab857e093c4a0d0895 upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Jim Keniston <jkenisto@linux.vnet.ibm.com>
-Cc: Linux-mm <linux-mm@kvack.org>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Link: http://lkml.kernel.org/r/20120312092545.5379.91251.sendpatchset@srdronam.in.ibm.com
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/x86/include/asm/uprobes.h |    4 ++--
- include/linux/uprobes.h        |    4 ++--
- kernel/events/uprobes.c        |   34 +++++++++++++++++-----------------
- 3 files changed, 21 insertions(+), 21 deletions(-)
-
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-index 384f1be..0500391 100644
---- a/arch/x86/include/asm/uprobes.h
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -28,8 +28,8 @@ typedef u8 uprobe_opcode_t;
- #define MAX_UINSN_BYTES			  16
- #define UPROBE_XOL_SLOT_BYTES		 128	/* to keep it cache aligned */
- 
--#define UPROBE_BKPT_INSN		0xcc
--#define UPROBE_BKPT_INSN_SIZE		   1
-+#define UPROBE_SWBP_INSN		0xcc
-+#define UPROBE_SWBP_INSN_SIZE		   1
- 
- struct arch_uprobe {
- 	u16				fixups;
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-index 5869918..eac525f 100644
---- a/include/linux/uprobes.h
-+++ b/include/linux/uprobes.h
-@@ -52,9 +52,9 @@ struct uprobe_consumer {
- };
- 
- #ifdef CONFIG_UPROBES
--extern int __weak set_bkpt(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
-+extern int __weak set_swbp(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long vaddr);
- extern int __weak set_orig_insn(struct arch_uprobe *aup, struct mm_struct *mm,  unsigned long vaddr, bool verify);
--extern bool __weak is_bkpt_insn(uprobe_opcode_t *insn);
-+extern bool __weak is_swbp_insn(uprobe_opcode_t *insn);
- extern int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern void uprobe_unregister(struct inode *inode, loff_t offset, struct uprobe_consumer *uc);
- extern int uprobe_mmap(struct vm_area_struct *vma);
-diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c
-index 9c5ddff..e56e56a 100644
---- a/kernel/events/uprobes.c
-+++ b/kernel/events/uprobes.c
-@@ -170,14 +170,14 @@ out:
- }
- 
- /**
-- * is_bkpt_insn - check if instruction is breakpoint instruction.
-+ * is_swbp_insn - check if instruction is breakpoint instruction.
-  * @insn: instruction to be checked.
-- * Default implementation of is_bkpt_insn
-+ * Default implementation of is_swbp_insn
-  * Returns true if @insn is a breakpoint instruction.
-  */
--bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
-+bool __weak is_swbp_insn(uprobe_opcode_t *insn)
- {
--	return *insn == UPROBE_BKPT_INSN;
-+	return *insn == UPROBE_SWBP_INSN;
- }
- 
- /*
-@@ -227,7 +227,7 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
- 	 * adding probes in write mapped pages since the breakpoints
- 	 * might end up in the file copy.
- 	 */
--	if (!valid_vma(vma, is_bkpt_insn(&opcode)))
-+	if (!valid_vma(vma, is_swbp_insn(&opcode)))
- 		goto put_out;
- 
- 	uprobe = container_of(auprobe, struct uprobe, arch);
-@@ -259,8 +259,8 @@ static int write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm,
- 
- 	/* poke the new insn in, ASSUMES we don't cross page boundary */
- 	vaddr &= ~PAGE_MASK;
--	BUG_ON(vaddr + UPROBE_BKPT_INSN_SIZE > PAGE_SIZE);
--	memcpy(vaddr_new + vaddr, &opcode, UPROBE_BKPT_INSN_SIZE);
-+	BUG_ON(vaddr + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE);
-+	memcpy(vaddr_new + vaddr, &opcode, UPROBE_SWBP_INSN_SIZE);
- 
- 	kunmap_atomic(vaddr_new);
- 	kunmap_atomic(vaddr_old);
-@@ -308,7 +308,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_
- 	lock_page(page);
- 	vaddr_new = kmap_atomic(page);
- 	vaddr &= ~PAGE_MASK;
--	memcpy(opcode, vaddr_new + vaddr, UPROBE_BKPT_INSN_SIZE);
-+	memcpy(opcode, vaddr_new + vaddr, UPROBE_SWBP_INSN_SIZE);
- 	kunmap_atomic(vaddr_new);
- 	unlock_page(page);
- 
-@@ -317,7 +317,7 @@ static int read_opcode(struct mm_struct *mm, unsigned long vaddr, uprobe_opcode_
- 	return 0;
- }
- 
--static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
-+static int is_swbp_at_addr(struct mm_struct *mm, unsigned long vaddr)
- {
- 	uprobe_opcode_t opcode;
- 	int result;
-@@ -326,14 +326,14 @@ static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
- 	if (result)
- 		return result;
- 
--	if (is_bkpt_insn(&opcode))
-+	if (is_swbp_insn(&opcode))
- 		return 1;
- 
- 	return 0;
- }
- 
- /**
-- * set_bkpt - store breakpoint at a given address.
-+ * set_swbp - store breakpoint at a given address.
-  * @auprobe: arch specific probepoint information.
-  * @mm: the probed process address space.
-  * @vaddr: the virtual address to insert the opcode.
-@@ -341,18 +341,18 @@ static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
-  * For mm @mm, store the breakpoint instruction at @vaddr.
-  * Return 0 (success) or a negative errno.
-  */
--int __weak set_bkpt(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
-+int __weak set_swbp(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long vaddr)
- {
- 	int result;
- 
--	result = is_bkpt_at_addr(mm, vaddr);
-+	result = is_swbp_at_addr(mm, vaddr);
- 	if (result == 1)
- 		return -EEXIST;
- 
- 	if (result)
- 		return result;
- 
--	return write_opcode(auprobe, mm, vaddr, UPROBE_BKPT_INSN);
-+	return write_opcode(auprobe, mm, vaddr, UPROBE_SWBP_INSN);
- }
- 
- /**
-@@ -371,7 +371,7 @@ set_orig_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, unsigned long v
- 	if (verify) {
- 		int result;
- 
--		result = is_bkpt_at_addr(mm, vaddr);
-+		result = is_swbp_at_addr(mm, vaddr);
- 		if (!result)
- 			return -EINVAL;
- 
-@@ -642,7 +642,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- 		if (ret)
- 			return ret;
- 
--		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->arch.insn))
-+		if (is_swbp_insn((uprobe_opcode_t *)uprobe->arch.insn))
- 			return -EEXIST;
- 
- 		ret = arch_uprobes_analyze_insn(&uprobe->arch, mm);
-@@ -651,7 +651,7 @@ install_breakpoint(struct uprobe *uprobe, struct mm_struct *mm,
- 
- 		uprobe->flags |= UPROBE_COPY_INSN;
- 	}
--	ret = set_bkpt(&uprobe->arch, mm, addr);
-+	ret = set_swbp(&uprobe->arch, mm, addr);
- 
- 	return ret;
- }
--- 
-1.7.5.4
-
diff --git a/features/uprobe/uprobes-mm-x86-Add-the-ability-to-install-and-remove.patch b/features/uprobe/uprobes-mm-x86-Add-the-ability-to-install-and-remove.patch
deleted file mode 100644
index 84c75480b7396047660359d16e5564fcf1e8342f..0000000000000000000000000000000000000000
--- a/features/uprobe/uprobes-mm-x86-Add-the-ability-to-install-and-remove.patch
+++ /dev/null
@@ -1,1883 +0,0 @@
-From 3760d62e72e4c63e47a58cc199b7b260799faa86 Mon Sep 17 00:00:00 2001
-From: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Date: Thu, 9 Feb 2012 14:56:42 +0530
-Subject: [PATCH 01/24] uprobes, mm, x86: Add the ability to install and
- remove uprobes breakpoints
-
-Add uprobes support to the core kernel, with x86 support.
-
-This commit adds the kernel facilities, the actual uprobes
-user-space ABI and perf probe support comes in later commits.
-
-General design:
-
-Uprobes are maintained in an rb-tree indexed by inode and offset
-(the offset here is from the start of the mapping). For a unique
-(inode, offset) tuple, there can be at most one uprobe in the
-rb-tree.
-
-Since the (inode, offset) tuple identifies a unique uprobe, more
-than one user may be interested in the same uprobe. This provides
-the ability to connect multiple 'consumers' to the same uprobe.
-
-Each consumer defines a handler and a filter (optional). The
-'handler' is run every time the uprobe is hit, if it matches the
-'filter' criteria.
-
-The first consumer of a uprobe causes the breakpoint to be
-inserted at the specified address and subsequent consumers are
-appended to this list.  On subsequent probes, the consumer gets
-appended to the existing list of consumers. The breakpoint is
-removed when the last consumer unregisters. For all other
-unregisterations, the consumer is removed from the list of
-consumers.
-
-Given a inode, we get a list of the mms that have mapped the
-inode. Do the actual registration if mm maps the page where a
-probe needs to be inserted/removed.
-
-We use a temporary list to walk through the vmas that map the
-inode.
-
-- The number of maps that map the inode, is not known before we
-  walk the rmap and keeps changing.
-- extending vm_area_struct wasn't recommended, it's a
-  size-critical data structure.
-- There can be more than one maps of the inode in the same mm.
-
-We add callbacks to the mmap methods to keep an eye on text vmas
-that are of interest to uprobes.  When a vma of interest is mapped,
-we insert the breakpoint at the right address.
-
-Uprobe works by replacing the instruction at the address defined
-by (inode, offset) with the arch specific breakpoint
-instruction. We save a copy of the original instruction at the
-uprobed address.
-
-This is needed for:
-
- a. executing the instruction out-of-line (xol).
- b. instruction analysis for any subsequent fixups.
- c. restoring the instruction back when the uprobe is unregistered.
-
-We insert or delete a breakpoint instruction, and this
-breakpoint instruction is assumed to be the smallest instruction
-available on the platform. For fixed size instruction platforms
-this is trivially true, for variable size instruction platforms
-the breakpoint instruction is typically the smallest (often a
-single byte).
-
-Writing the instruction is done by COWing the page and changing
-the instruction during the copy, this even though most platforms
-allow atomic writes of the breakpoint instruction. This also
-mirrors the behaviour of a ptrace() memory write to a PRIVATE
-file map.
-
-The core worker is derived from KSM's replace_page() logic.
-
-In essence, similar to KSM:
-
- a. allocate a new page and copy over contents of the page that
-    has the uprobed vaddr
- b. modify the copy and insert the breakpoint at the required
-    address
- c. switch the original page with the copy containing the
-    breakpoint
- d. flush page tables.
-
-replace_page() is being replicated here because of some minor
-changes in the type of pages and also because Hugh Dickins had
-plans to improve replace_page() for KSM specific work.
-
-Instruction analysis on x86 is based on instruction decoder and
-determines if an instruction can be probed and determines the
-necessary fixups after singlestep.  Instruction analysis is done
-at probe insertion time so that we avoid having to repeat the
-same analysis every time a probe is hit.
-
-A lot of code here is due to the improvement/suggestions/inputs
-from Peter Zijlstra.
-
-Changelog:
-
-(v10):
- - Add code to clear REX.B prefix as suggested by Denys Vlasenko
-   and Masami Hiramatsu.
-
-(v9):
- - Use insn_offset_modrm as suggested by Masami Hiramatsu.
-
-(v7):
-
- Handle comments from Peter Zijlstra:
-
- - Dont take reference to inode. (expect inode to uprobe_register to be sane).
- - Use PTR_ERR to set the return value.
- - No need to take reference to inode.
- - use PTR_ERR to return error value.
- - register and uprobe_unregister share code.
-
-(v5):
-
- - Modified del_consumer as per comments from Peter.
- - Drop reference to inode before dropping reference to uprobe.
- - Use i_size_read(inode) instead of inode->i_size.
- - Ensure uprobe->consumers is NULL, before __uprobe_unregister() is called.
- - Includes errno.h as recommended by Stephen Rothwell to fix a build issue
-   on sparc defconfig
- - Remove restrictions while unregistering.
- - Earlier code leaked inode references under some conditions while
-   registering/unregistering.
- - Continue the vma-rmap walk even if the intermediate vma doesnt
-   meet the requirements.
- - Validate the vma found by find_vma before inserting/removing the
-   breakpoint
- - Call del_consumer under mutex_lock.
- - Use hash locks.
- - Handle mremap.
- - Introduce find_least_offset_node() instead of close match logic in
-   find_uprobe
- - Uprobes no more depends on MM_OWNER; No reference to task_structs
-   while inserting/removing a probe.
- - Uses read_mapping_page instead of grab_cache_page so that the pages
-   have valid content.
- - pass NULL to get_user_pages for the task parameter.
- - call SetPageUptodate on the new page allocated in write_opcode.
- - fix leaking a reference to the new page under certain conditions.
- - Include Instruction Decoder if Uprobes gets defined.
- - Remove const attributes for instruction prefix arrays.
- - Uses mm_context to know if the application is 32 bit.
-
-commit 2b144498350860b6ee9dc57ff27a93ad488de5dc upstream
-
-Signed-off-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
-Also-written-by: Jim Keniston <jkenisto@us.ibm.com>
-Reviewed-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
-Cc: Oleg Nesterov <oleg@redhat.com>
-Cc: Andi Kleen <andi@firstfloor.org>
-Cc: Christoph Hellwig <hch@infradead.org>
-Cc: Steven Rostedt <rostedt@goodmis.org>
-Cc: Roland McGrath <roland@hack.frob.com>
-Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
-Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
-Cc: Anton Arapov <anton@redhat.com>
-Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-Cc: Stephen Rothwell <sfr@canb.auug.org.au>
-Cc: Denys Vlasenko <vda.linux@googlemail.com>
-Cc: Peter Zijlstra <peterz@infradead.org>
-Cc: Linus Torvalds <torvalds@linux-foundation.org>
-Cc: Andrew Morton <akpm@linux-foundation.org>
-Cc: Linux-mm <linux-mm@kvack.org>
-Link: http://lkml.kernel.org/r/20120209092642.GE16600@linux.vnet.ibm.com
-[ Made various small edits to the commit log ]
-Signed-off-by: Ingo Molnar <mingo@elte.hu>
-Signed-off-by: Paul Barrette <paul.barrette@windriver.com>
----
- arch/Kconfig                   |   11 +
- arch/x86/Kconfig               |    5 +-
- arch/x86/include/asm/uprobes.h |   42 ++
- arch/x86/kernel/Makefile       |    1 +
- arch/x86/kernel/uprobes.c      |  412 +++++++++++++++++
- include/linux/uprobes.h        |   98 ++++
- kernel/Makefile                |    1 +
- kernel/uprobes.c               |  976 ++++++++++++++++++++++++++++++++++++++++
- mm/mmap.c                      |   23 +
- 9 files changed, 1568 insertions(+), 1 deletions(-)
- create mode 100644 arch/x86/include/asm/uprobes.h
- create mode 100644 arch/x86/kernel/uprobes.c
- create mode 100644 include/linux/uprobes.h
- create mode 100644 kernel/uprobes.c
-
-diff --git a/arch/Kconfig b/arch/Kconfig
-index c024b3e..5083bf2 100644
---- a/arch/Kconfig
-+++ b/arch/Kconfig
-@@ -76,6 +76,17 @@ config OPTPROBES
- 	depends on KPROBES && HAVE_OPTPROBES
- 	depends on !PREEMPT
- 
-+config UPROBES
-+	bool "User-space probes (EXPERIMENTAL)"
-+	depends on ARCH_SUPPORTS_UPROBES
-+	default n
-+	help
-+	  Uprobes enables kernel subsystems to establish probepoints
-+	  in user applications and execute handler functions when
-+	  the probepoints are hit.
-+
-+	  If in doubt, say "N".
-+
- config HAVE_EFFICIENT_UNALIGNED_ACCESS
- 	bool
- 	help
-diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
-index 2b79d94..fb0c234 100644
---- a/arch/x86/Kconfig
-+++ b/arch/x86/Kconfig
-@@ -85,7 +85,7 @@ config X86
- 	select HAVE_ARCH_SECCOMP_FILTER
- 
- config INSTRUCTION_DECODER
--	def_bool (KPROBES || PERF_EVENTS)
-+	def_bool (KPROBES || PERF_EVENTS || UPROBES)
- 
- config OUTPUT_FORMAT
- 	string
-@@ -244,6 +244,9 @@ config ARCH_CPU_PROBE_RELEASE
- 	def_bool y
- 	depends on HOTPLUG_CPU
- 
-+config ARCH_SUPPORTS_UPROBES
-+	def_bool y
-+
- source "init/Kconfig"
- source "kernel/Kconfig.freezer"
- 
-diff --git a/arch/x86/include/asm/uprobes.h b/arch/x86/include/asm/uprobes.h
-new file mode 100644
-index 0000000..8208234
---- /dev/null
-+++ b/arch/x86/include/asm/uprobes.h
-@@ -0,0 +1,42 @@
-+#ifndef _ASM_UPROBES_H
-+#define _ASM_UPROBES_H
-+/*
-+ * Userspace Probes (UProbes) for x86
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2008-2011
-+ * Authors:
-+ *	Srikar Dronamraju
-+ *	Jim Keniston
-+ */
-+
-+typedef u8 uprobe_opcode_t;
-+#define MAX_UINSN_BYTES 16
-+#define UPROBES_XOL_SLOT_BYTES	128	/* to keep it cache aligned */
-+
-+#define UPROBES_BKPT_INSN 0xcc
-+#define UPROBES_BKPT_INSN_SIZE 1
-+
-+struct uprobe_arch_info {
-+	u16			fixups;
-+#ifdef CONFIG_X86_64
-+	unsigned long rip_rela_target_address;
-+#endif
-+};
-+
-+struct uprobe;
-+extern int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe);
-+#endif	/* _ASM_UPROBES_H */
-diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
-index 532d2e0..d23d835 100644
---- a/arch/x86/kernel/Makefile
-+++ b/arch/x86/kernel/Makefile
-@@ -101,6 +101,7 @@ obj-$(CONFIG_X86_CHECK_BIOS_CORRUPTION) += check.o
- 
- obj-$(CONFIG_SWIOTLB)			+= pci-swiotlb.o
- obj-$(CONFIG_OF)			+= devicetree.o
-+obj-$(CONFIG_UPROBES)			+= uprobes.o
- 
- ###
- # 64 bit specific files
-diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
-new file mode 100644
-index 0000000..2a301bb
---- /dev/null
-+++ b/arch/x86/kernel/uprobes.c
-@@ -0,0 +1,412 @@
-+/*
-+ * Userspace Probes (UProbes) for x86
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2008-2011
-+ * Authors:
-+ *	Srikar Dronamraju
-+ *	Jim Keniston
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/ptrace.h>
-+#include <linux/uprobes.h>
-+
-+#include <linux/kdebug.h>
-+#include <asm/insn.h>
-+
-+/* Post-execution fixups. */
-+
-+/* No fixup needed */
-+#define UPROBES_FIX_NONE	0x0
-+/* Adjust IP back to vicinity of actual insn */
-+#define UPROBES_FIX_IP		0x1
-+/* Adjust the return address of a call insn */
-+#define UPROBES_FIX_CALL	0x2
-+
-+#define UPROBES_FIX_RIP_AX	0x8000
-+#define UPROBES_FIX_RIP_CX	0x4000
-+
-+/* Adaptations for mhiramat x86 decoder v14. */
-+#define OPCODE1(insn) ((insn)->opcode.bytes[0])
-+#define OPCODE2(insn) ((insn)->opcode.bytes[1])
-+#define OPCODE3(insn) ((insn)->opcode.bytes[2])
-+#define MODRM_REG(insn) X86_MODRM_REG(insn->modrm.value)
-+
-+#define W(row, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, ba, bb, bc, bd, be, bf)\
-+	(((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) |   \
-+	  (b4##UL << 0x4)|(b5##UL << 0x5)|(b6##UL << 0x6)|(b7##UL << 0x7) |   \
-+	  (b8##UL << 0x8)|(b9##UL << 0x9)|(ba##UL << 0xa)|(bb##UL << 0xb) |   \
-+	  (bc##UL << 0xc)|(bd##UL << 0xd)|(be##UL << 0xe)|(bf##UL << 0xf))    \
-+	 << (row % 32))
-+
-+#ifdef CONFIG_X86_64
-+static volatile u32 good_insns_64[256 / 32] = {
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+	/*      ----------------------------------------------         */
-+	W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */
-+	W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */
-+	W(0x20, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 20 */
-+	W(0x30, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 30 */
-+	W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */
-+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
-+	W(0x60, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
-+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
-+	W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
-+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
-+	W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
-+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
-+	W(0xc0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
-+	W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
-+	W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
-+	W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1)   /* f0 */
-+	/*      ----------------------------------------------         */
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+};
-+#endif
-+
-+/* Good-instruction tables for 32-bit apps */
-+
-+static volatile u32 good_insns_32[256 / 32] = {
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+	/*      ----------------------------------------------         */
-+	W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 00 */
-+	W(0x10, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 10 */
-+	W(0x20, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) | /* 20 */
-+	W(0x30, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) , /* 30 */
-+	W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
-+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
-+	W(0x60, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
-+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
-+	W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
-+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
-+	W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
-+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
-+	W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
-+	W(0xd0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
-+	W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
-+	W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1)   /* f0 */
-+	/*      ----------------------------------------------         */
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+};
-+
-+/* Using this for both 64-bit and 32-bit apps */
-+static volatile u32 good_2byte_insns[256 / 32] = {
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+	/*      ----------------------------------------------         */
-+	W(0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1) | /* 00 */
-+	W(0x10, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1) , /* 10 */
-+	W(0x20, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 20 */
-+	W(0x30, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) , /* 30 */
-+	W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
-+	W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
-+	W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 60 */
-+	W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1) , /* 70 */
-+	W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
-+	W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
-+	W(0xa0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1) | /* a0 */
-+	W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
-+	W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* c0 */
-+	W(0xd0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
-+	W(0xe0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* e0 */
-+	W(0xf0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)   /* f0 */
-+	/*      ----------------------------------------------         */
-+	/*      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f         */
-+};
-+
-+#undef W
-+
-+/*
-+ * opcodes we'll probably never support:
-+ * 6c-6d, e4-e5, ec-ed - in
-+ * 6e-6f, e6-e7, ee-ef - out
-+ * cc, cd - int3, int
-+ * cf - iret
-+ * d6 - illegal instruction
-+ * f1 - int1/icebp
-+ * f4 - hlt
-+ * fa, fb - cli, sti
-+ * 0f - lar, lsl, syscall, clts, sysret, sysenter, sysexit, invd, wbinvd, ud2
-+ *
-+ * invalid opcodes in 64-bit mode:
-+ * 06, 0e, 16, 1e, 27, 2f, 37, 3f, 60-62, 82, c4-c5, d4-d5
-+ *
-+ * 63 - we support this opcode in x86_64 but not in i386.
-+ *
-+ * opcodes we may need to refine support for:
-+ * 0f - 2-byte instructions: For many of these instructions, the validity
-+ * depends on the prefix and/or the reg field.  On such instructions, we
-+ * just consider the opcode combination valid if it corresponds to any
-+ * valid instruction.
-+ * 8f - Group 1 - only reg = 0 is OK
-+ * c6-c7 - Group 11 - only reg = 0 is OK
-+ * d9-df - fpu insns with some illegal encodings
-+ * f2, f3 - repnz, repz prefixes.  These are also the first byte for
-+ * certain floating-point instructions, such as addsd.
-+ * fe - Group 4 - only reg = 0 or 1 is OK
-+ * ff - Group 5 - only reg = 0-6 is OK
-+ *
-+ * others -- Do we need to support these?
-+ * 0f - (floating-point?) prefetch instructions
-+ * 07, 17, 1f - pop es, pop ss, pop ds
-+ * 26, 2e, 36, 3e - es:, cs:, ss:, ds: segment prefixes --
-+ *	but 64 and 65 (fs: and gs:) seem to be used, so we support them
-+ * 67 - addr16 prefix
-+ * ce - into
-+ * f0 - lock prefix
-+ */
-+
-+/*
-+ * TODO:
-+ * - Where necessary, examine the modrm byte and allow only valid instructions
-+ * in the different Groups and fpu instructions.
-+ */
-+
-+static bool is_prefix_bad(struct insn *insn)
-+{
-+	int i;
-+
-+	for (i = 0; i < insn->prefixes.nbytes; i++) {
-+		switch (insn->prefixes.bytes[i]) {
-+		case 0x26:	/*INAT_PFX_ES   */
-+		case 0x2E:	/*INAT_PFX_CS   */
-+		case 0x36:	/*INAT_PFX_DS   */
-+		case 0x3E:	/*INAT_PFX_SS   */
-+		case 0xF0:	/*INAT_PFX_LOCK */
-+			return true;
-+		}
-+	}
-+	return false;
-+}
-+
-+static int validate_insn_32bits(struct uprobe *uprobe, struct insn *insn)
-+{
-+	insn_init(insn, uprobe->insn, false);
-+
-+	/* Skip good instruction prefixes; reject "bad" ones. */
-+	insn_get_opcode(insn);
-+	if (is_prefix_bad(insn))
-+		return -ENOTSUPP;
-+	if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_32))
-+		return 0;
-+	if (insn->opcode.nbytes == 2) {
-+		if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
-+			return 0;
-+	}
-+	return -ENOTSUPP;
-+}
-+
-+/*
-+ * Figure out which fixups post_xol() will need to perform, and annotate
-+ * uprobe->arch_info.fixups accordingly.  To start with,
-+ * uprobe->arch_info.fixups is either zero or it reflects rip-related
-+ * fixups.
-+ */
-+static void prepare_fixups(struct uprobe *uprobe, struct insn *insn)
-+{
-+	bool fix_ip = true, fix_call = false;	/* defaults */
-+	int reg;
-+
-+	insn_get_opcode(insn);	/* should be a nop */
-+
-+	switch (OPCODE1(insn)) {
-+	case 0xc3:		/* ret/lret */
-+	case 0xcb:
-+	case 0xc2:
-+	case 0xca:
-+		/* ip is correct */
-+		fix_ip = false;
-+		break;
-+	case 0xe8:		/* call relative - Fix return addr */
-+		fix_call = true;
-+		break;
-+	case 0x9a:		/* call absolute - Fix return addr, not ip */
-+		fix_call = true;
-+		fix_ip = false;
-+		break;
-+	case 0xff:
-+		insn_get_modrm(insn);
-+		reg = MODRM_REG(insn);
-+		if (reg == 2 || reg == 3) {
-+			/* call or lcall, indirect */
-+			/* Fix return addr; ip is correct. */
-+			fix_call = true;
-+			fix_ip = false;
-+		} else if (reg == 4 || reg == 5) {
-+			/* jmp or ljmp, indirect */
-+			/* ip is correct. */
-+			fix_ip = false;
-+		}
-+		break;
-+	case 0xea:		/* jmp absolute -- ip is correct */
-+		fix_ip = false;
-+		break;
-+	default:
-+		break;
-+	}
-+	if (fix_ip)
-+		uprobe->arch_info.fixups |= UPROBES_FIX_IP;
-+	if (fix_call)
-+		uprobe->arch_info.fixups |= UPROBES_FIX_CALL;
-+}
-+
-+#ifdef CONFIG_X86_64
-+/*
-+ * If uprobe->insn doesn't use rip-relative addressing, return
-+ * immediately.  Otherwise, rewrite the instruction so that it accesses
-+ * its memory operand indirectly through a scratch register.  Set
-+ * uprobe->arch_info.fixups and uprobe->arch_info.rip_rela_target_address
-+ * accordingly.  (The contents of the scratch register will be saved
-+ * before we single-step the modified instruction, and restored
-+ * afterward.)
-+ *
-+ * We do this because a rip-relative instruction can access only a
-+ * relatively small area (+/- 2 GB from the instruction), and the XOL
-+ * area typically lies beyond that area.  At least for instructions
-+ * that store to memory, we can't execute the original instruction
-+ * and "fix things up" later, because the misdirected store could be
-+ * disastrous.
-+ *
-+ * Some useful facts about rip-relative instructions:
-+ * - There's always a modrm byte.
-+ * - There's never a SIB byte.
-+ * - The displacement is always 4 bytes.
-+ */
-+static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
-+							struct insn *insn)
-+{
-+	u8 *cursor;
-+	u8 reg;
-+
-+	if (mm->context.ia32_compat)
-+		return;
-+
-+	uprobe->arch_info.rip_rela_target_address = 0x0;
-+	if (!insn_rip_relative(insn))
-+		return;
-+
-+	/*
-+	 * insn_rip_relative() would have decoded rex_prefix, modrm.
-+	 * Clear REX.b bit (extension of MODRM.rm field):
-+	 * we want to encode rax/rcx, not r8/r9.
-+	 */
-+	if (insn->rex_prefix.nbytes) {
-+		cursor = uprobe->insn + insn_offset_rex_prefix(insn);
-+		*cursor &= 0xfe;	/* Clearing REX.B bit */
-+	}
-+
-+	/*
-+	 * Point cursor at the modrm byte.  The next 4 bytes are the
-+	 * displacement.  Beyond the displacement, for some instructions,
-+	 * is the immediate operand.
-+	 */
-+	cursor = uprobe->insn + insn_offset_modrm(insn);
-+	insn_get_length(insn);
-+
-+	/*
-+	 * Convert from rip-relative addressing to indirect addressing
-+	 * via a scratch register.  Change the r/m field from 0x5 (%rip)
-+	 * to 0x0 (%rax) or 0x1 (%rcx), and squeeze out the offset field.
-+	 */
-+	reg = MODRM_REG(insn);
-+	if (reg == 0) {
-+		/*
-+		 * The register operand (if any) is either the A register
-+		 * (%rax, %eax, etc.) or (if the 0x4 bit is set in the
-+		 * REX prefix) %r8.  In any case, we know the C register
-+		 * is NOT the register operand, so we use %rcx (register
-+		 * #1) for the scratch register.
-+		 */
-+		uprobe->arch_info.fixups = UPROBES_FIX_RIP_CX;
-+		/* Change modrm from 00 000 101 to 00 000 001. */
-+		*cursor = 0x1;
-+	} else {
-+		/* Use %rax (register #0) for the scratch register. */
-+		uprobe->arch_info.fixups = UPROBES_FIX_RIP_AX;
-+		/* Change modrm from 00 xxx 101 to 00 xxx 000 */
-+		*cursor = (reg << 3);
-+	}
-+
-+	/* Target address = address of next instruction + (signed) offset */
-+	uprobe->arch_info.rip_rela_target_address = (long)insn->length
-+					+ insn->displacement.value;
-+	/* Displacement field is gone; slide immediate field (if any) over. */
-+	if (insn->immediate.nbytes) {
-+		cursor++;
-+		memmove(cursor, cursor + insn->displacement.nbytes,
-+						insn->immediate.nbytes);
-+	}
-+	return;
-+}
-+
-+static int validate_insn_64bits(struct uprobe *uprobe, struct insn *insn)
-+{
-+	insn_init(insn, uprobe->insn, true);
-+
-+	/* Skip good instruction prefixes; reject "bad" ones. */
-+	insn_get_opcode(insn);
-+	if (is_prefix_bad(insn))
-+		return -ENOTSUPP;
-+	if (test_bit(OPCODE1(insn), (unsigned long *)good_insns_64))
-+		return 0;
-+	if (insn->opcode.nbytes == 2) {
-+		if (test_bit(OPCODE2(insn), (unsigned long *)good_2byte_insns))
-+			return 0;
-+	}
-+	return -ENOTSUPP;
-+}
-+
-+static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe,
-+				struct insn *insn)
-+{
-+	if (mm->context.ia32_compat)
-+		return validate_insn_32bits(uprobe, insn);
-+	return validate_insn_64bits(uprobe, insn);
-+}
-+#else
-+static void handle_riprel_insn(struct mm_struct *mm, struct uprobe *uprobe,
-+							struct insn *insn)
-+{
-+	return;
-+}
-+
-+static int validate_insn_bits(struct mm_struct *mm, struct uprobe *uprobe,
-+				struct insn *insn)
-+{
-+	return validate_insn_32bits(uprobe, insn);
-+}
-+#endif /* CONFIG_X86_64 */
-+
-+/**
-+ * analyze_insn - instruction analysis including validity and fixups.
-+ * @mm: the probed address space.
-+ * @uprobe: the probepoint information.
-+ * Return 0 on success or a -ve number on error.
-+ */
-+int analyze_insn(struct mm_struct *mm, struct uprobe *uprobe)
-+{
-+	int ret;
-+	struct insn insn;
-+
-+	uprobe->arch_info.fixups = 0;
-+	ret = validate_insn_bits(mm, uprobe, &insn);
-+	if (ret != 0)
-+		return ret;
-+	handle_riprel_insn(mm, uprobe, &insn);
-+	prepare_fixups(uprobe, &insn);
-+	return 0;
-+}
-diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h
-new file mode 100644
-index 0000000..f1d13fd
---- /dev/null
-+++ b/include/linux/uprobes.h
-@@ -0,0 +1,98 @@
-+#ifndef _LINUX_UPROBES_H
-+#define _LINUX_UPROBES_H
-+/*
-+ * Userspace Probes (UProbes)
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2008-2011
-+ * Authors:
-+ *	Srikar Dronamraju
-+ *	Jim Keniston
-+ */
-+
-+#include <linux/errno.h>
-+#include <linux/rbtree.h>
-+
-+struct vm_area_struct;
-+#ifdef CONFIG_ARCH_SUPPORTS_UPROBES
-+#include <asm/uprobes.h>
-+#else
-+
-+typedef u8 uprobe_opcode_t;
-+struct uprobe_arch_info {};
-+
-+#define MAX_UINSN_BYTES 4
-+#endif
-+
-+#define uprobe_opcode_sz sizeof(uprobe_opcode_t)
-+
-+/* flags that denote/change uprobes behaviour */
-+/* Have a copy of original instruction */
-+#define UPROBES_COPY_INSN	0x1
-+/* Dont run handlers when first register/ last unregister in progress*/
-+#define UPROBES_RUN_HANDLER	0x2
-+
-+struct uprobe_consumer {
-+	int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs);
-+	/*
-+	 * filter is optional; If a filter exists, handler is run
-+	 * if and only if filter returns true.
-+	 */
-+	bool (*filter)(struct uprobe_consumer *self, struct task_struct *task);
-+
-+	struct uprobe_consumer *next;
-+};
-+
-+struct uprobe {
-+	struct rb_node		rb_node;	/* node in the rb tree */
-+	atomic_t		ref;
-+	struct rw_semaphore	consumer_rwsem;
-+	struct list_head	pending_list;
-+	struct uprobe_arch_info arch_info;
-+	struct uprobe_consumer	*consumers;
-+	struct inode		*inode;		/* Also hold a ref to inode */
-+	loff_t			offset;
-+	int			flags;
-+	u8			insn[MAX_UINSN_BYTES];
-+};
-+
-+#ifdef CONFIG_UPROBES
-+extern int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
-+							unsigned long vaddr);
-+extern int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe,
-+					unsigned long vaddr, bool verify);
-+extern bool __weak is_bkpt_insn(uprobe_opcode_t *insn);
-+extern int register_uprobe(struct inode *inode, loff_t offset,
-+				struct uprobe_consumer *consumer);
-+extern void unregister_uprobe(struct inode *inode, loff_t offset,
-+				struct uprobe_consumer *consumer);
-+extern int mmap_uprobe(struct vm_area_struct *vma);
-+#else /* CONFIG_UPROBES is not defined */
-+static inline int register_uprobe(struct inode *inode, loff_t offset,
-+				struct uprobe_consumer *consumer)
-+{
-+	return -ENOSYS;
-+}
-+static inline void unregister_uprobe(struct inode *inode, loff_t offset,
-+				struct uprobe_consumer *consumer)
-+{
-+}
-+static inline int mmap_uprobe(struct vm_area_struct *vma)
-+{
-+	return 0;
-+}
-+#endif /* CONFIG_UPROBES */
-+#endif	/* _LINUX_UPROBES_H */
-diff --git a/kernel/Makefile b/kernel/Makefile
-index 633b548..72ea789 100644
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -107,6 +107,7 @@ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
- obj-$(CONFIG_PADATA) += padata.o
- obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
- obj-$(CONFIG_JUMP_LABEL) += jump_label.o
-+obj-$(CONFIG_UPROBES) += uprobes.o
- 
- $(obj)/configs.o: $(obj)/config_data.h
- 
-diff --git a/kernel/uprobes.c b/kernel/uprobes.c
-new file mode 100644
-index 0000000..72e8bb3
---- /dev/null
-+++ b/kernel/uprobes.c
-@@ -0,0 +1,976 @@
-+/*
-+ * Userspace Probes (UProbes)
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that 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.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+ *
-+ * Copyright (C) IBM Corporation, 2008-2011
-+ * Authors:
-+ *	Srikar Dronamraju
-+ *	Jim Keniston
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/highmem.h>
-+#include <linux/pagemap.h>	/* read_mapping_page */
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/rmap.h>		/* anon_vma_prepare */
-+#include <linux/mmu_notifier.h>	/* set_pte_at_notify */
-+#include <linux/swap.h>		/* try_to_free_swap */
-+#include <linux/uprobes.h>
-+
-+static struct rb_root uprobes_tree = RB_ROOT;
-+static DEFINE_SPINLOCK(uprobes_treelock);	/* serialize rbtree access */
-+
-+#define UPROBES_HASH_SZ	13
-+/* serialize (un)register */
-+static struct mutex uprobes_mutex[UPROBES_HASH_SZ];
-+#define uprobes_hash(v)	(&uprobes_mutex[((unsigned long)(v)) %\
-+						UPROBES_HASH_SZ])
-+
-+/* serialize uprobe->pending_list */
-+static struct mutex uprobes_mmap_mutex[UPROBES_HASH_SZ];
-+#define uprobes_mmap_hash(v)	(&uprobes_mmap_mutex[((unsigned long)(v)) %\
-+						UPROBES_HASH_SZ])
-+
-+/*
-+ * uprobe_events allows us to skip the mmap_uprobe if there are no uprobe
-+ * events active at this time.  Probably a fine grained per inode count is
-+ * better?
-+ */
-+static atomic_t uprobe_events = ATOMIC_INIT(0);
-+
-+/*
-+ * Maintain a temporary per vma info that can be used to search if a vma
-+ * has already been handled. This structure is introduced since extending
-+ * vm_area_struct wasnt recommended.
-+ */
-+struct vma_info {
-+	struct list_head probe_list;
-+	struct mm_struct *mm;
-+	loff_t vaddr;
-+};
-+
-+/*
-+ * valid_vma: Verify if the specified vma is an executable vma
-+ * Relax restrictions while unregistering: vm_flags might have
-+ * changed after breakpoint was inserted.
-+ *	- is_register: indicates if we are in register context.
-+ *	- Return 1 if the specified virtual address is in an
-+ *	  executable vma.
-+ */
-+static bool valid_vma(struct vm_area_struct *vma, bool is_register)
-+{
-+	if (!vma->vm_file)
-+		return false;
-+
-+	if (!is_register)
-+		return true;
-+
-+	if ((vma->vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)) ==
-+						(VM_READ|VM_EXEC))
-+		return true;
-+
-+	return false;
-+}
-+
-+static loff_t vma_address(struct vm_area_struct *vma, loff_t offset)
-+{
-+	loff_t vaddr;
-+
-+	vaddr = vma->vm_start + offset;
-+	vaddr -= vma->vm_pgoff << PAGE_SHIFT;
-+	return vaddr;
-+}
-+
-+/**
-+ * __replace_page - replace page in vma by new page.
-+ * based on replace_page in mm/ksm.c
-+ *
-+ * @vma:      vma that holds the pte pointing to page
-+ * @page:     the cowed page we are replacing by kpage
-+ * @kpage:    the modified page we replace page by
-+ *
-+ * Returns 0 on success, -EFAULT on failure.
-+ */
-+static int __replace_page(struct vm_area_struct *vma, struct page *page,
-+					struct page *kpage)
-+{
-+	struct mm_struct *mm = vma->vm_mm;
-+	pgd_t *pgd;
-+	pud_t *pud;
-+	pmd_t *pmd;
-+	pte_t *ptep;
-+	spinlock_t *ptl;
-+	unsigned long addr;
-+	int err = -EFAULT;
-+
-+	addr = page_address_in_vma(page, vma);
-+	if (addr == -EFAULT)
-+		goto out;
-+
-+	pgd = pgd_offset(mm, addr);
-+	if (!pgd_present(*pgd))
-+		goto out;
-+
-+	pud = pud_offset(pgd, addr);
-+	if (!pud_present(*pud))
-+		goto out;
-+
-+	pmd = pmd_offset(pud, addr);
-+	if (!pmd_present(*pmd))
-+		goto out;
-+
-+	ptep = pte_offset_map_lock(mm, pmd, addr, &ptl);
-+	if (!ptep)
-+		goto out;
-+
-+	get_page(kpage);
-+	page_add_new_anon_rmap(kpage, vma, addr);
-+
-+	flush_cache_page(vma, addr, pte_pfn(*ptep));
-+	ptep_clear_flush(vma, addr, ptep);
-+	set_pte_at_notify(mm, addr, ptep, mk_pte(kpage, vma->vm_page_prot));
-+
-+	page_remove_rmap(page);
-+	if (!page_mapped(page))
-+		try_to_free_swap(page);
-+	put_page(page);
-+	pte_unmap_unlock(ptep, ptl);
-+	err = 0;
-+
-+out:
-+	return err;
-+}
-+
-+/**
-+ * is_bkpt_insn - check if instruction is breakpoint instruction.
-+ * @insn: instruction to be checked.
-+ * Default implementation of is_bkpt_insn
-+ * Returns true if @insn is a breakpoint instruction.
-+ */
-+bool __weak is_bkpt_insn(uprobe_opcode_t *insn)
-+{
-+	return (*insn == UPROBES_BKPT_INSN);
-+}
-+
-+/*
-+ * NOTE:
-+ * Expect the breakpoint instruction to be the smallest size instruction for
-+ * the architecture. If an arch has variable length instruction and the
-+ * breakpoint instruction is not of the smallest length instruction
-+ * supported by that architecture then we need to modify read_opcode /
-+ * write_opcode accordingly. This would never be a problem for archs that
-+ * have fixed length instructions.
-+ */
-+
-+/*
-+ * write_opcode - write the opcode at a given virtual address.
-+ * @mm: the probed process address space.
-+ * @uprobe: the breakpointing information.
-+ * @vaddr: the virtual address to store the opcode.
-+ * @opcode: opcode to be written at @vaddr.
-+ *
-+ * Called with mm->mmap_sem held (for read and with a reference to
-+ * mm).
-+ *
-+ * For mm @mm, write the opcode at @vaddr.
-+ * Return 0 (success) or a negative errno.
-+ */
-+static int write_opcode(struct mm_struct *mm, struct uprobe *uprobe,
-+			unsigned long vaddr, uprobe_opcode_t opcode)
-+{
-+	struct page *old_page, *new_page;
-+	struct address_space *mapping;
-+	void *vaddr_old, *vaddr_new;
-+	struct vm_area_struct *vma;
-+	loff_t addr;
-+	int ret;
-+
-+	/* Read the page with vaddr into memory */
-+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &old_page, &vma);
-+	if (ret <= 0)
-+		return ret;
-+	ret = -EINVAL;
-+
-+	/*
-+	 * We are interested in text pages only. Our pages of interest
-+	 * should be mapped for read and execute only. We desist from
-+	 * adding probes in write mapped pages since the breakpoints
-+	 * might end up in the file copy.
-+	 */
-+	if (!valid_vma(vma, is_bkpt_insn(&opcode)))
-+		goto put_out;
-+
-+	mapping = uprobe->inode->i_mapping;
-+	if (mapping != vma->vm_file->f_mapping)
-+		goto put_out;
-+
-+	addr = vma_address(vma, uprobe->offset);
-+	if (vaddr != (unsigned long)addr)
-+		goto put_out;
-+
-+	ret = -ENOMEM;
-+	new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, vaddr);
-+	if (!new_page)
-+		goto put_out;
-+
-+	__SetPageUptodate(new_page);
-+
-+	/*
-+	 * lock page will serialize against do_wp_page()'s
-+	 * PageAnon() handling
-+	 */
-+	lock_page(old_page);
-+	/* copy the page now that we've got it stable */
-+	vaddr_old = kmap_atomic(old_page);
-+	vaddr_new = kmap_atomic(new_page);
-+
-+	memcpy(vaddr_new, vaddr_old, PAGE_SIZE);
-+	/* poke the new insn in, ASSUMES we don't cross page boundary */
-+	vaddr &= ~PAGE_MASK;
-+	BUG_ON(vaddr + uprobe_opcode_sz > PAGE_SIZE);
-+	memcpy(vaddr_new + vaddr, &opcode, uprobe_opcode_sz);
-+
-+	kunmap_atomic(vaddr_new);
-+	kunmap_atomic(vaddr_old);
-+
-+	ret = anon_vma_prepare(vma);
-+	if (ret)
-+		goto unlock_out;
-+
-+	lock_page(new_page);
-+	ret = __replace_page(vma, old_page, new_page);
-+	unlock_page(new_page);
-+
-+unlock_out:
-+	unlock_page(old_page);
-+	page_cache_release(new_page);
-+
-+put_out:
-+	put_page(old_page);	/* we did a get_page in the beginning */
-+	return ret;
-+}
-+
-+/**
-+ * read_opcode - read the opcode at a given virtual address.
-+ * @mm: the probed process address space.
-+ * @vaddr: the virtual address to read the opcode.
-+ * @opcode: location to store the read opcode.
-+ *
-+ * Called with mm->mmap_sem held (for read and with a reference to
-+ * mm.
-+ *
-+ * For mm @mm, read the opcode at @vaddr and store it in @opcode.
-+ * Return 0 (success) or a negative errno.
-+ */
-+static int read_opcode(struct mm_struct *mm, unsigned long vaddr,
-+						uprobe_opcode_t *opcode)
-+{
-+	struct page *page;
-+	void *vaddr_new;
-+	int ret;
-+
-+	ret = get_user_pages(NULL, mm, vaddr, 1, 0, 0, &page, NULL);
-+	if (ret <= 0)
-+		return ret;
-+
-+	lock_page(page);
-+	vaddr_new = kmap_atomic(page);
-+	vaddr &= ~PAGE_MASK;
-+	memcpy(opcode, vaddr_new + vaddr, uprobe_opcode_sz);
-+	kunmap_atomic(vaddr_new);
-+	unlock_page(page);
-+	put_page(page);		/* we did a get_user_pages in the beginning */
-+	return 0;
-+}
-+
-+static int is_bkpt_at_addr(struct mm_struct *mm, unsigned long vaddr)
-+{
-+	uprobe_opcode_t opcode;
-+	int result = read_opcode(mm, vaddr, &opcode);
-+
-+	if (result)
-+		return result;
-+
-+	if (is_bkpt_insn(&opcode))
-+		return 1;
-+
-+	return 0;
-+}
-+
-+/**
-+ * set_bkpt - store breakpoint at a given address.
-+ * @mm: the probed process address space.
-+ * @uprobe: the probepoint information.
-+ * @vaddr: the virtual address to insert the opcode.
-+ *
-+ * For mm @mm, store the breakpoint instruction at @vaddr.
-+ * Return 0 (success) or a negative errno.
-+ */
-+int __weak set_bkpt(struct mm_struct *mm, struct uprobe *uprobe,
-+						unsigned long vaddr)
-+{
-+	int result = is_bkpt_at_addr(mm, vaddr);
-+
-+	if (result == 1)
-+		return -EEXIST;
-+
-+	if (result)
-+		return result;
-+
-+	return write_opcode(mm, uprobe, vaddr, UPROBES_BKPT_INSN);
-+}
-+
-+/**
-+ * set_orig_insn - Restore the original instruction.
-+ * @mm: the probed process address space.
-+ * @uprobe: the probepoint information.
-+ * @vaddr: the virtual address to insert the opcode.
-+ * @verify: if true, verify existance of breakpoint instruction.
-+ *
-+ * For mm @mm, restore the original opcode (opcode) at @vaddr.
-+ * Return 0 (success) or a negative errno.
-+ */
-+int __weak set_orig_insn(struct mm_struct *mm, struct uprobe *uprobe,
-+					unsigned long vaddr, bool verify)
-+{
-+	if (verify) {
-+		int result = is_bkpt_at_addr(mm, vaddr);
-+
-+		if (!result)
-+			return -EINVAL;
-+
-+		if (result != 1)
-+			return result;
-+	}
-+	return write_opcode(mm, uprobe, vaddr,
-+				*(uprobe_opcode_t *)uprobe->insn);
-+}
-+
-+static int match_uprobe(struct uprobe *l, struct uprobe *r)
-+{
-+	if (l->inode < r->inode)
-+		return -1;
-+	if (l->inode > r->inode)
-+		return 1;
-+	else {
-+		if (l->offset < r->offset)
-+			return -1;
-+
-+		if (l->offset > r->offset)
-+			return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+static struct uprobe *__find_uprobe(struct inode *inode, loff_t offset)
-+{
-+	struct uprobe u = { .inode = inode, .offset = offset };
-+	struct rb_node *n = uprobes_tree.rb_node;
-+	struct uprobe *uprobe;
-+	int match;
-+
-+	while (n) {
-+		uprobe = rb_entry(n, struct uprobe, rb_node);
-+		match = match_uprobe(&u, uprobe);
-+		if (!match) {
-+			atomic_inc(&uprobe->ref);
-+			return uprobe;
-+		}
-+		if (match < 0)
-+			n = n->rb_left;
-+		else
-+			n = n->rb_right;
-+	}
-+	return NULL;
-+}
-+
-+/*
-+ * Find a uprobe corresponding to a given inode:offset
-+ * Acquires uprobes_treelock
-+ */
-+static struct uprobe *find_uprobe(struct inode *inode, loff_t offset)
-+{
-+	struct uprobe *uprobe;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	uprobe = __find_uprobe(inode, offset);
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+	return uprobe;
-+}
-+
-+static struct uprobe *__insert_uprobe(struct uprobe *uprobe)
-+{
-+	struct rb_node **p = &uprobes_tree.rb_node;
-+	struct rb_node *parent = NULL;
-+	struct uprobe *u;
-+	int match;
-+
-+	while (*p) {
-+		parent = *p;
-+		u = rb_entry(parent, struct uprobe, rb_node);
-+		match = match_uprobe(uprobe, u);
-+		if (!match) {
-+			atomic_inc(&u->ref);
-+			return u;
-+		}
-+
-+		if (match < 0)
-+			p = &parent->rb_left;
-+		else
-+			p = &parent->rb_right;
-+
-+	}
-+	u = NULL;
-+	rb_link_node(&uprobe->rb_node, parent, p);
-+	rb_insert_color(&uprobe->rb_node, &uprobes_tree);
-+	/* get access + creation ref */
-+	atomic_set(&uprobe->ref, 2);
-+	return u;
-+}
-+
-+/*
-+ * Acquires uprobes_treelock.
-+ * Matching uprobe already exists in rbtree;
-+ *	increment (access refcount) and return the matching uprobe.
-+ *
-+ * No matching uprobe; insert the uprobe in rb_tree;
-+ *	get a double refcount (access + creation) and return NULL.
-+ */
-+static struct uprobe *insert_uprobe(struct uprobe *uprobe)
-+{
-+	unsigned long flags;
-+	struct uprobe *u;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	u = __insert_uprobe(uprobe);
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+	return u;
-+}
-+
-+static void put_uprobe(struct uprobe *uprobe)
-+{
-+	if (atomic_dec_and_test(&uprobe->ref))
-+		kfree(uprobe);
-+}
-+
-+static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset)
-+{
-+	struct uprobe *uprobe, *cur_uprobe;
-+
-+	uprobe = kzalloc(sizeof(struct uprobe), GFP_KERNEL);
-+	if (!uprobe)
-+		return NULL;
-+
-+	uprobe->inode = igrab(inode);
-+	uprobe->offset = offset;
-+	init_rwsem(&uprobe->consumer_rwsem);
-+	INIT_LIST_HEAD(&uprobe->pending_list);
-+
-+	/* add to uprobes_tree, sorted on inode:offset */
-+	cur_uprobe = insert_uprobe(uprobe);
-+
-+	/* a uprobe exists for this inode:offset combination */
-+	if (cur_uprobe) {
-+		kfree(uprobe);
-+		uprobe = cur_uprobe;
-+		iput(inode);
-+	} else
-+		atomic_inc(&uprobe_events);
-+	return uprobe;
-+}
-+
-+/* Returns the previous consumer */
-+static struct uprobe_consumer *add_consumer(struct uprobe *uprobe,
-+				struct uprobe_consumer *consumer)
-+{
-+	down_write(&uprobe->consumer_rwsem);
-+	consumer->next = uprobe->consumers;
-+	uprobe->consumers = consumer;
-+	up_write(&uprobe->consumer_rwsem);
-+	return consumer->next;
-+}
-+
-+/*
-+ * For uprobe @uprobe, delete the consumer @consumer.
-+ * Return true if the @consumer is deleted successfully
-+ * or return false.
-+ */
-+static bool del_consumer(struct uprobe *uprobe,
-+				struct uprobe_consumer *consumer)
-+{
-+	struct uprobe_consumer **con;
-+	bool ret = false;
-+
-+	down_write(&uprobe->consumer_rwsem);
-+	for (con = &uprobe->consumers; *con; con = &(*con)->next) {
-+		if (*con == consumer) {
-+			*con = consumer->next;
-+			ret = true;
-+			break;
-+		}
-+	}
-+	up_write(&uprobe->consumer_rwsem);
-+	return ret;
-+}
-+
-+static int __copy_insn(struct address_space *mapping,
-+			struct vm_area_struct *vma, char *insn,
-+			unsigned long nbytes, unsigned long offset)
-+{
-+	struct file *filp = vma->vm_file;
-+	struct page *page;
-+	void *vaddr;
-+	unsigned long off1;
-+	unsigned long idx;
-+
-+	if (!filp)
-+		return -EINVAL;
-+
-+	idx = (unsigned long)(offset >> PAGE_CACHE_SHIFT);
-+	off1 = offset &= ~PAGE_MASK;
-+
-+	/*
-+	 * Ensure that the page that has the original instruction is
-+	 * populated and in page-cache.
-+	 */
-+	page = read_mapping_page(mapping, idx, filp);
-+	if (IS_ERR(page))
-+		return PTR_ERR(page);
-+
-+	vaddr = kmap_atomic(page);
-+	memcpy(insn, vaddr + off1, nbytes);
-+	kunmap_atomic(vaddr);
-+	page_cache_release(page);
-+	return 0;
-+}
-+
-+static int copy_insn(struct uprobe *uprobe, struct vm_area_struct *vma,
-+					unsigned long addr)
-+{
-+	struct address_space *mapping;
-+	int bytes;
-+	unsigned long nbytes;
-+
-+	addr &= ~PAGE_MASK;
-+	nbytes = PAGE_SIZE - addr;
-+	mapping = uprobe->inode->i_mapping;
-+
-+	/* Instruction at end of binary; copy only available bytes */
-+	if (uprobe->offset + MAX_UINSN_BYTES > uprobe->inode->i_size)
-+		bytes = uprobe->inode->i_size - uprobe->offset;
-+	else
-+		bytes = MAX_UINSN_BYTES;
-+
-+	/* Instruction at the page-boundary; copy bytes in second page */
-+	if (nbytes < bytes) {
-+		if (__copy_insn(mapping, vma, uprobe->insn + nbytes,
-+				bytes - nbytes, uprobe->offset + nbytes))
-+			return -ENOMEM;
-+
-+		bytes = nbytes;
-+	}
-+	return __copy_insn(mapping, vma, uprobe->insn, bytes, uprobe->offset);
-+}
-+
-+static int install_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
-+				struct vm_area_struct *vma, loff_t vaddr)
-+{
-+	unsigned long addr;
-+	int ret;
-+
-+	/*
-+	 * If probe is being deleted, unregister thread could be done with
-+	 * the vma-rmap-walk through. Adding a probe now can be fatal since
-+	 * nobody will be able to cleanup. Also we could be from fork or
-+	 * mremap path, where the probe might have already been inserted.
-+	 * Hence behave as if probe already existed.
-+	 */
-+	if (!uprobe->consumers)
-+		return -EEXIST;
-+
-+	addr = (unsigned long)vaddr;
-+	if (!(uprobe->flags & UPROBES_COPY_INSN)) {
-+		ret = copy_insn(uprobe, vma, addr);
-+		if (ret)
-+			return ret;
-+
-+		if (is_bkpt_insn((uprobe_opcode_t *)uprobe->insn))
-+			return -EEXIST;
-+
-+		ret = analyze_insn(mm, uprobe);
-+		if (ret)
-+			return ret;
-+
-+		uprobe->flags |= UPROBES_COPY_INSN;
-+	}
-+	ret = set_bkpt(mm, uprobe, addr);
-+
-+	return ret;
-+}
-+
-+static void remove_breakpoint(struct mm_struct *mm, struct uprobe *uprobe,
-+							loff_t vaddr)
-+{
-+	set_orig_insn(mm, uprobe, (unsigned long)vaddr, true);
-+}
-+
-+static void delete_uprobe(struct uprobe *uprobe)
-+{
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	rb_erase(&uprobe->rb_node, &uprobes_tree);
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+	iput(uprobe->inode);
-+	put_uprobe(uprobe);
-+	atomic_dec(&uprobe_events);
-+}
-+
-+static struct vma_info *__find_next_vma_info(struct list_head *head,
-+			loff_t offset, struct address_space *mapping,
-+			struct vma_info *vi, bool is_register)
-+{
-+	struct prio_tree_iter iter;
-+	struct vm_area_struct *vma;
-+	struct vma_info *tmpvi;
-+	loff_t vaddr;
-+	unsigned long pgoff = offset >> PAGE_SHIFT;
-+	int existing_vma;
-+
-+	vma_prio_tree_foreach(vma, &iter, &mapping->i_mmap, pgoff, pgoff) {
-+		if (!valid_vma(vma, is_register))
-+			continue;
-+
-+		existing_vma = 0;
-+		vaddr = vma_address(vma, offset);
-+		list_for_each_entry(tmpvi, head, probe_list) {
-+			if (tmpvi->mm == vma->vm_mm && tmpvi->vaddr == vaddr) {
-+				existing_vma = 1;
-+				break;
-+			}
-+		}
-+
-+		/*
-+		 * Another vma needs a probe to be installed. However skip
-+		 * installing the probe if the vma is about to be unlinked.
-+		 */
-+		if (!existing_vma &&
-+				atomic_inc_not_zero(&vma->vm_mm->mm_users)) {
-+			vi->mm = vma->vm_mm;
-+			vi->vaddr = vaddr;
-+			list_add(&vi->probe_list, head);
-+			return vi;
-+		}
-+	}
-+	return NULL;
-+}
-+
-+/*
-+ * Iterate in the rmap prio tree  and find a vma where a probe has not
-+ * yet been inserted.
-+ */
-+static struct vma_info *find_next_vma_info(struct list_head *head,
-+			loff_t offset, struct address_space *mapping,
-+			bool is_register)
-+{
-+	struct vma_info *vi, *retvi;
-+	vi = kzalloc(sizeof(struct vma_info), GFP_KERNEL);
-+	if (!vi)
-+		return ERR_PTR(-ENOMEM);
-+
-+	mutex_lock(&mapping->i_mmap_mutex);
-+	retvi = __find_next_vma_info(head, offset, mapping, vi, is_register);
-+	mutex_unlock(&mapping->i_mmap_mutex);
-+
-+	if (!retvi)
-+		kfree(vi);
-+	return retvi;
-+}
-+
-+static int register_for_each_vma(struct uprobe *uprobe, bool is_register)
-+{
-+	struct list_head try_list;
-+	struct vm_area_struct *vma;
-+	struct address_space *mapping;
-+	struct vma_info *vi, *tmpvi;
-+	struct mm_struct *mm;
-+	loff_t vaddr;
-+	int ret = 0;
-+
-+	mapping = uprobe->inode->i_mapping;
-+	INIT_LIST_HEAD(&try_list);
-+	while ((vi = find_next_vma_info(&try_list, uprobe->offset,
-+					mapping, is_register)) != NULL) {
-+		if (IS_ERR(vi)) {
-+			ret = PTR_ERR(vi);
-+			break;
-+		}
-+		mm = vi->mm;
-+		down_read(&mm->mmap_sem);
-+		vma = find_vma(mm, (unsigned long)vi->vaddr);
-+		if (!vma || !valid_vma(vma, is_register)) {
-+			list_del(&vi->probe_list);
-+			kfree(vi);
-+			up_read(&mm->mmap_sem);
-+			mmput(mm);
-+			continue;
-+		}
-+		vaddr = vma_address(vma, uprobe->offset);
-+		if (vma->vm_file->f_mapping->host != uprobe->inode ||
-+						vaddr != vi->vaddr) {
-+			list_del(&vi->probe_list);
-+			kfree(vi);
-+			up_read(&mm->mmap_sem);
-+			mmput(mm);
-+			continue;
-+		}
-+
-+		if (is_register)
-+			ret = install_breakpoint(mm, uprobe, vma, vi->vaddr);
-+		else
-+			remove_breakpoint(mm, uprobe, vi->vaddr);
-+
-+		up_read(&mm->mmap_sem);
-+		mmput(mm);
-+		if (is_register) {
-+			if (ret && ret == -EEXIST)
-+				ret = 0;
-+			if (ret)
-+				break;
-+		}
-+	}
-+	list_for_each_entry_safe(vi, tmpvi, &try_list, probe_list) {
-+		list_del(&vi->probe_list);
-+		kfree(vi);
-+	}
-+	return ret;
-+}
-+
-+static int __register_uprobe(struct uprobe *uprobe)
-+{
-+	return register_for_each_vma(uprobe, true);
-+}
-+
-+static void __unregister_uprobe(struct uprobe *uprobe)
-+{
-+	if (!register_for_each_vma(uprobe, false))
-+		delete_uprobe(uprobe);
-+
-+	/* TODO : cant unregister? schedule a worker thread */
-+}
-+
-+/*
-+ * register_uprobe - register a probe
-+ * @inode: the file in which the probe has to be placed.
-+ * @offset: offset from the start of the file.
-+ * @consumer: information on howto handle the probe..
-+ *
-+ * Apart from the access refcount, register_uprobe() takes a creation
-+ * refcount (thro alloc_uprobe) if and only if this @uprobe is getting
-+ * inserted into the rbtree (i.e first consumer for a @inode:@offset
-+ * tuple).  Creation refcount stops unregister_uprobe from freeing the
-+ * @uprobe even before the register operation is complete. Creation
-+ * refcount is released when the last @consumer for the @uprobe
-+ * unregisters.
-+ *
-+ * Return errno if it cannot successully install probes
-+ * else return 0 (success)
-+ */
-+int register_uprobe(struct inode *inode, loff_t offset,
-+				struct uprobe_consumer *consumer)
-+{
-+	struct uprobe *uprobe;
-+	int ret = -EINVAL;
-+
-+	if (!inode || !consumer || consumer->next)
-+		return ret;
-+
-+	if (offset > i_size_read(inode))
-+		return ret;
-+
-+	ret = 0;
-+	mutex_lock(uprobes_hash(inode));
-+	uprobe = alloc_uprobe(inode, offset);
-+	if (uprobe && !add_consumer(uprobe, consumer)) {
-+		ret = __register_uprobe(uprobe);
-+		if (ret) {
-+			uprobe->consumers = NULL;
-+			__unregister_uprobe(uprobe);
-+		} else
-+			uprobe->flags |= UPROBES_RUN_HANDLER;
-+	}
-+
-+	mutex_unlock(uprobes_hash(inode));
-+	put_uprobe(uprobe);
-+
-+	return ret;
-+}
-+
-+/*
-+ * unregister_uprobe - unregister a already registered probe.
-+ * @inode: the file in which the probe has to be removed.
-+ * @offset: offset from the start of the file.
-+ * @consumer: identify which probe if multiple probes are colocated.
-+ */
-+void unregister_uprobe(struct inode *inode, loff_t offset,
-+				struct uprobe_consumer *consumer)
-+{
-+	struct uprobe *uprobe = NULL;
-+
-+	if (!inode || !consumer)
-+		return;
-+
-+	uprobe = find_uprobe(inode, offset);
-+	if (!uprobe)
-+		return;
-+
-+	mutex_lock(uprobes_hash(inode));
-+	if (!del_consumer(uprobe, consumer))
-+		goto unreg_out;
-+
-+	if (!uprobe->consumers) {
-+		__unregister_uprobe(uprobe);
-+		uprobe->flags &= ~UPROBES_RUN_HANDLER;
-+	}
-+
-+unreg_out:
-+	mutex_unlock(uprobes_hash(inode));
-+	if (uprobe)
-+		put_uprobe(uprobe);
-+}
-+
-+/*
-+ * Of all the nodes that correspond to the given inode, return the node
-+ * with the least offset.
-+ */
-+static struct rb_node *find_least_offset_node(struct inode *inode)
-+{
-+	struct uprobe u = { .inode = inode, .offset = 0};
-+	struct rb_node *n = uprobes_tree.rb_node;
-+	struct rb_node *close_node = NULL;
-+	struct uprobe *uprobe;
-+	int match;
-+
-+	while (n) {
-+		uprobe = rb_entry(n, struct uprobe, rb_node);
-+		match = match_uprobe(&u, uprobe);
-+		if (uprobe->inode == inode)
-+			close_node = n;
-+
-+		if (!match)
-+			return close_node;
-+
-+		if (match < 0)
-+			n = n->rb_left;
-+		else
-+			n = n->rb_right;
-+	}
-+	return close_node;
-+}
-+
-+/*
-+ * For a given inode, build a list of probes that need to be inserted.
-+ */
-+static void build_probe_list(struct inode *inode, struct list_head *head)
-+{
-+	struct uprobe *uprobe;
-+	struct rb_node *n;
-+	unsigned long flags;
-+
-+	spin_lock_irqsave(&uprobes_treelock, flags);
-+	n = find_least_offset_node(inode);
-+	for (; n; n = rb_next(n)) {
-+		uprobe = rb_entry(n, struct uprobe, rb_node);
-+		if (uprobe->inode != inode)
-+			break;
-+
-+		list_add(&uprobe->pending_list, head);
-+		atomic_inc(&uprobe->ref);
-+	}
-+	spin_unlock_irqrestore(&uprobes_treelock, flags);
-+}
-+
-+/*
-+ * Called from mmap_region.
-+ * called with mm->mmap_sem acquired.
-+ *
-+ * Return -ve no if we fail to insert probes and we cannot
-+ * bail-out.
-+ * Return 0 otherwise. i.e :
-+ *	- successful insertion of probes
-+ *	- (or) no possible probes to be inserted.
-+ *	- (or) insertion of probes failed but we can bail-out.
-+ */
-+int mmap_uprobe(struct vm_area_struct *vma)
-+{
-+	struct list_head tmp_list;
-+	struct uprobe *uprobe, *u;
-+	struct inode *inode;
-+	int ret = 0;
-+
-+	if (!atomic_read(&uprobe_events) || !valid_vma(vma, true))
-+		return ret;	/* Bail-out */
-+
-+	inode = vma->vm_file->f_mapping->host;
-+	if (!inode)
-+		return ret;
-+
-+	INIT_LIST_HEAD(&tmp_list);
-+	mutex_lock(uprobes_mmap_hash(inode));
-+	build_probe_list(inode, &tmp_list);
-+	list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) {
-+		loff_t vaddr;
-+
-+		list_del(&uprobe->pending_list);
-+		if (!ret) {
-+			vaddr = vma_address(vma, uprobe->offset);
-+			if (vaddr < vma->vm_start || vaddr >= vma->vm_end) {
-+				put_uprobe(uprobe);
-+				continue;
-+			}
-+			ret = install_breakpoint(vma->vm_mm, uprobe, vma,
-+								vaddr);
-+			if (ret == -EEXIST)
-+				ret = 0;
-+		}
-+		put_uprobe(uprobe);
-+	}
-+
-+	mutex_unlock(uprobes_mmap_hash(inode));
-+
-+	return ret;
-+}
-+
-+static int __init init_uprobes(void)
-+{
-+	int i;
-+
-+	for (i = 0; i < UPROBES_HASH_SZ; i++) {
-+		mutex_init(&uprobes_mutex[i]);
-+		mutex_init(&uprobes_mmap_mutex[i]);
-+	}
-+	return 0;
-+}
-+
-+static void __exit exit_uprobes(void)
-+{
-+}
-+
-+module_init(init_uprobes);
-+module_exit(exit_uprobes);
-diff --git a/mm/mmap.c b/mm/mmap.c
-index 848ef52..f6ea842 100644
---- a/mm/mmap.c
-+++ b/mm/mmap.c
-@@ -30,6 +30,7 @@
- #include <linux/perf_event.h>
- #include <linux/audit.h>
- #include <linux/khugepaged.h>
-+#include <linux/uprobes.h>
- 
- #include <asm/uaccess.h>
- #include <asm/cacheflush.h>
-@@ -617,6 +618,13 @@ again:			remove_next = 1 + (end > next->vm_end);
- 	if (mapping)
- 		mutex_unlock(&mapping->i_mmap_mutex);
- 
-+	if (root) {
-+		mmap_uprobe(vma);
-+
-+		if (adjust_next)
-+			mmap_uprobe(next);
-+	}
-+
- 	if (remove_next) {
- 		if (file) {
- 			fput(file);
-@@ -638,6 +646,8 @@ again:			remove_next = 1 + (end > next->vm_end);
- 			goto again;
- 		}
- 	}
-+	if (insert && file)
-+		mmap_uprobe(insert);
- 
- 	validate_mm(mm);
- 
-@@ -1371,6 +1381,11 @@ out:
- 			mm->locked_vm += (len >> PAGE_SHIFT);
- 	} else if ((flags & MAP_POPULATE) && !(flags & MAP_NONBLOCK))
- 		make_pages_present(addr, addr + len);
-+
-+	if (file && mmap_uprobe(vma))
-+		/* matching probes but cannot insert */
-+		goto unmap_and_free_vma;
-+
- 	return addr;
- 
- unmap_and_free_vma:
-@@ -2352,6 +2367,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma)
- 	if ((vma->vm_flags & VM_ACCOUNT) &&
- 	     security_vm_enough_memory_mm(mm, vma_pages(vma)))
- 		return -ENOMEM;
-+
-+	if (vma->vm_file && mmap_uprobe(vma))
-+		return -EINVAL;
-+
- 	vma_link(mm, vma, prev, rb_link, rb_parent);
- 	return 0;
- }
-@@ -2421,6 +2440,10 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap,
- 			new_vma->vm_pgoff = pgoff;
- 			if (new_vma->vm_file) {
- 				get_file(new_vma->vm_file);
-+
-+				if (mmap_uprobe(new_vma))
-+					goto out_free_mempol;
-+
- 				if (vma->vm_flags & VM_EXECUTABLE)
- 					added_exe_file_vma(mm);
- 			}
--- 
-1.7.5.4
-
diff --git a/features/vfat/FAT-Added-FAT_NO_83NAME.patch b/features/vfat/FAT-Added-FAT_NO_83NAME.patch
index 34cce4895d40f2d707361a85d5de3794b05d19d5..b24b912d379cf17c9bf6e5f50b41bf57f05c24d6 100644
--- a/features/vfat/FAT-Added-FAT_NO_83NAME.patch
+++ b/features/vfat/FAT-Added-FAT_NO_83NAME.patch
@@ -10,30 +10,28 @@ inaccessible. For VFAT it makes the file only accessible by the long
 filename.
 
 Signed-off-by: Andrew Tridgell <tridge@samba.org>
----
- fs/fat/dir.c             |   14 ++++++++++++++
- include/linux/msdos_fs.h |    1 +
- 2 files changed, 15 insertions(+), 0 deletions(-)
-
 diff --git a/fs/fat/dir.c b/fs/fat/dir.c
-index 530b4ca..2d0ef72 100644
+index dc49ed2..43ffba1 100644
 --- a/fs/fat/dir.c
 +++ b/fs/fat/dir.c
-@@ -384,6 +384,13 @@ parse_record:
- 				goto end_of_dir;
- 		}
+@@ -368,7 +368,15 @@ static int fat_parse_short(struct super_block *sb,
+ 		dotoffset = 1;
+ 	}
  
-+		/*
-+		 * The FAT_NO_83NAME flag is used to mark files
-+		 * created with no 8.3 short name
-+		 */
-+		if (de->lcase & FAT_NO_83NAME)
-+			goto compare_longname;
+-	memcpy(work, de->name, sizeof(work));
++	/*
++	 * The FAT_NO_83NAME flag is used to mark files
++	 * created with no 8.3 short name
++	 */
++	if (de->lcase & FAT_NO_83NAME)
++		goto compare_longname;
 +
- 		memcpy(work, de->name, sizeof(de->name));
- 		/* see namei.c, msdos_format_name */
- 		if (work[0] == 0x05)
-@@ -428,6 +435,7 @@ parse_record:
++	memcpy(work, de->name, sizeof(de->name));
++
+ 	/* see namei.c, msdos_format_name */
+ 	if (work[0] == 0x05)
+ 		work[0] = 0xE5;
+@@ -512,6 +520,7 @@ parse_record:
  		if (fat_name_match(sbi, name, name_len, bufname, len))
  			goto found;
  
@@ -41,7 +39,7 @@ index 530b4ca..2d0ef72 100644
  		if (nr_slots) {
  			void *longname = unicode + FAT_MAX_UNI_CHARS;
  			int size = PATH_MAX - FAT_MAX_UNI_SIZE;
-@@ -529,6 +537,8 @@ parse_record:
+@@ -608,6 +617,8 @@ parse_record:
  		if (de->attr != ATTR_EXT && IS_FREE(de->name))
  			goto record_end;
  	} else {
@@ -50,7 +48,7 @@ index 530b4ca..2d0ef72 100644
  		if ((de->attr & ATTR_VOLUME) || IS_FREE(de->name))
  			goto record_end;
  	}
-@@ -934,6 +944,10 @@ int fat_scan(struct inode *dir, const unsigned char *name,
+@@ -950,6 +961,10 @@ int fat_scan(struct inode *dir, const unsigned char *name,
  	sinfo->bh = NULL;
  	while (fat_get_short_entry(dir, &sinfo->slot_off, &sinfo->bh,
  				   &sinfo->de) >= 0) {
@@ -62,10 +60,10 @@ index 530b4ca..2d0ef72 100644
  			sinfo->slot_off -= sizeof(*sinfo->de);
  			sinfo->nr_slots = 1;
 diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h
-index 34066e6..12ba0ba 100644
+index 11cc2ac..0e3c229 100644
 --- a/include/linux/msdos_fs.h
 +++ b/include/linux/msdos_fs.h
-@@ -44,6 +44,7 @@
+@@ -45,6 +45,7 @@
  
  #define CASE_LOWER_BASE	8	/* base is lower case */
  #define CASE_LOWER_EXT	16	/* extension is lower case */
@@ -73,6 +71,3 @@ index 34066e6..12ba0ba 100644
  
  #define DELETED_FLAG	0xe5	/* marks file as deleted when in name[0] */
  #define IS_FREE(n)	(!*(n) || *(n) == DELETED_FLAG)
--- 
-1.6.5.2
-
diff --git a/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch b/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
index dcf9f3e33ca6c79697cbf9f16c2f882fc6394c3c..abad650d4a150f58c16e7f96b12bce5570779b83 100644
--- a/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
+++ b/patches/boot/NFS-allow-nfs-root-mount-to-use-alternate-rpc-ports.patch
@@ -8,21 +8,27 @@ Allow an nfs root mount to use alternate RPC ports for mountd and nfsd.
 Signed-off-by: Jason Wessel <jason.wessel@windriver.com>
 [forward port to 2.6.33+]
 Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
----
- fs/nfs/client.c           |   12 +++++++++++-
- fs/nfs/internal.h         |    6 ++++--
- fs/nfs/mount_clnt.c       |    7 ++++---
- fs/nfs/super.c            |   33 ++++++++++++++++++++++++++++++++-
- include/linux/nfs_fs_sb.h |    3 +++
- include/linux/nfs_mount.h |    4 +++-
- 6 files changed, 57 insertions(+), 8 deletions(-)
-
 diff --git a/fs/nfs/client.c b/fs/nfs/client.c
-index 4a108a0..745d2f2 100644
+index 9969444..0742c9e 100644
 --- a/fs/nfs/client.c
 +++ b/fs/nfs/client.c
-@@ -100,7 +100,7 @@ static const struct rpc_version *nfs_version[5] = {
- #endif
+@@ -7,7 +7,14 @@
+  * modify it under the terms of the GNU General Public License
+  * as published by the Free Software Foundation; either version
+  * 2 of the License, or (at your option) any later version.
++<<<<<<<
+  */
++|||||||
++};
++=======
++	int nfs_prog;
++};
++>>>>>>>
+ 
+ 
+ #include <linux/module.h>
+@@ -70,7 +77,7 @@ static const struct rpc_version *nfs_version[5] = {
+ 	[4] = NULL,
  };
  
 -const struct rpc_program nfs_program = {
@@ -30,23 +36,15 @@ index 4a108a0..745d2f2 100644
  	.name			= "nfs",
  	.number			= NFS_PROGRAM,
  	.nrvers			= ARRAY_SIZE(nfs_version),
-@@ -137,6 +137,7 @@ struct nfs_client_initdata {
- 	int proto;
- 	u32 minorversion;
- 	struct net *net;
-+	int nfs_prog;
- };
- 
- /*
-@@ -155,6 +156,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
- 		goto error_0;
+@@ -161,6 +168,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
+ 	try_module_get(clp->cl_nfs_mod->owner);
  
- 	clp->rpc_ops = cl_init->rpc_ops;
+ 	clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
 +	clp->nfs_prog = cl_init->nfs_prog;
  
  	atomic_set(&clp->cl_count, 1);
  	clp->cl_cons_state = NFS_CS_INITING;
-@@ -495,6 +497,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
+@@ -419,6 +427,9 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
  		/* Match nfsv4 minorversion */
  		if (clp->cl_minorversion != data->minorversion)
  			continue;
@@ -56,7 +54,7 @@ index 4a108a0..745d2f2 100644
  		/* Match the full socket address */
  		if (!nfs_sockaddr_cmp(sap, clap))
  			continue;
-@@ -679,6 +684,10 @@ static int nfs_create_rpc_client(struct nfs_client *clp,
+@@ -597,6 +608,10 @@ int nfs_create_rpc_client(struct nfs_client *clp,
  	if (!IS_ERR(clp->cl_rpcclient))
  		return 0;
  
@@ -67,8 +65,8 @@ index 4a108a0..745d2f2 100644
  	clnt = rpc_create(&args);
  	if (IS_ERR(clnt)) {
  		dprintk("%s: cannot create RPC client. Error = %ld\n",
-@@ -851,6 +860,7 @@ static int nfs_init_server(struct nfs_server *server,
- 		.rpc_ops = &nfs_v2_clientops,
+@@ -750,6 +765,7 @@ static int nfs_init_server(struct nfs_server *server,
+ 		.nfs_mod = nfs_mod,
  		.proto = data->nfs_server.protocol,
  		.net = data->net,
 +		.nfs_prog = data->nfs_prog,
@@ -76,10 +74,18 @@ index 4a108a0..745d2f2 100644
  	struct rpc_timeout timeparms;
  	struct nfs_client *clp;
 diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
-index 2476dc6..dd36bc8 100644
+index 31fdb03..1c8f2b5 100644
 --- a/fs/nfs/internal.h
 +++ b/fs/nfs/internal.h
-@@ -94,6 +94,8 @@ struct nfs_parsed_mount_data {
+@@ -94,6 +94,7 @@ struct nfs_client_initdata {
+ 	int proto;
+ 	u32 minorversion;
+ 	struct net *net;
++	int nfs_prog;
+ };
+ 
+ /*
+@@ -105,6 +106,8 @@ struct nfs_parsed_mount_data {
  	int			timeo, retrans;
  	int			acregmin, acregmax,
  				acdirmin, acdirmax;
@@ -88,8 +94,8 @@ index 2476dc6..dd36bc8 100644
  	int			namlen;
  	unsigned int		options;
  	unsigned int		bsize;
-@@ -141,11 +143,11 @@ struct nfs_mount_request {
- 	struct net		*net;
+@@ -161,11 +164,11 @@ struct nfs_mount_info {
+ 	struct nfs_fh *mntfh;
  };
  
 -extern int nfs_mount(struct nfs_mount_request *info);
@@ -100,8 +106,8 @@ index 2476dc6..dd36bc8 100644
 -extern const struct rpc_program nfs_program;
 +extern struct rpc_program nfs_program;
  extern void nfs_clients_init(struct net *net);
- 
- extern void nfs_cleanup_cb_ident_idr(struct net *);
+ extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
+ int nfs_create_rpc_client(struct nfs_client *, const struct rpc_timeout *, rpc_authflavor_t);
 diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c
 index 8e65c7f..9794450 100644
 --- a/fs/nfs/mount_clnt.c
@@ -142,10 +148,10 @@ index 8e65c7f..9794450 100644
  	.number		= NFS_MNT_PROGRAM,
  	.nrvers		= ARRAY_SIZE(mnt_version),
 diff --git a/fs/nfs/super.c b/fs/nfs/super.c
-index ccc4cdb..47305a2 100644
+index 239aff7..e063958 100644
 --- a/fs/nfs/super.c
 +++ b/fs/nfs/super.c
-@@ -99,6 +99,8 @@ enum {
+@@ -100,6 +100,8 @@ enum {
  	Opt_mountport,
  	Opt_mountvers,
  	Opt_minorversion,
@@ -154,7 +160,7 @@ index ccc4cdb..47305a2 100644
  
  	/* Mount options that take string arguments */
  	Opt_nfsvers,
-@@ -162,6 +164,8 @@ static const match_table_t nfs_mount_option_tokens = {
+@@ -163,6 +165,8 @@ static const match_table_t nfs_mount_option_tokens = {
  	{ Opt_mountport, "mountport=%s" },
  	{ Opt_mountvers, "mountvers=%s" },
  	{ Opt_minorversion, "minorversion=%s" },
@@ -163,7 +169,7 @@ index ccc4cdb..47305a2 100644
  
  	{ Opt_nfsvers, "nfsvers=%s" },
  	{ Opt_nfsvers, "vers=%s" },
-@@ -949,6 +953,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(unsigned int ve
+@@ -905,6 +909,8 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
  		data->acregmax		= NFS_DEF_ACREGMAX;
  		data->acdirmin		= NFS_DEF_ACDIRMIN;
  		data->acdirmax		= NFS_DEF_ACDIRMAX;
@@ -172,7 +178,7 @@ index ccc4cdb..47305a2 100644
  		data->mount_server.port	= NFS_UNSPEC_PORT;
  		data->nfs_server.port	= NFS_UNSPEC_PORT;
  		data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
-@@ -1342,6 +1348,26 @@ static int nfs_parse_mount_options(char *raw,
+@@ -1298,6 +1304,26 @@ static int nfs_parse_mount_options(char *raw,
  				goto out_invalid_value;
  			mnt->acdirmax = option;
  			break;
@@ -199,7 +205,7 @@ index ccc4cdb..47305a2 100644
  		case Opt_actimeo:
  			if (nfs_get_option_ul(args, &option))
  				goto out_invalid_value;
-@@ -1724,7 +1750,7 @@ static int nfs_try_mount(struct nfs_parsed_mount_data *args,
+@@ -1680,7 +1706,7 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
  	 * Now ask the mount server to map our export path
  	 * to a file handle.
  	 */
@@ -208,7 +214,7 @@ index ccc4cdb..47305a2 100644
  	if (status != 0) {
  		dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
  				request.hostname, status);
-@@ -1834,6 +1860,7 @@ static int nfs_validate_mount_data(void *options,
+@@ -1812,6 +1838,7 @@ static int nfs23_validate_mount_data(void *options,
  {
  	struct nfs_mount_data *data = (struct nfs_mount_data *)options;
  	struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
@@ -216,7 +222,7 @@ index ccc4cdb..47305a2 100644
  
  	if (data == NULL)
  		goto out_no_data;
-@@ -1853,6 +1880,8 @@ static int nfs_validate_mount_data(void *options,
+@@ -1832,6 +1859,8 @@ static int nfs23_validate_mount_data(void *options,
  			goto out_no_sec;
  	case 5:
  		memset(data->context, 0, sizeof(data->context));
@@ -225,9 +231,9 @@ index ccc4cdb..47305a2 100644
  	case 6:
  		if (data->flags & NFS_MOUNT_VER3) {
  			if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
-@@ -2588,6 +2617,8 @@ static int nfs4_validate_mount_data(void *options,
- 	if (data == NULL)
- 		goto out_no_data;
+@@ -2553,6 +2582,8 @@ static int nfs4_validate_mount_data(void *options,
+ 
+ 	args->version = 4;
  
 +	args->nfs_prog = NFS_PROGRAM;
 +
@@ -235,21 +241,21 @@ index ccc4cdb..47305a2 100644
  	case 1:
  		if (data->host_addrlen > sizeof(args->nfs_server.address))
 diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
-index 7073fc7..1b056df 100644
+index 310c63c..ac826d0 100644
 --- a/include/linux/nfs_fs_sb.h
 +++ b/include/linux/nfs_fs_sb.h
-@@ -47,6 +47,7 @@ struct nfs_client {
+@@ -52,6 +52,7 @@ struct nfs_client {
  
  	u32			cl_minorversion;/* NFSv4 minorversion */
  	struct rpc_cred		*cl_machine_cred;
 +	int			nfs_prog;
  
- #ifdef CONFIG_NFS_V4
+ #if IS_ENABLED(CONFIG_NFS_V4)
  	u64			cl_clientid;	/* constant */
-@@ -72,7 +73,9 @@ struct nfs_client {
+@@ -73,7 +74,9 @@ struct nfs_client {
+ 	 * This is used to generate the mv0 callback address.
  	 */
  	char			cl_ipaddr[48];
- 	unsigned char		cl_id_uniquifier;
 +
  	u32			cl_cb_ident;	/* v4.0 callback identifier */
 +
@@ -278,6 +284,3 @@ index 576bddd..9541d71 100644
  };
  
  /* bits in the flags field visible to user space */
--- 
-1.7.5.4
-
diff --git a/staging/emgd-1.14.scc b/staging/emgd-1.14.scc
index ef80aa3ecb8890b82fbcc03ab06a1af228204023..f2dd169707e8a40cd5c8d361f20acd4bfe20645e 100644
--- a/staging/emgd-1.14.scc
+++ b/staging/emgd-1.14.scc
@@ -1,4 +1,4 @@
 git branch emgd-1.14 master
 
-patch yocto-emgd-emgd-1.14-driver.patch
-patch emgd-pvr-get-it-building-with-v3.4-kernel.patch
+#patch yocto-emgd-emgd-1.14-driver.patch
+#patch emgd-pvr-get-it-building-with-v3.4-kernel.patch