From: Greg Kroah-Hartman Date: Mon, 2 May 2016 19:54:40 +0000 (-0700) Subject: 4.5-stable patches X-Git-Tag: v3.14.68~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d512fd0d8e31659b60d3b9cb5819bcdcd586bbef;p=thirdparty%2Fkernel%2Fstable-queue.git 4.5-stable patches added patches: drivers-misc-ad525x_dpot-ad5274-fix-rdac-read-back-errors.patch ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch fbdev-da8xx-fb-fix-videomodes-of-lcd-panels.patch irqchip-mxs-fix-error-check-of-of_io_request_and_map.patch irqchip-sunxi-nmi-fix-error-check-of-of_io_request_and_map.patch lib-mpi-endianness-fix.patch locking-mcs-fix-mcs_spin_lock-ordering.patch misc-bmp085-enable-building-as-a-module.patch misc-mic-scif-fix-wrap-around-tests.patch paride-make-verbose-parameter-an-int-again.patch perf-evlist-reference-count-the-cpu-and-thread-maps-at-set_maps.patch perf-tools-fix-perf-script-python-database-export-crash.patch pm-domains-fix-removal-of-a-subdomain.patch pm-opp-initialize-u_volt_min-max-to-a-valid-value.patch regulator-s5m8767-fix-get_register-error-handling.patch rtc-ds1685-passing-bogus-values-to-irq_restore.patch rtc-hym8563-fix-invalid-year-calculation.patch rtc-max77686-properly-handle-regmap_irq_get_virq-error-code.patch rtc-rx8025-remove-rv8803-id.patch rtc-vr41xx-wire-up-alarm_irq_enable.patch scsi_dh-force-modular-build-if-scsi-is-a-module.patch spi-rockchip-make-sure-spi-clk-is-on-in-rockchip_spi_set_cs.patch spi-rockchip-modify-dma-max-burst-to-1.patch x86-mm-kmmio-fix-mmiotrace-for-hugepages.patch --- diff --git a/queue-4.5/drivers-misc-ad525x_dpot-ad5274-fix-rdac-read-back-errors.patch b/queue-4.5/drivers-misc-ad525x_dpot-ad5274-fix-rdac-read-back-errors.patch new file mode 100644 index 00000000000..0fbe8bdb111 --- /dev/null +++ b/queue-4.5/drivers-misc-ad525x_dpot-ad5274-fix-rdac-read-back-errors.patch @@ -0,0 +1,30 @@ +From f3df53e4d70b5736368a8fe8aa1bb70c1cb1f577 Mon Sep 17 00:00:00 2001 +From: Michael Hennerich +Date: Mon, 22 Feb 2016 10:20:24 +0100 +Subject: drivers/misc/ad525x_dpot: AD5274 fix RDAC read back errors + +From: Michael Hennerich + +commit f3df53e4d70b5736368a8fe8aa1bb70c1cb1f577 upstream. + +Fix RDAC read back errors caused by a typo. Value must shift by 2. + +Fixes: a4bd394956f2 ("drivers/misc/ad525x_dpot.c: new features") +Signed-off-by: Michael Hennerich +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/ad525x_dpot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/ad525x_dpot.c ++++ b/drivers/misc/ad525x_dpot.c +@@ -216,7 +216,7 @@ static s32 dpot_read_i2c(struct dpot_dat + */ + value = swab16(value); + +- if (dpot->uid == DPOT_UID(AD5271_ID)) ++ if (dpot->uid == DPOT_UID(AD5274_ID)) + value = value >> 2; + return value; + default: diff --git a/queue-4.5/ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch b/queue-4.5/ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch new file mode 100644 index 00000000000..7aa60d18db2 --- /dev/null +++ b/queue-4.5/ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch @@ -0,0 +1,87 @@ +From 5e1021f2b6dff1a86a468a1424d59faae2bc63c1 Mon Sep 17 00:00:00 2001 +From: Eryu Guan +Date: Sat, 12 Mar 2016 21:40:32 -0500 +Subject: ext4: fix NULL pointer dereference in ext4_mark_inode_dirty() + +From: Eryu Guan + +commit 5e1021f2b6dff1a86a468a1424d59faae2bc63c1 upstream. + +ext4_reserve_inode_write() in ext4_mark_inode_dirty() could fail on +error (e.g. EIO) and iloc.bh can be NULL in this case. But the error is +ignored in the following "if" condition and ext4_expand_extra_isize() +might be called with NULL iloc.bh set, which triggers NULL pointer +dereference. + +This is uncovered by commit 8b4953e13f4c ("ext4: reserve code points for +the project quota feature"), which enlarges the ext4_inode size, and +run the following script on new kernel but with old mke2fs: + + #/bin/bash + mnt=/mnt/ext4 + devname=ext4-error + dev=/dev/mapper/$devname + fsimg=/home/fs.img + + trap cleanup 0 1 2 3 9 15 + + cleanup() + { + umount $mnt >/dev/null 2>&1 + dmsetup remove $devname + losetup -d $backend_dev + rm -f $fsimg + exit 0 + } + + rm -f $fsimg + fallocate -l 1g $fsimg + backend_dev=`losetup -f --show $fsimg` + devsize=`blockdev --getsz $backend_dev` + + good_tab="0 $devsize linear $backend_dev 0" + error_tab="0 $devsize error $backend_dev 0" + + dmsetup create $devname --table "$good_tab" + + mkfs -t ext4 $dev + mount -t ext4 -o errors=continue,strictatime $dev $mnt + + dmsetup load $devname --table "$error_tab" && dmsetup resume $devname + echo 3 > /proc/sys/vm/drop_caches + ls -l $mnt + exit 0 + +[ Patch changed to simplify the function a tiny bit. -- Ted ] + +Signed-off-by: Eryu Guan +Signed-off-by: Theodore Ts'o +Cc: Jan Kara +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/inode.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -5261,6 +5261,8 @@ int ext4_mark_inode_dirty(handle_t *hand + might_sleep(); + trace_ext4_mark_inode_dirty(inode, _RET_IP_); + err = ext4_reserve_inode_write(handle, inode, &iloc); ++ if (err) ++ return err; + if (ext4_handle_valid(handle) && + EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && + !ext4_test_inode_state(inode, EXT4_STATE_NO_EXPAND)) { +@@ -5291,9 +5293,7 @@ int ext4_mark_inode_dirty(handle_t *hand + } + } + } +- if (!err) +- err = ext4_mark_iloc_dirty(handle, inode, &iloc); +- return err; ++ return ext4_mark_iloc_dirty(handle, inode, &iloc); + } + + /* diff --git a/queue-4.5/fbdev-da8xx-fb-fix-videomodes-of-lcd-panels.patch b/queue-4.5/fbdev-da8xx-fb-fix-videomodes-of-lcd-panels.patch new file mode 100644 index 00000000000..5f6c6011b12 --- /dev/null +++ b/queue-4.5/fbdev-da8xx-fb-fix-videomodes-of-lcd-panels.patch @@ -0,0 +1,56 @@ +From 713fced8d10fa1c759c8fb6bf9aaa681bae68cad Mon Sep 17 00:00:00 2001 +From: Sushaanth Srirangapathi +Date: Mon, 29 Feb 2016 18:42:19 +0530 +Subject: fbdev: da8xx-fb: fix videomodes of lcd panels + +From: Sushaanth Srirangapathi + +commit 713fced8d10fa1c759c8fb6bf9aaa681bae68cad upstream. + +Commit 028cd86b794f4a ("video: da8xx-fb: fix the polarities of the +hsync/vsync pulse") fixes polarities of HSYNC/VSYNC pulse but +forgot to update known_lcd_panels[] which had sync values +according to old logic. This breaks LCD at least on DA850 EVM. + +This patch fixes this issue and I have tested this for panel +"Sharp_LK043T1DG01" using DA850 EVM board. + +Fixes: 028cd86b794f4a ("video: da8xx-fb: fix the polarities of the hsync/vsync pulse") +Signed-off-by: Sushaanth Srirangapathi +Signed-off-by: Tomi Valkeinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/fbdev/da8xx-fb.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +--- a/drivers/video/fbdev/da8xx-fb.c ++++ b/drivers/video/fbdev/da8xx-fb.c +@@ -209,8 +209,7 @@ static struct fb_videomode known_lcd_pan + .lower_margin = 2, + .hsync_len = 0, + .vsync_len = 0, +- .sync = FB_SYNC_CLK_INVERT | +- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .sync = FB_SYNC_CLK_INVERT, + }, + /* Sharp LK043T1DG01 */ + [1] = { +@@ -224,7 +223,7 @@ static struct fb_videomode known_lcd_pan + .lower_margin = 2, + .hsync_len = 41, + .vsync_len = 10, +- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .sync = 0, + .flag = 0, + }, + [2] = { +@@ -239,7 +238,7 @@ static struct fb_videomode known_lcd_pan + .lower_margin = 10, + .hsync_len = 10, + .vsync_len = 10, +- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, ++ .sync = 0, + .flag = 0, + }, + [3] = { diff --git a/queue-4.5/irqchip-mxs-fix-error-check-of-of_io_request_and_map.patch b/queue-4.5/irqchip-mxs-fix-error-check-of-of_io_request_and_map.patch new file mode 100644 index 00000000000..5f5b4f22a64 --- /dev/null +++ b/queue-4.5/irqchip-mxs-fix-error-check-of-of_io_request_and_map.patch @@ -0,0 +1,40 @@ +From edf8fcdc6b254236be005851af35ea5e826e7e09 Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy +Date: Wed, 9 Mar 2016 03:21:40 +0200 +Subject: irqchip/mxs: Fix error check of of_io_request_and_map() + +From: Vladimir Zapolskiy + +commit edf8fcdc6b254236be005851af35ea5e826e7e09 upstream. + +The of_io_request_and_map() returns a valid pointer in iomem region or +ERR_PTR(), check for NULL always fails and may cause a NULL pointer +dereference on error path. + +Fixes: 25e34b44313b ("irqchip/mxs: Prepare driver for hardware with different offsets") +Signed-off-by: Vladimir Zapolskiy +Cc: Jason Cooper +Cc: Marc Zyngier +Cc: Oleksij Rempel +Cc: Sascha Hauer +Cc: Shawn Guo +Cc: linux-arm-kernel@lists.infradead.org +Link: http://lkml.kernel.org/r/1457486500-10237-1-git-send-email-vz@mleia.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-mxs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-mxs.c ++++ b/drivers/irqchip/irq-mxs.c +@@ -183,7 +183,7 @@ static void __iomem * __init icoll_init_ + void __iomem *icoll_base; + + icoll_base = of_io_request_and_map(np, 0, np->name); +- if (!icoll_base) ++ if (IS_ERR(icoll_base)) + panic("%s: unable to map resource", np->full_name); + return icoll_base; + } diff --git a/queue-4.5/irqchip-sunxi-nmi-fix-error-check-of-of_io_request_and_map.patch b/queue-4.5/irqchip-sunxi-nmi-fix-error-check-of-of_io_request_and_map.patch new file mode 100644 index 00000000000..d924e79ea8f --- /dev/null +++ b/queue-4.5/irqchip-sunxi-nmi-fix-error-check-of-of_io_request_and_map.patch @@ -0,0 +1,42 @@ +From cfe199afefe6201e998ddc07102fc1fdb55f196c Mon Sep 17 00:00:00 2001 +From: Vladimir Zapolskiy +Date: Wed, 9 Mar 2016 03:21:29 +0200 +Subject: irqchip/sunxi-nmi: Fix error check of of_io_request_and_map() + +From: Vladimir Zapolskiy + +commit cfe199afefe6201e998ddc07102fc1fdb55f196c upstream. + +The of_io_request_and_map() returns a valid pointer in iomem region or +ERR_PTR(), check for NULL always fails and may cause a NULL pointer +dereference on error path. + +Fixes: 0e841b04c829 ("irqchip/sunxi-nmi: Switch to of_io_request_and_map() from of_iomap()") +Signed-off-by: Vladimir Zapolskiy +Cc: Jason Cooper +Cc: Marc Zyngier +Cc: Chen-Yu Tsai +Cc: Maxime Ripard +Cc: linux-arm-kernel@lists.infradead.org +Link: http://lkml.kernel.org/r/1457486489-10189-1-git-send-email-vz@mleia.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-sunxi-nmi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/irqchip/irq-sunxi-nmi.c ++++ b/drivers/irqchip/irq-sunxi-nmi.c +@@ -160,9 +160,9 @@ static int __init sunxi_sc_nmi_irq_init( + + gc = irq_get_domain_generic_chip(domain, 0); + gc->reg_base = of_io_request_and_map(node, 0, of_node_full_name(node)); +- if (!gc->reg_base) { ++ if (IS_ERR(gc->reg_base)) { + pr_err("unable to map resource\n"); +- ret = -ENOMEM; ++ ret = PTR_ERR(gc->reg_base); + goto fail_irqd_remove; + } + diff --git a/queue-4.5/lib-mpi-endianness-fix.patch b/queue-4.5/lib-mpi-endianness-fix.patch new file mode 100644 index 00000000000..aa51220fae2 --- /dev/null +++ b/queue-4.5/lib-mpi-endianness-fix.patch @@ -0,0 +1,100 @@ +From 3ee0cb5fb5eea2110db1b5cb7f67029b7be8a376 Mon Sep 17 00:00:00 2001 +From: Michal Marek +Date: Wed, 17 Feb 2016 14:46:59 +0100 +Subject: lib/mpi: Endianness fix + +From: Michal Marek + +commit 3ee0cb5fb5eea2110db1b5cb7f67029b7be8a376 upstream. + +The limbs are integers in the host endianness, so we can't simply +iterate over the individual bytes. The current code happens to work on +little-endian, because the order of the limbs in the MPI array is the +same as the order of the bytes in each limb, but it breaks on +big-endian. + +Fixes: 0f74fbf77d45 ("MPI: Fix mpi_read_buffer") +Signed-off-by: Michal Marek +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + lib/mpi/mpicoder.c | 39 +++++++++++++++++++++------------------ + 1 file changed, 21 insertions(+), 18 deletions(-) + +--- a/lib/mpi/mpicoder.c ++++ b/lib/mpi/mpicoder.c +@@ -128,6 +128,23 @@ leave: + } + EXPORT_SYMBOL_GPL(mpi_read_from_buffer); + ++static int count_lzeros(MPI a) ++{ ++ mpi_limb_t alimb; ++ int i, lzeros = 0; ++ ++ for (i = a->nlimbs - 1; i >= 0; i--) { ++ alimb = a->d[i]; ++ if (alimb == 0) { ++ lzeros += sizeof(mpi_limb_t); ++ } else { ++ lzeros += count_leading_zeros(alimb) / 8; ++ break; ++ } ++ } ++ return lzeros; ++} ++ + /** + * mpi_read_buffer() - read MPI to a bufer provided by user (msb first) + * +@@ -148,7 +165,7 @@ int mpi_read_buffer(MPI a, uint8_t *buf, + uint8_t *p; + mpi_limb_t alimb; + unsigned int n = mpi_get_size(a); +- int i, lzeros = 0; ++ int i, lzeros; + + if (!buf || !nbytes) + return -EINVAL; +@@ -156,14 +173,7 @@ int mpi_read_buffer(MPI a, uint8_t *buf, + if (sign) + *sign = a->sign; + +- p = (void *)&a->d[a->nlimbs] - 1; +- +- for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) { +- if (!*p) +- lzeros++; +- else +- break; +- } ++ lzeros = count_lzeros(a); + + if (buf_len < n - lzeros) { + *nbytes = n - lzeros; +@@ -351,7 +361,7 @@ int mpi_write_to_sgl(MPI a, struct scatt + u8 *p, *p2; + mpi_limb_t alimb, alimb2; + unsigned int n = mpi_get_size(a); +- int i, x, y = 0, lzeros = 0, buf_len; ++ int i, x, y = 0, lzeros, buf_len; + + if (!nbytes) + return -EINVAL; +@@ -359,14 +369,7 @@ int mpi_write_to_sgl(MPI a, struct scatt + if (sign) + *sign = a->sign; + +- p = (void *)&a->d[a->nlimbs] - 1; +- +- for (i = a->nlimbs * sizeof(alimb) - 1; i >= 0; i--, p--) { +- if (!*p) +- lzeros++; +- else +- break; +- } ++ lzeros = count_lzeros(a); + + if (*nbytes < n - lzeros) { + *nbytes = n - lzeros; diff --git a/queue-4.5/locking-mcs-fix-mcs_spin_lock-ordering.patch b/queue-4.5/locking-mcs-fix-mcs_spin_lock-ordering.patch new file mode 100644 index 00000000000..7ee5b54f568 --- /dev/null +++ b/queue-4.5/locking-mcs-fix-mcs_spin_lock-ordering.patch @@ -0,0 +1,54 @@ +From 920c720aa5aa3900a7f1689228fdfc2580a91e7e Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 1 Feb 2016 15:11:28 +0100 +Subject: locking/mcs: Fix mcs_spin_lock() ordering + +From: Peter Zijlstra + +commit 920c720aa5aa3900a7f1689228fdfc2580a91e7e upstream. + +Similar to commit b4b29f94856a ("locking/osq: Fix ordering of node +initialisation in osq_lock") the use of xchg_acquire() is +fundamentally broken with MCS like constructs. + +Furthermore, it turns out we rely on the global transitivity of this +operation because the unlock path observes the pointer with a +READ_ONCE(), not an smp_load_acquire(). + +This is non-critical because the MCS code isn't actually used and +mostly serves as documentation, a stepping stone to the more complex +things we've build on top of the idea. + +Reported-by: Andrea Parri +Signed-off-by: Peter Zijlstra (Intel) +Cc: Andrew Morton +Cc: Linus Torvalds +Cc: Paul E. McKenney +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Will Deacon +Fixes: 3552a07a9c4a ("locking/mcs: Use acquire/release semantics") +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/locking/mcs_spinlock.h | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/kernel/locking/mcs_spinlock.h ++++ b/kernel/locking/mcs_spinlock.h +@@ -67,7 +67,13 @@ void mcs_spin_lock(struct mcs_spinlock * + node->locked = 0; + node->next = NULL; + +- prev = xchg_acquire(lock, node); ++ /* ++ * We rely on the full barrier with global transitivity implied by the ++ * below xchg() to order the initialization stores above against any ++ * observation of @node. And to provide the ACQUIRE ordering associated ++ * with a LOCK primitive. ++ */ ++ prev = xchg(lock, node); + if (likely(prev == NULL)) { + /* + * Lock acquired, don't need to set node->locked to 1. Threads diff --git a/queue-4.5/misc-bmp085-enable-building-as-a-module.patch b/queue-4.5/misc-bmp085-enable-building-as-a-module.patch new file mode 100644 index 00000000000..7c7c5ba8fed --- /dev/null +++ b/queue-4.5/misc-bmp085-enable-building-as-a-module.patch @@ -0,0 +1,36 @@ +From 50e6315dba721cbc24ccd6d7b299f1782f210a98 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Mon, 14 Dec 2015 14:29:23 +0000 +Subject: misc/bmp085: Enable building as a module + +From: Ben Hutchings + +commit 50e6315dba721cbc24ccd6d7b299f1782f210a98 upstream. + +Commit 985087dbcb02 'misc: add support for bmp18x chips to the bmp085 +driver' changed the BMP085 config symbol to a boolean. I see no +reason why the shared code cannot be built as a module, so change it +back to tristate. + +Fixes: 985087dbcb02 ("misc: add support for bmp18x chips to the bmp085 driver") +Cc: Eric Andersson +Signed-off-by: Ben Hutchings +Acked-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -440,7 +440,7 @@ config ARM_CHARLCD + still useful. + + config BMP085 +- bool ++ tristate + depends on SYSFS + + config BMP085_I2C diff --git a/queue-4.5/misc-mic-scif-fix-wrap-around-tests.patch b/queue-4.5/misc-mic-scif-fix-wrap-around-tests.patch new file mode 100644 index 00000000000..fc16c0058cc --- /dev/null +++ b/queue-4.5/misc-mic-scif-fix-wrap-around-tests.patch @@ -0,0 +1,51 @@ +From 7b64dbf849abdd7e769820e25120758f956a7f13 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 19 Oct 2015 14:19:01 +0300 +Subject: misc: mic/scif: fix wrap around tests + +From: Dan Carpenter + +commit 7b64dbf849abdd7e769820e25120758f956a7f13 upstream. + +Signed integer overflow is undefined. Also I added a check for +"(offset < 0)" in scif_unregister() because that makes it match the +other conditions and because I didn't want to subtract a negative. + +Fixes: ba612aa8b487 ('misc: mic: SCIF memory registration and unregistration') +Signed-off-by: Dan Carpenter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/misc/mic/scif/scif_rma.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/misc/mic/scif/scif_rma.c ++++ b/drivers/misc/mic/scif/scif_rma.c +@@ -1511,7 +1511,7 @@ off_t scif_register_pinned_pages(scif_ep + if ((map_flags & SCIF_MAP_FIXED) && + ((ALIGN(offset, PAGE_SIZE) != offset) || + (offset < 0) || +- (offset + (off_t)len < offset))) ++ (len > LONG_MAX - offset))) + return -EINVAL; + + might_sleep(); +@@ -1614,7 +1614,7 @@ off_t scif_register(scif_epd_t epd, void + if ((map_flags & SCIF_MAP_FIXED) && + ((ALIGN(offset, PAGE_SIZE) != offset) || + (offset < 0) || +- (offset + (off_t)len < offset))) ++ (len > LONG_MAX - offset))) + return -EINVAL; + + /* Unsupported protection requested */ +@@ -1732,7 +1732,8 @@ scif_unregister(scif_epd_t epd, off_t of + + /* Offset is not page aligned or offset+len wraps around */ + if ((ALIGN(offset, PAGE_SIZE) != offset) || +- (offset + (off_t)len < offset)) ++ (offset < 0) || ++ (len > LONG_MAX - offset)) + return -EINVAL; + + err = scif_verify_epd(ep); diff --git a/queue-4.5/paride-make-verbose-parameter-an-int-again.patch b/queue-4.5/paride-make-verbose-parameter-an-int-again.patch new file mode 100644 index 00000000000..845396ded05 --- /dev/null +++ b/queue-4.5/paride-make-verbose-parameter-an-int-again.patch @@ -0,0 +1,80 @@ +From dec63a4dec2d6d01346fd5d96062e67c0636852b Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 15 Mar 2016 14:53:29 -0700 +Subject: paride: make 'verbose' parameter an 'int' again + +From: Arnd Bergmann + +commit dec63a4dec2d6d01346fd5d96062e67c0636852b upstream. + +gcc-6.0 found an ancient bug in the paride driver, which had a +"module_param(verbose, bool, 0);" since before 2.6.12, but actually uses +it to accept '0', '1' or '2' as arguments: + + drivers/block/paride/pd.c: In function 'pd_init_dev_parms': + drivers/block/paride/pd.c:298:29: warning: comparison of constant '1' with boolean expression is always false [-Wbool-compare] + #define DBMSG(msg) ((verbose>1)?(msg):NULL) + +In 2012, Rusty did a cleanup patch that also changed the type of the +variable to 'bool', which introduced what is now a gcc warning. + +This changes the type back to 'int' and adapts the module_param() line +instead, so it should work as documented in case anyone ever cares about +running the ancient driver with debugging. + +Fixes: 90ab5ee94171 ("module_param: make bool parameters really bool (drivers & misc)") +Signed-off-by: Arnd Bergmann +Rusty Russell +Cc: Tim Waugh +Cc: Sudip Mukherjee +Cc: Jens Axboe +Cc: Greg Kroah-Hartman +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/block/paride/pd.c | 4 ++-- + drivers/block/paride/pt.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/block/paride/pd.c ++++ b/drivers/block/paride/pd.c +@@ -126,7 +126,7 @@ + */ + #include + +-static bool verbose = 0; ++static int verbose = 0; + static int major = PD_MAJOR; + static char *name = PD_NAME; + static int cluster = 64; +@@ -161,7 +161,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, + static DEFINE_MUTEX(pd_mutex); + static DEFINE_SPINLOCK(pd_lock); + +-module_param(verbose, bool, 0); ++module_param(verbose, int, 0); + module_param(major, int, 0); + module_param(name, charp, 0); + module_param(cluster, int, 0); +--- a/drivers/block/paride/pt.c ++++ b/drivers/block/paride/pt.c +@@ -117,7 +117,7 @@ + + */ + +-static bool verbose = 0; ++static int verbose = 0; + static int major = PT_MAJOR; + static char *name = PT_NAME; + static int disable = 0; +@@ -152,7 +152,7 @@ static int (*drives[4])[6] = {&drive0, & + + #include + +-module_param(verbose, bool, 0); ++module_param(verbose, int, 0); + module_param(major, int, 0); + module_param(name, charp, 0); + module_param_array(drive0, int, NULL, 0); diff --git a/queue-4.5/perf-evlist-reference-count-the-cpu-and-thread-maps-at-set_maps.patch b/queue-4.5/perf-evlist-reference-count-the-cpu-and-thread-maps-at-set_maps.patch new file mode 100644 index 00000000000..ae5cdf9b4da --- /dev/null +++ b/queue-4.5/perf-evlist-reference-count-the-cpu-and-thread-maps-at-set_maps.patch @@ -0,0 +1,70 @@ +From a55e5663761366fb883f6f25375dd68bc958b9db Mon Sep 17 00:00:00 2001 +From: Arnaldo Carvalho de Melo +Date: Wed, 17 Feb 2016 10:57:19 -0300 +Subject: perf evlist: Reference count the cpu and thread maps at set_maps() + +From: Arnaldo Carvalho de Melo + +commit a55e5663761366fb883f6f25375dd68bc958b9db upstream. + +We were dropping the reference we possibly held but not obtaining one +for the new maps, which we will drop at perf_evlist__delete(), fix it. + +This was caught by Steven Noonan in some of the machines which would +produce this output when caught by glibc debug mechanisms: + + $ sudo perf test 21 + 21: Test object code reading :*** + Error in `perf': corrupted double-linked list: 0x00000000023ffcd0 *** + ======= Backtrace: ========= + /usr/lib/libc.so.6(+0x72055)[0x7f25be0f3055] + /usr/lib/libc.so.6(+0x779b6)[0x7f25be0f89b6] + /usr/lib/libc.so.6(+0x7a0ed)[0x7f25be0fb0ed] + /usr/lib/libc.so.6(__libc_calloc+0xba)[0x7f25be0fceda] + perf(parse_events_lex_init_extra+0x38)[0x4cfff8] + perf(parse_events+0x55)[0x4a0615] + perf(perf_evlist__config+0xcf)[0x4eeb2f] + perf[0x479f82] + perf(test__code_reading+0x1e)[0x47ad4e] + perf(cmd_test+0x5dd)[0x46452d] + perf[0x47f4e3] + perf(main+0x603)[0x42c723] + /usr/lib/libc.so.6(__libc_start_main+0xf0)[0x7f25be0a1610] + perf(_start+0x29)[0x42c859] + +Further investigation using valgrind led to the reference count imbalance fixed +in this patch. + +Reported-and-Tested-by: Steven Noonan +Report-Link: http://lkml.kernel.org/r/CAKbGBLjC2Dx5vshxyGmQkcD+VwiAQLbHoXA9i7kvRB2-2opHZQ@mail.gmail.com +Cc: Adrian Hunter +Cc: David Ahern +Cc: Jiri Olsa +Cc: Namhyung Kim +Cc: Wang Nan +Fixes: f30a79b012e5 ("perf tools: Add reference counting for cpu_map object") +Link: http://lkml.kernel.org/n/tip-j0u1bdhr47sa511sgg76kb8h@git.kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/evlist.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/tools/perf/util/evlist.c ++++ b/tools/perf/util/evlist.c +@@ -1181,12 +1181,12 @@ void perf_evlist__set_maps(struct perf_e + */ + if (cpus != evlist->cpus) { + cpu_map__put(evlist->cpus); +- evlist->cpus = cpus; ++ evlist->cpus = cpu_map__get(cpus); + } + + if (threads != evlist->threads) { + thread_map__put(evlist->threads); +- evlist->threads = threads; ++ evlist->threads = thread_map__get(threads); + } + + perf_evlist__propagate_maps(evlist); diff --git a/queue-4.5/perf-tools-fix-perf-script-python-database-export-crash.patch b/queue-4.5/perf-tools-fix-perf-script-python-database-export-crash.patch new file mode 100644 index 00000000000..9d9609b3709 --- /dev/null +++ b/queue-4.5/perf-tools-fix-perf-script-python-database-export-crash.patch @@ -0,0 +1,71 @@ +From 616df645d7238e45d3b369933a30fee4e4e305e2 Mon Sep 17 00:00:00 2001 +From: Chris Phlipot +Date: Tue, 8 Mar 2016 21:11:54 -0800 +Subject: perf tools: Fix perf script python database export crash + +From: Chris Phlipot + +commit 616df645d7238e45d3b369933a30fee4e4e305e2 upstream. + +Remove the union in evsel so that the database id and priv pointer can +be used simultainously without conflicting and crashing. + +Detailed Description for the fixed bug follows: + +perf script crashes with a segmentation fault on user space tool version +4.5.rc7.ge2857b when using the python database export API. It works +properly in 4.4 and prior versions. + +the crash fist appeared in: + +cfc8874a4859 ("perf script: Process cpu/threads maps") + +How to reproduce the bug: + +Remove any temporary files left over from a previous crash (if you have +already attemped to reproduce the bug): + + $ rm -r test_db-perf-data + $ dropdb test_db + + $ perf record timeout 1 yes >/dev/null + $ perf script -s scripts/python/export-to-postgresql.py test_db + + Stack Trace: + Program received signal SIGSEGV, Segmentation fault. + __GI___libc_free (mem=0x1) at malloc.c:2929 + 2929 malloc.c: No such file or directory. + (gdb) bt + at util/stat.c:122 + argv=, prefix=) at builtin-script.c:2231 + argc=argc@entry=4, argv=argv@entry=0x7fffffffdf70) at perf.c:390 + at perf.c:451 + +Signed-off-by: Chris Phlipot +Acked-by: Jiri Olsa +Cc: Adrian Hunter +Cc: Peter Zijlstra +Fixes: cfc8874a4859 ("perf script: Process cpu/threads maps") +Link: http://lkml.kernel.org/r/1457500314-8912-1-git-send-email-cphlipot0@gmail.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/evsel.h | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/tools/perf/util/evsel.h ++++ b/tools/perf/util/evsel.h +@@ -93,10 +93,8 @@ struct perf_evsel { + const char *unit; + struct event_format *tp_format; + off_t id_offset; +- union { +- void *priv; +- u64 db_id; +- }; ++ void *priv; ++ u64 db_id; + struct cgroup_sel *cgrp; + void *handler; + struct cpu_map *cpus; diff --git a/queue-4.5/pm-domains-fix-removal-of-a-subdomain.patch b/queue-4.5/pm-domains-fix-removal-of-a-subdomain.patch new file mode 100644 index 00000000000..4fb2706518b --- /dev/null +++ b/queue-4.5/pm-domains-fix-removal-of-a-subdomain.patch @@ -0,0 +1,42 @@ +From beda5fc1ff9b527059290a97b672d2ee0eb7b92f Mon Sep 17 00:00:00 2001 +From: Jon Hunter +Date: Fri, 4 Mar 2016 10:55:14 +0000 +Subject: PM / Domains: Fix removal of a subdomain + +From: Jon Hunter + +commit beda5fc1ff9b527059290a97b672d2ee0eb7b92f upstream. + +Commit 30e7a65b3fdb (PM / Domains: Ensure subdomain is not in use +before removing) added a test to ensure that a subdomain is not a +master to another subdomain or if any devices are using the subdomain +before removing. This change incorrectly used the "slave_links" list to +determine if the subdomain is a master to another subdomain, where it +should have been using the "master_links" list instead. The +"slave_links" list will never be empty for a subdomain and so a +subdomain can never be removed. Fix this by testing if the +"master_links" list is empty instead. + +Fixes: 30e7a65b3fdb (PM / Domains: Ensure subdomain is not in use before removing) +Signed-off-by: Jon Hunter +Reviewed-by: Thierry Reding +Acked-by: Ulf Hansson +Acked-by: Kevin Hilman +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/domain.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/base/power/domain.c ++++ b/drivers/base/power/domain.c +@@ -1378,7 +1378,7 @@ int pm_genpd_remove_subdomain(struct gen + mutex_lock(&subdomain->lock); + mutex_lock_nested(&genpd->lock, SINGLE_DEPTH_NESTING); + +- if (!list_empty(&subdomain->slave_links) || subdomain->device_count) { ++ if (!list_empty(&subdomain->master_links) || subdomain->device_count) { + pr_warn("%s: unable to remove subdomain %s\n", genpd->name, + subdomain->name); + ret = -EBUSY; diff --git a/queue-4.5/pm-opp-initialize-u_volt_min-max-to-a-valid-value.patch b/queue-4.5/pm-opp-initialize-u_volt_min-max-to-a-valid-value.patch new file mode 100644 index 00000000000..845199ecab5 --- /dev/null +++ b/queue-4.5/pm-opp-initialize-u_volt_min-max-to-a-valid-value.patch @@ -0,0 +1,74 @@ +From c88c395f4a6485f23f81e385c79945d68bcd5c5d Mon Sep 17 00:00:00 2001 +From: Viresh Kumar +Date: Mon, 15 Feb 2016 10:21:53 +0530 +Subject: PM / OPP: Initialize u_volt_min/max to a valid value + +From: Viresh Kumar + +commit c88c395f4a6485f23f81e385c79945d68bcd5c5d upstream. + +We kept u_volt_min/max initialized to 0, when only the target voltage is +present in DT, instead of the target/min/max triplet. + +This didn't go well with the regulator framework, as on few calls the +min voltage was set to target and max was set to 0 and so resulted in a +kernel crash like below: + +kernel BUG at ../drivers/regulator/core.c:216! + +[] (regulator_check_voltage) from [] (regulator_set_voltage_unlocked+0x58/0x230) +[] (regulator_set_voltage_unlocked) from [] (regulator_set_voltage+0x28/0x54) +[] (regulator_set_voltage) from [] (_set_opp_voltage+0x30/0x98) +[] (_set_opp_voltage) from [] (dev_pm_opp_set_rate+0xf0/0x28c) +[] (dev_pm_opp_set_rate) from [] (__cpufreq_driver_target+0x184/0x2b4) +[] (__cpufreq_driver_target) from [] (dbs_check_cpu+0x1b0/0x1f4) +[] (dbs_check_cpu) from [] (cpufreq_governor_dbs+0x324/0x5c4) +[] (cpufreq_governor_dbs) from [] (__cpufreq_governor+0xe4/0x1ec) +[] (__cpufreq_governor) from [] (cpufreq_init_policy+0x64/0x8c) +[] (cpufreq_init_policy) from [] (cpufreq_online+0x2fc/0x708) +[] (cpufreq_online) from [] (subsys_interface_register+0x94/0xd8) +[] (subsys_interface_register) from [] (cpufreq_register_driver+0x14c/0x19c) +[] (cpufreq_register_driver) from [] (dt_cpufreq_probe+0x70/0xec) +[] (dt_cpufreq_probe) from [] (platform_drv_probe+0x4c/0xb0) +[] (platform_drv_probe) from [] (driver_probe_device+0x214/0x2c0) +[] (driver_probe_device) from [] (__driver_attach+0x8c/0x90) +[] (__driver_attach) from [] (bus_for_each_dev+0x68/0x9c) +[] (bus_for_each_dev) from [] (bus_add_driver+0x1a0/0x218) +[] (bus_add_driver) from [] (driver_register+0x78/0xf8) +[] (driver_register) from [] (do_one_initcall+0x90/0x1d8) +[] (do_one_initcall) from [] (kernel_init_freeable+0x15c/0x1fc) +[] (kernel_init_freeable) from [] (kernel_init+0x8/0xf0) +[] (kernel_init) from [] (ret_from_fork+0x14/0x3c) +Code: e1550004 baffffeb e3a00000 e8bd8070 (e7f001f2) + +Fix that by initializing u_volt_min/max to the target voltage in such cases. + +Reported-and-tested-by: Krzysztof Kozlowski +Fixes: 274659029c9d (PM / OPP: Add support to parse "operating-points-v2" bindings) +Signed-off-by: Viresh Kumar +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/base/power/opp/core.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/base/power/opp/core.c ++++ b/drivers/base/power/opp/core.c +@@ -844,8 +844,14 @@ static int opp_parse_supplies(struct dev + } + + opp->u_volt = microvolt[0]; +- opp->u_volt_min = microvolt[1]; +- opp->u_volt_max = microvolt[2]; ++ ++ if (count == 1) { ++ opp->u_volt_min = opp->u_volt; ++ opp->u_volt_max = opp->u_volt; ++ } else { ++ opp->u_volt_min = microvolt[1]; ++ opp->u_volt_max = microvolt[2]; ++ } + + /* Search for "opp-microamp-" */ + prop = NULL; diff --git a/queue-4.5/regulator-s5m8767-fix-get_register-error-handling.patch b/queue-4.5/regulator-s5m8767-fix-get_register-error-handling.patch new file mode 100644 index 00000000000..77f038d526d --- /dev/null +++ b/queue-4.5/regulator-s5m8767-fix-get_register-error-handling.patch @@ -0,0 +1,68 @@ +From e07ff9434167981c993a26d2edbbcb8e13801dbb Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Tue, 16 Feb 2016 15:53:11 +0100 +Subject: regulator: s5m8767: fix get_register() error handling + +From: Arnd Bergmann + +commit e07ff9434167981c993a26d2edbbcb8e13801dbb upstream. + +The s5m8767_pmic_probe() function calls s5m8767_get_register() to +read data without checking the return code, which produces a compile-time +warning when that data is accessed: + +drivers/regulator/s5m8767.c: In function 's5m8767_pmic_probe': +drivers/regulator/s5m8767.c:924:7: error: 'enable_reg' may be used uninitialized in this function [-Werror=maybe-uninitialized] +drivers/regulator/s5m8767.c:944:30: error: 'enable_val' may be used uninitialized in this function [-Werror=maybe-uninitialized] + +This changes the s5m8767_get_register() function to return a -EINVAL +not just for an invalid register number but also for an invalid +regulator number, as both would result in returning uninitialized +data. The s5m8767_pmic_probe() function is then changed accordingly +to fail on a read error, as all the other callers of s5m8767_get_register() +already do. + +In practice this probably cannot happen, as we don't call +s5m8767_get_register() with invalid arguments, but the gcc +warning seems valid in principle, in terms writing safe +error checking. + +Signed-off-by: Arnd Bergmann +Fixes: 9c4c60554acf ("regulator: s5m8767: Convert to use regulator_[enable|disable|is_enabled]_regmap") +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/regulator/s5m8767.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/drivers/regulator/s5m8767.c ++++ b/drivers/regulator/s5m8767.c +@@ -202,9 +202,10 @@ static int s5m8767_get_register(struct s + } + } + +- if (i < s5m8767->num_regulators) +- *enable_ctrl = +- s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT; ++ if (i >= s5m8767->num_regulators) ++ return -EINVAL; ++ ++ *enable_ctrl = s5m8767_opmode_reg[reg_id][mode] << S5M8767_ENCTRL_SHIFT; + + return 0; + } +@@ -937,8 +938,12 @@ static int s5m8767_pmic_probe(struct pla + else + regulators[id].vsel_mask = 0xff; + +- s5m8767_get_register(s5m8767, id, &enable_reg, ++ ret = s5m8767_get_register(s5m8767, id, &enable_reg, + &enable_val); ++ if (ret) { ++ dev_err(s5m8767->dev, "error reading registers\n"); ++ return ret; ++ } + regulators[id].enable_reg = enable_reg; + regulators[id].enable_mask = S5M8767_ENCTRL_MASK; + regulators[id].enable_val = enable_val; diff --git a/queue-4.5/rtc-ds1685-passing-bogus-values-to-irq_restore.patch b/queue-4.5/rtc-ds1685-passing-bogus-values-to-irq_restore.patch new file mode 100644 index 00000000000..886f81401e6 --- /dev/null +++ b/queue-4.5/rtc-ds1685-passing-bogus-values-to-irq_restore.patch @@ -0,0 +1,53 @@ +From 8c09b9fdecab1f4a289f07b46e2ad174b6641928 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 2 Mar 2016 13:07:45 +0300 +Subject: rtc: ds1685: passing bogus values to irq_restore + +From: Dan Carpenter + +commit 8c09b9fdecab1f4a289f07b46e2ad174b6641928 upstream. + +We call spin_lock_irqrestore with "flags" set to zero instead of to the +value from spin_lock_irqsave(). + +Fixes: aaaf5fbf56f1 ('rtc: add driver for DS1685 family of real time clocks') +Signed-off-by: Dan Carpenter +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-ds1685.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/rtc/rtc-ds1685.c ++++ b/drivers/rtc/rtc-ds1685.c +@@ -187,9 +187,9 @@ ds1685_rtc_end_data_access(struct ds1685 + * Only use this where you are certain another lock will not be held. + */ + static inline void +-ds1685_rtc_begin_ctrl_access(struct ds1685_priv *rtc, unsigned long flags) ++ds1685_rtc_begin_ctrl_access(struct ds1685_priv *rtc, unsigned long *flags) + { +- spin_lock_irqsave(&rtc->lock, flags); ++ spin_lock_irqsave(&rtc->lock, *flags); + ds1685_rtc_switch_to_bank1(rtc); + } + +@@ -1300,7 +1300,7 @@ ds1685_rtc_sysfs_ctrl_regs_store(struct + { + struct ds1685_priv *rtc = dev_get_drvdata(dev); + u8 reg = 0, bit = 0, tmp; +- unsigned long flags = 0; ++ unsigned long flags; + long int val = 0; + const struct ds1685_rtc_ctrl_regs *reg_info = + ds1685_rtc_sysfs_ctrl_regs_lookup(attr->attr.name); +@@ -1321,7 +1321,7 @@ ds1685_rtc_sysfs_ctrl_regs_store(struct + bit = reg_info->bit; + + /* Safe to spinlock during a write. */ +- ds1685_rtc_begin_ctrl_access(rtc, flags); ++ ds1685_rtc_begin_ctrl_access(rtc, &flags); + tmp = rtc->read(rtc, reg); + rtc->write(rtc, reg, (val ? (tmp | bit) : (tmp & ~(bit)))); + ds1685_rtc_end_ctrl_access(rtc, flags); diff --git a/queue-4.5/rtc-hym8563-fix-invalid-year-calculation.patch b/queue-4.5/rtc-hym8563-fix-invalid-year-calculation.patch new file mode 100644 index 00000000000..81d35ec4e6e --- /dev/null +++ b/queue-4.5/rtc-hym8563-fix-invalid-year-calculation.patch @@ -0,0 +1,34 @@ +From d5861262210067fc01b2fb4f7af2fd85a3453f15 Mon Sep 17 00:00:00 2001 +From: Alexander Kochetkov +Date: Sun, 6 Mar 2016 12:43:57 +0300 +Subject: rtc: hym8563: fix invalid year calculation + +From: Alexander Kochetkov + +commit d5861262210067fc01b2fb4f7af2fd85a3453f15 upstream. + +Year field must be in BCD format, according to +hym8563 datasheet. + +Due to the bug year 2016 became 2010. + +Fixes: dcaf03849352 ("rtc: add hym8563 rtc-driver") +Signed-off-by: Alexander Kochetkov +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-hym8563.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/rtc/rtc-hym8563.c ++++ b/drivers/rtc/rtc-hym8563.c +@@ -144,7 +144,7 @@ static int hym8563_rtc_set_time(struct d + * it does not seem to carry it over a subsequent write/read. + * So we'll limit ourself to 100 years, starting at 2000 for now. + */ +- buf[6] = tm->tm_year - 100; ++ buf[6] = bin2bcd(tm->tm_year - 100); + + /* + * CTL1 only contains TEST-mode bits apart from stop, diff --git a/queue-4.5/rtc-max77686-properly-handle-regmap_irq_get_virq-error-code.patch b/queue-4.5/rtc-max77686-properly-handle-regmap_irq_get_virq-error-code.patch new file mode 100644 index 00000000000..094717bb1f2 --- /dev/null +++ b/queue-4.5/rtc-max77686-properly-handle-regmap_irq_get_virq-error-code.patch @@ -0,0 +1,38 @@ +From fb166ba1d7f0a662f7332f4ff660a0d6f4d76915 Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Thu, 4 Feb 2016 09:26:35 +0900 +Subject: rtc: max77686: Properly handle regmap_irq_get_virq() error code + +From: Krzysztof Kozlowski + +commit fb166ba1d7f0a662f7332f4ff660a0d6f4d76915 upstream. + +The regmap_irq_get_virq() can return 0 or -EINVAL in error conditions +but driver checked only for value of 0. + +This could lead to a cast of -EINVAL to an unsigned int used as a +interrupt number for devm_request_threaded_irq(). Although this is not +yet fatal (devm_request_threaded_irq() will just fail with -EINVAL) but +might be a misleading when diagnosing errors. + +Signed-off-by: Krzysztof Kozlowski +Fixes: 6f1c1e71d933 ("mfd: max77686: Convert to use regmap_irq") +Reviewed-by: Javier Martinez Canillas +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-max77686.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/rtc/rtc-max77686.c ++++ b/drivers/rtc/rtc-max77686.c +@@ -465,7 +465,7 @@ static int max77686_rtc_probe(struct pla + + info->virq = regmap_irq_get_virq(max77686->rtc_irq_data, + MAX77686_RTCIRQ_RTCA1); +- if (!info->virq) { ++ if (info->virq <= 0) { + ret = -ENXIO; + goto err_rtc; + } diff --git a/queue-4.5/rtc-rx8025-remove-rv8803-id.patch b/queue-4.5/rtc-rx8025-remove-rv8803-id.patch new file mode 100644 index 00000000000..9c764ee42f9 --- /dev/null +++ b/queue-4.5/rtc-rx8025-remove-rv8803-id.patch @@ -0,0 +1,30 @@ +From aaa3cee5deffa28415a6e1852c5afae0f5d210e2 Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Thu, 21 Jan 2016 13:24:21 +0100 +Subject: rtc: rx8025: remove rv8803 id + +From: Alexandre Belloni + +commit aaa3cee5deffa28415a6e1852c5afae0f5d210e2 upstream. + +The rv8803 has its own driver that should be used. Remove its id from +the rx8025 driver. + +Fixes: b1f9d790b59dc04f8813a49a92ddd8651770ffee +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-rx8025.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/rtc/rtc-rx8025.c ++++ b/drivers/rtc/rtc-rx8025.c +@@ -65,7 +65,6 @@ + + static const struct i2c_device_id rx8025_id[] = { + { "rx8025", 0 }, +- { "rv8803", 1 }, + { } + }; + MODULE_DEVICE_TABLE(i2c, rx8025_id); diff --git a/queue-4.5/rtc-vr41xx-wire-up-alarm_irq_enable.patch b/queue-4.5/rtc-vr41xx-wire-up-alarm_irq_enable.patch new file mode 100644 index 00000000000..f96a28d74cf --- /dev/null +++ b/queue-4.5/rtc-vr41xx-wire-up-alarm_irq_enable.patch @@ -0,0 +1,48 @@ +From a25f4a95ec3cded34c1250364eba704c5e4fdac4 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Tue, 1 Mar 2016 09:50:01 +0100 +Subject: rtc: vr41xx: Wire up alarm_irq_enable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +commit a25f4a95ec3cded34c1250364eba704c5e4fdac4 upstream. + +drivers/rtc/rtc-vr41xx.c:229: warning: ‘vr41xx_rtc_alarm_irq_enable’ defined but not used + +Apparently the conversion to alarm_irq_enable forgot to wire up the +callback. + +Fixes: 16380c153a69c378 ("RTC: Convert rtc drivers to use the alarm_irq_enable method") +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Alexandre Belloni +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/rtc/rtc-vr41xx.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/drivers/rtc/rtc-vr41xx.c ++++ b/drivers/rtc/rtc-vr41xx.c +@@ -272,12 +272,13 @@ static irqreturn_t rtclong1_interrupt(in + } + + static const struct rtc_class_ops vr41xx_rtc_ops = { +- .release = vr41xx_rtc_release, +- .ioctl = vr41xx_rtc_ioctl, +- .read_time = vr41xx_rtc_read_time, +- .set_time = vr41xx_rtc_set_time, +- .read_alarm = vr41xx_rtc_read_alarm, +- .set_alarm = vr41xx_rtc_set_alarm, ++ .release = vr41xx_rtc_release, ++ .ioctl = vr41xx_rtc_ioctl, ++ .read_time = vr41xx_rtc_read_time, ++ .set_time = vr41xx_rtc_set_time, ++ .read_alarm = vr41xx_rtc_read_alarm, ++ .set_alarm = vr41xx_rtc_set_alarm, ++ .alarm_irq_enable = vr41xx_rtc_alarm_irq_enable, + }; + + static int rtc_probe(struct platform_device *pdev) diff --git a/queue-4.5/scsi_dh-force-modular-build-if-scsi-is-a-module.patch b/queue-4.5/scsi_dh-force-modular-build-if-scsi-is-a-module.patch new file mode 100644 index 00000000000..e3f0668e3ab --- /dev/null +++ b/queue-4.5/scsi_dh-force-modular-build-if-scsi-is-a-module.patch @@ -0,0 +1,66 @@ +From 0c994c03c926d26ce48e6bbabbbe60366044fcae Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 27 Jan 2016 16:57:23 +0100 +Subject: scsi_dh: force modular build if SCSI is a module + +From: Arnd Bergmann + +commit 0c994c03c926d26ce48e6bbabbbe60366044fcae upstream. + +When the scsi_dh core was moved into the scsi core module, +CONFIG_SCSI_DH became a 'bool' option, and now anything depending on it +can be built-in even when CONFIG_SCSI=m. This of course cannot link +successfully: + +drivers/scsi/built-in.o: In function `rdac_init': +scsi_dh_alua.c:(.init.text+0x14): undefined reference to `scsi_register_device_handler' +scsi_dh_alua.c:(.init.text+0x64): undefined reference to `scsi_unregister_device_handler' +drivers/scsi/built-in.o: In function `alua_init': +scsi_dh_alua.c:(.init.text+0xb0): undefined reference to `scsi_register_device_handler' + +As a workaround, this adds an extra dependency on CONFIG_SCSI, so +Kconfig can figure out whether built-in is allowed or not. + +Signed-off-by: Arnd Bergmann +Fixes: 086b91d052eb ("scsi_dh: integrate into the core SCSI code") +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/device_handler/Kconfig | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/scsi/device_handler/Kconfig ++++ b/drivers/scsi/device_handler/Kconfig +@@ -13,13 +13,13 @@ menuconfig SCSI_DH + + config SCSI_DH_RDAC + tristate "LSI RDAC Device Handler" +- depends on SCSI_DH ++ depends on SCSI_DH && SCSI + help + If you have a LSI RDAC select y. Otherwise, say N. + + config SCSI_DH_HP_SW + tristate "HP/COMPAQ MSA Device Handler" +- depends on SCSI_DH ++ depends on SCSI_DH && SCSI + help + If you have a HP/COMPAQ MSA device that requires START_STOP to + be sent to start it and cannot upgrade the firmware then select y. +@@ -27,13 +27,13 @@ config SCSI_DH_HP_SW + + config SCSI_DH_EMC + tristate "EMC CLARiiON Device Handler" +- depends on SCSI_DH ++ depends on SCSI_DH && SCSI + help + If you have a EMC CLARiiON select y. Otherwise, say N. + + config SCSI_DH_ALUA + tristate "SPC-3 ALUA Device Handler" +- depends on SCSI_DH ++ depends on SCSI_DH && SCSI + help + SCSI Device handler for generic SPC-3 Asymmetric Logical Unit + Access (ALUA). diff --git a/queue-4.5/series b/queue-4.5/series index 8ed01305ee9..459e14dc964 100644 --- a/queue-4.5/series +++ b/queue-4.5/series @@ -135,3 +135,27 @@ numa-fix-proc-pid-numa_maps-for-thp.patch mm-vmscan-reclaim-highmem-zone-if-buffer_heads-is-over-limit.patch mm-hwpoison-fix-wrong-num_poisoned_pages-accounting.patch usb-usbip-fix-potential-out-of-bounds-write.patch +locking-mcs-fix-mcs_spin_lock-ordering.patch +spi-rockchip-make-sure-spi-clk-is-on-in-rockchip_spi_set_cs.patch +irqchip-sunxi-nmi-fix-error-check-of-of_io_request_and_map.patch +irqchip-mxs-fix-error-check-of-of_io_request_and_map.patch +regulator-s5m8767-fix-get_register-error-handling.patch +paride-make-verbose-parameter-an-int-again.patch +scsi_dh-force-modular-build-if-scsi-is-a-module.patch +fbdev-da8xx-fb-fix-videomodes-of-lcd-panels.patch +lib-mpi-endianness-fix.patch +misc-bmp085-enable-building-as-a-module.patch +misc-mic-scif-fix-wrap-around-tests.patch +pm-opp-initialize-u_volt_min-max-to-a-valid-value.patch +pm-domains-fix-removal-of-a-subdomain.patch +rtc-hym8563-fix-invalid-year-calculation.patch +rtc-vr41xx-wire-up-alarm_irq_enable.patch +rtc-ds1685-passing-bogus-values-to-irq_restore.patch +rtc-rx8025-remove-rv8803-id.patch +rtc-max77686-properly-handle-regmap_irq_get_virq-error-code.patch +drivers-misc-ad525x_dpot-ad5274-fix-rdac-read-back-errors.patch +perf-evlist-reference-count-the-cpu-and-thread-maps-at-set_maps.patch +perf-tools-fix-perf-script-python-database-export-crash.patch +spi-rockchip-modify-dma-max-burst-to-1.patch +x86-mm-kmmio-fix-mmiotrace-for-hugepages.patch +ext4-fix-null-pointer-dereference-in-ext4_mark_inode_dirty.patch diff --git a/queue-4.5/spi-rockchip-make-sure-spi-clk-is-on-in-rockchip_spi_set_cs.patch b/queue-4.5/spi-rockchip-make-sure-spi-clk-is-on-in-rockchip_spi_set_cs.patch new file mode 100644 index 00000000000..7f955497a11 --- /dev/null +++ b/queue-4.5/spi-rockchip-make-sure-spi-clk-is-on-in-rockchip_spi_set_cs.patch @@ -0,0 +1,46 @@ +From b920cc3191d7612f26f36ee494e05b5ffd9044c0 Mon Sep 17 00:00:00 2001 +From: Huibin Hong +Date: Wed, 24 Feb 2016 18:00:04 +0800 +Subject: spi/rockchip: Make sure spi clk is on in rockchip_spi_set_cs + +From: Huibin Hong + +commit b920cc3191d7612f26f36ee494e05b5ffd9044c0 upstream. + +Rockchip_spi_set_cs could be called by spi_setup, but +spi_setup may be called by device driver after runtime suspend. +Then the spi clock is closed, rockchip_spi_set_cs may access the +spi registers, which causes cpu block in some socs. + +Fixes: 64e36824b32 ("spi/rockchip: add driver for Rockchip RK3xxx") +Signed-off-by: Huibin Hong +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-rockchip.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/drivers/spi/spi-rockchip.c ++++ b/drivers/spi/spi-rockchip.c +@@ -265,7 +265,10 @@ static inline u32 rx_max(struct rockchip + static void rockchip_spi_set_cs(struct spi_device *spi, bool enable) + { + u32 ser; +- struct rockchip_spi *rs = spi_master_get_devdata(spi->master); ++ struct spi_master *master = spi->master; ++ struct rockchip_spi *rs = spi_master_get_devdata(master); ++ ++ pm_runtime_get_sync(rs->dev); + + ser = readl_relaxed(rs->regs + ROCKCHIP_SPI_SER) & SER_MASK; + +@@ -290,6 +293,8 @@ static void rockchip_spi_set_cs(struct s + ser &= ~(1 << spi->chip_select); + + writel_relaxed(ser, rs->regs + ROCKCHIP_SPI_SER); ++ ++ pm_runtime_put_sync(rs->dev); + } + + static int rockchip_spi_prepare_message(struct spi_master *master, diff --git a/queue-4.5/spi-rockchip-modify-dma-max-burst-to-1.patch b/queue-4.5/spi-rockchip-modify-dma-max-burst-to-1.patch new file mode 100644 index 00000000000..fbc2b048726 --- /dev/null +++ b/queue-4.5/spi-rockchip-modify-dma-max-burst-to-1.patch @@ -0,0 +1,72 @@ +From 80abf8880cc6e1594c11b7c417f22dde60e25312 Mon Sep 17 00:00:00 2001 +From: Addy Ke +Date: Fri, 22 Jan 2016 19:06:52 +0800 +Subject: spi: rockchip: modify DMA max burst to 1 + +From: Addy Ke + +commit 80abf8880cc6e1594c11b7c417f22dde60e25312 upstream. + +Generic dma controller on Rockchips' platform cannot support +DMAFLUSHP instruction which make dma to flush the req of non-aligned +or non-multiple of what we need. That will cause an unrecoverable +dma bus error. The saftest way is to set dma max burst to 1. + +Signed-off-by: Addy ke +Fixes: 64e36824b32b06 ("spi/rockchip: add driver for Rockchip...") +Signed-off-by: Shawn Lin +cc: Heiko Stuebner +cc: Olof Johansson +cc: Doug Anderson +cc: Sonny Rao +Acked-by: Mark Brown +Signed-off-by: Caesar Wang +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/spi/spi-rockchip.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/spi/spi-rockchip.c ++++ b/drivers/spi/spi-rockchip.c +@@ -199,6 +199,7 @@ struct rockchip_spi { + struct sg_table rx_sg; + struct rockchip_spi_dma_data dma_rx; + struct rockchip_spi_dma_data dma_tx; ++ struct dma_slave_caps dma_caps; + }; + + static inline void spi_enable_chip(struct rockchip_spi *rs, int enable) +@@ -454,7 +455,10 @@ static void rockchip_spi_prepare_dma(str + rxconf.direction = rs->dma_rx.direction; + rxconf.src_addr = rs->dma_rx.addr; + rxconf.src_addr_width = rs->n_bytes; +- rxconf.src_maxburst = rs->n_bytes; ++ if (rs->dma_caps.max_burst > 4) ++ rxconf.src_maxburst = 4; ++ else ++ rxconf.src_maxburst = 1; + dmaengine_slave_config(rs->dma_rx.ch, &rxconf); + + rxdesc = dmaengine_prep_slave_sg( +@@ -471,7 +475,10 @@ static void rockchip_spi_prepare_dma(str + txconf.direction = rs->dma_tx.direction; + txconf.dst_addr = rs->dma_tx.addr; + txconf.dst_addr_width = rs->n_bytes; +- txconf.dst_maxburst = rs->n_bytes; ++ if (rs->dma_caps.max_burst > 4) ++ txconf.dst_maxburst = 4; ++ else ++ txconf.dst_maxburst = 1; + dmaengine_slave_config(rs->dma_tx.ch, &txconf); + + txdesc = dmaengine_prep_slave_sg( +@@ -735,6 +742,7 @@ static int rockchip_spi_probe(struct pla + } + + if (rs->dma_tx.ch && rs->dma_rx.ch) { ++ dma_get_slave_caps(rs->dma_rx.ch, &(rs->dma_caps)); + rs->dma_tx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_TXDR); + rs->dma_rx.addr = (dma_addr_t)(mem->start + ROCKCHIP_SPI_RXDR); + rs->dma_tx.direction = DMA_MEM_TO_DEV; diff --git a/queue-4.5/x86-mm-kmmio-fix-mmiotrace-for-hugepages.patch b/queue-4.5/x86-mm-kmmio-fix-mmiotrace-for-hugepages.patch new file mode 100644 index 00000000000..31cc142647f --- /dev/null +++ b/queue-4.5/x86-mm-kmmio-fix-mmiotrace-for-hugepages.patch @@ -0,0 +1,281 @@ +From cfa52c0cfa4d727aa3e457bf29aeff296c528a08 Mon Sep 17 00:00:00 2001 +From: Karol Herbst +Date: Thu, 3 Mar 2016 02:03:11 +0100 +Subject: x86/mm/kmmio: Fix mmiotrace for hugepages + +From: Karol Herbst + +commit cfa52c0cfa4d727aa3e457bf29aeff296c528a08 upstream. + +Because Linux might use bigger pages than the 4K pages to handle those mmio +ioremaps, the kmmio code shouldn't rely on the pade id as it currently does. + +Using the memory address instead of the page id lets us look up how big the +page is and what its base address is, so that we won't get a page fault +within the same page twice anymore. + +Tested-by: Pierre Moreau +Signed-off-by: Karol Herbst +Cc: Andrew Morton +Cc: Andy Lutomirski +Cc: Borislav Petkov +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: H. Peter Anvin +Cc: Linus Torvalds +Cc: Luis R. Rodriguez +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Toshi Kani +Cc: linux-mm@kvack.org +Cc: linux-x86_64@vger.kernel.org +Cc: nouveau@lists.freedesktop.org +Cc: pq@iki.fi +Cc: rostedt@goodmis.org +Link: http://lkml.kernel.org/r/1456966991-6861-1-git-send-email-nouveau@karolherbst.de +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/kmmio.c | 88 ++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 59 insertions(+), 29 deletions(-) + +--- a/arch/x86/mm/kmmio.c ++++ b/arch/x86/mm/kmmio.c +@@ -33,7 +33,7 @@ + struct kmmio_fault_page { + struct list_head list; + struct kmmio_fault_page *release_next; +- unsigned long page; /* location of the fault page */ ++ unsigned long addr; /* the requested address */ + pteval_t old_presence; /* page presence prior to arming */ + bool armed; + +@@ -70,9 +70,16 @@ unsigned int kmmio_count; + static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE]; + static LIST_HEAD(kmmio_probes); + +-static struct list_head *kmmio_page_list(unsigned long page) ++static struct list_head *kmmio_page_list(unsigned long addr) + { +- return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)]; ++ unsigned int l; ++ pte_t *pte = lookup_address(addr, &l); ++ ++ if (!pte) ++ return NULL; ++ addr &= page_level_mask(l); ++ ++ return &kmmio_page_table[hash_long(addr, KMMIO_PAGE_HASH_BITS)]; + } + + /* Accessed per-cpu */ +@@ -98,15 +105,19 @@ static struct kmmio_probe *get_kmmio_pro + } + + /* You must be holding RCU read lock. */ +-static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page) ++static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long addr) + { + struct list_head *head; + struct kmmio_fault_page *f; ++ unsigned int l; ++ pte_t *pte = lookup_address(addr, &l); + +- page &= PAGE_MASK; +- head = kmmio_page_list(page); ++ if (!pte) ++ return NULL; ++ addr &= page_level_mask(l); ++ head = kmmio_page_list(addr); + list_for_each_entry_rcu(f, head, list) { +- if (f->page == page) ++ if (f->addr == addr) + return f; + } + return NULL; +@@ -137,10 +148,10 @@ static void clear_pte_presence(pte_t *pt + static int clear_page_presence(struct kmmio_fault_page *f, bool clear) + { + unsigned int level; +- pte_t *pte = lookup_address(f->page, &level); ++ pte_t *pte = lookup_address(f->addr, &level); + + if (!pte) { +- pr_err("no pte for page 0x%08lx\n", f->page); ++ pr_err("no pte for addr 0x%08lx\n", f->addr); + return -1; + } + +@@ -156,7 +167,7 @@ static int clear_page_presence(struct km + return -1; + } + +- __flush_tlb_one(f->page); ++ __flush_tlb_one(f->addr); + return 0; + } + +@@ -176,12 +187,12 @@ static int arm_kmmio_fault_page(struct k + int ret; + WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n")); + if (f->armed) { +- pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n", +- f->page, f->count, !!f->old_presence); ++ pr_warning("double-arm: addr 0x%08lx, ref %d, old %d\n", ++ f->addr, f->count, !!f->old_presence); + } + ret = clear_page_presence(f, true); +- WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"), +- f->page); ++ WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming at 0x%08lx failed.\n"), ++ f->addr); + f->armed = true; + return ret; + } +@@ -191,7 +202,7 @@ static void disarm_kmmio_fault_page(stru + { + int ret = clear_page_presence(f, false); + WARN_ONCE(ret < 0, +- KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page); ++ KERN_ERR "kmmio disarming at 0x%08lx failed.\n", f->addr); + f->armed = false; + } + +@@ -215,6 +226,12 @@ int kmmio_handler(struct pt_regs *regs, + struct kmmio_context *ctx; + struct kmmio_fault_page *faultpage; + int ret = 0; /* default to fault not handled */ ++ unsigned long page_base = addr; ++ unsigned int l; ++ pte_t *pte = lookup_address(addr, &l); ++ if (!pte) ++ return -EINVAL; ++ page_base &= page_level_mask(l); + + /* + * Preemption is now disabled to prevent process switch during +@@ -227,7 +244,7 @@ int kmmio_handler(struct pt_regs *regs, + preempt_disable(); + rcu_read_lock(); + +- faultpage = get_kmmio_fault_page(addr); ++ faultpage = get_kmmio_fault_page(page_base); + if (!faultpage) { + /* + * Either this page fault is not caused by kmmio, or +@@ -239,7 +256,7 @@ int kmmio_handler(struct pt_regs *regs, + + ctx = &get_cpu_var(kmmio_ctx); + if (ctx->active) { +- if (addr == ctx->addr) { ++ if (page_base == ctx->addr) { + /* + * A second fault on the same page means some other + * condition needs handling by do_page_fault(), the +@@ -267,9 +284,9 @@ int kmmio_handler(struct pt_regs *regs, + ctx->active++; + + ctx->fpage = faultpage; +- ctx->probe = get_kmmio_probe(addr); ++ ctx->probe = get_kmmio_probe(page_base); + ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF)); +- ctx->addr = addr; ++ ctx->addr = page_base; + + if (ctx->probe && ctx->probe->pre_handler) + ctx->probe->pre_handler(ctx->probe, regs, addr); +@@ -354,12 +371,11 @@ out: + } + + /* You must be holding kmmio_lock. */ +-static int add_kmmio_fault_page(unsigned long page) ++static int add_kmmio_fault_page(unsigned long addr) + { + struct kmmio_fault_page *f; + +- page &= PAGE_MASK; +- f = get_kmmio_fault_page(page); ++ f = get_kmmio_fault_page(addr); + if (f) { + if (!f->count) + arm_kmmio_fault_page(f); +@@ -372,26 +388,25 @@ static int add_kmmio_fault_page(unsigned + return -1; + + f->count = 1; +- f->page = page; ++ f->addr = addr; + + if (arm_kmmio_fault_page(f)) { + kfree(f); + return -1; + } + +- list_add_rcu(&f->list, kmmio_page_list(f->page)); ++ list_add_rcu(&f->list, kmmio_page_list(f->addr)); + + return 0; + } + + /* You must be holding kmmio_lock. */ +-static void release_kmmio_fault_page(unsigned long page, ++static void release_kmmio_fault_page(unsigned long addr, + struct kmmio_fault_page **release_list) + { + struct kmmio_fault_page *f; + +- page &= PAGE_MASK; +- f = get_kmmio_fault_page(page); ++ f = get_kmmio_fault_page(addr); + if (!f) + return; + +@@ -420,18 +435,27 @@ int register_kmmio_probe(struct kmmio_pr + int ret = 0; + unsigned long size = 0; + const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); ++ unsigned int l; ++ pte_t *pte; + + spin_lock_irqsave(&kmmio_lock, flags); + if (get_kmmio_probe(p->addr)) { + ret = -EEXIST; + goto out; + } ++ ++ pte = lookup_address(p->addr, &l); ++ if (!pte) { ++ ret = -EINVAL; ++ goto out; ++ } ++ + kmmio_count++; + list_add_rcu(&p->list, &kmmio_probes); + while (size < size_lim) { + if (add_kmmio_fault_page(p->addr + size)) + pr_err("Unable to set page fault.\n"); +- size += PAGE_SIZE; ++ size += page_level_size(l); + } + out: + spin_unlock_irqrestore(&kmmio_lock, flags); +@@ -506,11 +530,17 @@ void unregister_kmmio_probe(struct kmmio + const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK); + struct kmmio_fault_page *release_list = NULL; + struct kmmio_delayed_release *drelease; ++ unsigned int l; ++ pte_t *pte; ++ ++ pte = lookup_address(p->addr, &l); ++ if (!pte) ++ return; + + spin_lock_irqsave(&kmmio_lock, flags); + while (size < size_lim) { + release_kmmio_fault_page(p->addr + size, &release_list); +- size += PAGE_SIZE; ++ size += page_level_size(l); + } + list_del_rcu(&p->list); + kmmio_count--;