From: Greg Kroah-Hartman Date: Fri, 4 Mar 2016 01:42:40 +0000 (-0800) Subject: 4.4-stable patches X-Git-Tag: v3.10.100~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7f14421203e7d8133bf4f66aaa50ab7c8589d969;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm-arm64-kvm-fix-ioctl-error-handling.patch block-initialize-max_dev_sectors-to-0.patch btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch btrfs-fix-no_space-in-write-and-rm-loop.patch cifs-fix-out-of-bounds-access-in-lease-parsing.patch cifs-fix-smb2-interim-response-processing-for-read-requests.patch drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch fbcon-set-a-default-value-to-blink-interval.patch fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch iommu-amd-apply-workaround-for-ats-write-permission-check.patch iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch kvm-x86-update-tsc-multiplier-on-change.patch mips-kvm-fix-ioctl-error-handling.patch parisc-fix-ptrace-syscall-number-and-return-value-modification.patch pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch vfio-fix-ioctl-error-handling.patch --- diff --git a/queue-4.4/arm-arm64-kvm-fix-ioctl-error-handling.patch b/queue-4.4/arm-arm64-kvm-fix-ioctl-error-handling.patch new file mode 100644 index 00000000000..507fd8471b9 --- /dev/null +++ b/queue-4.4/arm-arm64-kvm-fix-ioctl-error-handling.patch @@ -0,0 +1,51 @@ +From 4cad67fca3fc952d6f2ed9e799621f07666a560f Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 28 Feb 2016 17:32:07 +0200 +Subject: arm/arm64: KVM: Fix ioctl error handling + +From: Michael S. Tsirkin + +commit 4cad67fca3fc952d6f2ed9e799621f07666a560f upstream. + +Calling return copy_to_user(...) in an ioctl will not +do the right thing if there's a pagefault: +copy_to_user returns the number of bytes not copied +in this case. + +Fix up kvm to do + return copy_to_user(...)) ? -EFAULT : 0; + +everywhere. + +Acked-by: Christoffer Dall +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kvm/guest.c | 2 +- + arch/arm64/kvm/guest.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/kvm/guest.c ++++ b/arch/arm/kvm/guest.c +@@ -155,7 +155,7 @@ static int get_timer_reg(struct kvm_vcpu + u64 val; + + val = kvm_arm_timer_get_reg(vcpu, reg->id); +- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); ++ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0; + } + + static unsigned long num_core_regs(void) +--- a/arch/arm64/kvm/guest.c ++++ b/arch/arm64/kvm/guest.c +@@ -186,7 +186,7 @@ static int get_timer_reg(struct kvm_vcpu + u64 val; + + val = kvm_arm_timer_get_reg(vcpu, reg->id); +- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)); ++ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0; + } + + /** diff --git a/queue-4.4/block-initialize-max_dev_sectors-to-0.patch b/queue-4.4/block-initialize-max_dev_sectors-to-0.patch new file mode 100644 index 00000000000..9546bf7a141 --- /dev/null +++ b/queue-4.4/block-initialize-max_dev_sectors-to-0.patch @@ -0,0 +1,36 @@ +From 5f009d3f8e6685fe8c6215082c1696a08b411220 Mon Sep 17 00:00:00 2001 +From: Keith Busch +Date: Wed, 10 Feb 2016 16:52:47 -0700 +Subject: block: Initialize max_dev_sectors to 0 + +From: Keith Busch + +commit 5f009d3f8e6685fe8c6215082c1696a08b411220 upstream. + +The new queue limit is not used by the majority of block drivers, and +should be initialized to 0 for the driver's requested settings to be used. + +Signed-off-by: Keith Busch +Acked-by: Martin K. Petersen +Reviewed-by: Sagi Grimberg +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-settings.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -91,8 +91,8 @@ void blk_set_default_limits(struct queue + lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK; + lim->virt_boundary_mask = 0; + lim->max_segment_size = BLK_MAX_SEGMENT_SIZE; +- lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors = +- BLK_SAFE_MAX_SECTORS; ++ lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS; ++ lim->max_dev_sectors = 0; + lim->chunk_sectors = 0; + lim->max_write_same_sectors = 0; + lim->max_discard_sectors = 0; diff --git a/queue-4.4/btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch b/queue-4.4/btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch new file mode 100644 index 00000000000..25c4845c564 --- /dev/null +++ b/queue-4.4/btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch @@ -0,0 +1,36 @@ +From 0a95b851370b84a4b9d92ee6d1fa0926901d0454 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Fri, 22 Jan 2016 09:28:38 +0800 +Subject: btrfs: async-thread: Fix a use-after-free error for trace + +From: Qu Wenruo + +commit 0a95b851370b84a4b9d92ee6d1fa0926901d0454 upstream. + +Parameter of trace_btrfs_work_queued() can be freed in its workqueue. +So no one use use that pointer after queue_work(). + +Fix the user-after-free bug by move the trace line before queue_work(). + +Reported-by: Dave Jones +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/async-thread.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/async-thread.c ++++ b/fs/btrfs/async-thread.c +@@ -328,8 +328,8 @@ static inline void __btrfs_queue_work(st + list_add_tail(&work->ordered_list, &wq->ordered_list); + spin_unlock_irqrestore(&wq->list_lock, flags); + } +- queue_work(wq->normal_wq, &work->normal_work); + trace_btrfs_work_queued(work); ++ queue_work(wq->normal_wq, &work->normal_work); + } + + void btrfs_queue_work(struct btrfs_workqueue *wq, diff --git a/queue-4.4/btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch b/queue-4.4/btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch new file mode 100644 index 00000000000..2519f3204f5 --- /dev/null +++ b/queue-4.4/btrfs-fix-deadlock-running-delayed-iputs-at-transaction-commit-time.patch @@ -0,0 +1,238 @@ +From c2d6cb1636d235257086f939a8194ef0bf93af6e Mon Sep 17 00:00:00 2001 +From: Filipe Manana +Date: Fri, 15 Jan 2016 11:05:12 +0000 +Subject: Btrfs: fix deadlock running delayed iputs at transaction commit time + +From: Filipe Manana + +commit c2d6cb1636d235257086f939a8194ef0bf93af6e upstream. + +While running a stress test I ran into a deadlock when running the delayed +iputs at transaction time, which produced the following report and trace: + +[ 886.399989] ============================================= +[ 886.400871] [ INFO: possible recursive locking detected ] +[ 886.401663] 4.4.0-rc6-btrfs-next-18+ #1 Not tainted +[ 886.402384] --------------------------------------------- +[ 886.403182] fio/8277 is trying to acquire lock: +[ 886.403568] (&fs_info->delayed_iput_sem){++++..}, at: [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.403568] +[ 886.403568] but task is already holding lock: +[ 886.403568] (&fs_info->delayed_iput_sem){++++..}, at: [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.403568] +[ 886.403568] other info that might help us debug this: +[ 886.403568] Possible unsafe locking scenario: +[ 886.403568] +[ 886.403568] CPU0 +[ 886.403568] ---- +[ 886.403568] lock(&fs_info->delayed_iput_sem); +[ 886.403568] lock(&fs_info->delayed_iput_sem); +[ 886.403568] +[ 886.403568] *** DEADLOCK *** +[ 886.403568] +[ 886.403568] May be due to missing lock nesting notation +[ 886.403568] +[ 886.403568] 3 locks held by fio/8277: +[ 886.403568] #0: (sb_writers#11){.+.+.+}, at: [] __sb_start_write+0x5f/0xb0 +[ 886.403568] #1: (&sb->s_type->i_mutex_key#15){+.+.+.}, at: [] btrfs_file_write_iter+0x73/0x408 [btrfs] +[ 886.403568] #2: (&fs_info->delayed_iput_sem){++++..}, at: [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.403568] +[ 886.403568] stack backtrace: +[ 886.403568] CPU: 6 PID: 8277 Comm: fio Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[ 886.403568] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS by qemu-project.org 04/01/2014 +[ 886.403568] 0000000000000000 ffff88009f80f770 ffffffff8125d4fd ffffffff82af1fc0 +[ 886.403568] ffff88009f80f830 ffffffff8108e5f9 0000000200000000 ffff88009fd92290 +[ 886.403568] 0000000000000000 ffffffff82af1fc0 ffffffff829cfb01 00042b216d008804 +[ 886.403568] Call Trace: +[ 886.403568] [] dump_stack+0x4e/0x79 +[ 886.403568] [] __lock_acquire+0xd42/0xf0b +[ 886.403568] [] ? __module_address+0xdf/0x108 +[ 886.403568] [] lock_acquire+0x10d/0x194 +[ 886.403568] [] ? lock_acquire+0x10d/0x194 +[ 886.403568] [] ? btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.489542] [] down_read+0x3e/0x4d +[ 886.489542] [] ? btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.489542] [] btrfs_run_delayed_iputs+0x36/0xbf [btrfs] +[ 886.489542] [] btrfs_commit_transaction+0x8f5/0x96e [btrfs] +[ 886.489542] [] flush_space+0x435/0x44a [btrfs] +[ 886.489542] [] ? reserve_metadata_bytes+0x26a/0x384 [btrfs] +[ 886.489542] [] reserve_metadata_bytes+0x28d/0x384 [btrfs] +[ 886.489542] [] ? btrfs_block_rsv_refill+0x58/0x96 [btrfs] +[ 886.489542] [] btrfs_block_rsv_refill+0x70/0x96 [btrfs] +[ 886.489542] [] btrfs_evict_inode+0x394/0x55a [btrfs] +[ 886.489542] [] evict+0xa7/0x15c +[ 886.489542] [] iput+0x1d3/0x266 +[ 886.489542] [] btrfs_run_delayed_iputs+0x8f/0xbf [btrfs] +[ 886.489542] [] btrfs_commit_transaction+0x8f5/0x96e [btrfs] +[ 886.489542] [] ? signal_pending_state+0x31/0x31 +[ 886.489542] [] btrfs_alloc_data_chunk_ondemand+0x1d7/0x288 [btrfs] +[ 886.489542] [] btrfs_check_data_free_space+0x40/0x59 [btrfs] +[ 886.489542] [] btrfs_delalloc_reserve_space+0x1e/0x4e [btrfs] +[ 886.489542] [] btrfs_direct_IO+0x10c/0x27e [btrfs] +[ 886.489542] [] generic_file_direct_write+0xb3/0x128 +[ 886.489542] [] btrfs_file_write_iter+0x229/0x408 [btrfs] +[ 886.489542] [] ? __lock_is_held+0x38/0x50 +[ 886.489542] [] __vfs_write+0x7c/0xa5 +[ 886.489542] [] vfs_write+0xa0/0xe4 +[ 886.489542] [] SyS_write+0x50/0x7e +[ 886.489542] [] entry_SYSCALL_64_fastpath+0x12/0x6f +[ 1081.852335] INFO: task fio:8244 blocked for more than 120 seconds. +[ 1081.854348] Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[ 1081.857560] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 1081.863227] fio D ffff880213f9bb28 0 8244 8240 0x00000000 +[ 1081.868719] ffff880213f9bb28 00ffffff810fc6b0 ffffffff0000000a ffff88023ed55240 +[ 1081.872499] ffff880206b5d400 ffff880213f9c000 ffff88020a4d5318 ffff880206b5d400 +[ 1081.876834] ffffffff00000001 ffff880206b5d400 ffff880213f9bb40 ffffffff81482ba4 +[ 1081.880782] Call Trace: +[ 1081.881793] [] schedule+0x7f/0x97 +[ 1081.883340] [] rwsem_down_write_failed+0x2d5/0x325 +[ 1081.895525] [] ? trace_hardirqs_on_caller+0x16/0x1ab +[ 1081.897419] [] call_rwsem_down_write_failed+0x13/0x20 +[ 1081.899251] [] ? call_rwsem_down_write_failed+0x13/0x20 +[ 1081.901063] [] ? __down_write_nested.isra.0+0x1f/0x21 +[ 1081.902365] [] down_write+0x43/0x57 +[ 1081.903846] [] ? btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1081.906078] [] btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1081.908846] [] ? mark_held_locks+0x56/0x6c +[ 1081.910409] [] btrfs_check_data_free_space+0x40/0x59 [btrfs] +[ 1081.912482] [] btrfs_delalloc_reserve_space+0x1e/0x4e [btrfs] +[ 1081.914597] [] btrfs_direct_IO+0x10c/0x27e [btrfs] +[ 1081.919037] [] generic_file_direct_write+0xb3/0x128 +[ 1081.920754] [] btrfs_file_write_iter+0x229/0x408 [btrfs] +[ 1081.922496] [] ? __lock_is_held+0x38/0x50 +[ 1081.923922] [] __vfs_write+0x7c/0xa5 +[ 1081.925275] [] vfs_write+0xa0/0xe4 +[ 1081.926584] [] SyS_write+0x50/0x7e +[ 1081.927968] [] entry_SYSCALL_64_fastpath+0x12/0x6f +[ 1081.985293] INFO: lockdep is turned off. +[ 1081.986132] INFO: task fio:8249 blocked for more than 120 seconds. +[ 1081.987434] Not tainted 4.4.0-rc6-btrfs-next-18+ #1 +[ 1081.988534] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +[ 1081.990147] fio D ffff880218febbb8 0 8249 8240 0x00000000 +[ 1081.991626] ffff880218febbb8 00ffffff81486b8e ffff88020000000b ffff88023ed75240 +[ 1081.993258] ffff8802120a9a00 ffff880218fec000 ffff88020a4d5318 ffff8802120a9a00 +[ 1081.994850] ffffffff00000001 ffff8802120a9a00 ffff880218febbd0 ffffffff81482ba4 +[ 1081.996485] Call Trace: +[ 1081.997037] [] schedule+0x7f/0x97 +[ 1081.998017] [] rwsem_down_write_failed+0x2d5/0x325 +[ 1081.999241] [] ? finish_wait+0x6d/0x76 +[ 1082.000306] [] call_rwsem_down_write_failed+0x13/0x20 +[ 1082.001533] [] ? call_rwsem_down_write_failed+0x13/0x20 +[ 1082.002776] [] ? __down_write_nested.isra.0+0x1f/0x21 +[ 1082.003995] [] down_write+0x43/0x57 +[ 1082.005000] [] ? btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1082.007403] [] btrfs_alloc_data_chunk_ondemand+0x1f6/0x288 [btrfs] +[ 1082.008988] [] btrfs_fallocate+0x7c1/0xc2f [btrfs] +[ 1082.010193] [] ? percpu_down_read+0x4e/0x77 +[ 1082.011280] [] ? __sb_start_write+0x5f/0xb0 +[ 1082.012265] [] ? __sb_start_write+0x5f/0xb0 +[ 1082.013021] [] vfs_fallocate+0x170/0x1ff +[ 1082.013738] [] ioctl_preallocate+0x89/0x9b +[ 1082.014778] [] do_vfs_ioctl+0x40a/0x4ea +[ 1082.015778] [] ? SYSC_newfstat+0x25/0x2e +[ 1082.016806] [] ? __fget_light+0x4d/0x71 +[ 1082.017789] [] SyS_ioctl+0x57/0x79 +[ 1082.018706] [] entry_SYSCALL_64_fastpath+0x12/0x6f + +This happens because we can recursively acquire the semaphore +fs_info->delayed_iput_sem when attempting to allocate space to satisfy +a file write request as shown in the first trace above - when committing +a transaction we acquire (down_read) the semaphore before running the +delayed iputs, and when running a delayed iput() we can end up calling +an inode's eviction handler, which in turn commits another transaction +and attempts to acquire (down_read) again the semaphore to run more +delayed iput operations. +This results in a deadlock because if a task acquires multiple times a +semaphore it should invoke down_read_nested() with a different lockdep +class for each level of recursion. + +Fix this by simplifying the implementation and use a mutex instead that +is acquired by the cleaner kthread before it runs the delayed iputs +instead of always acquiring a semaphore before delayed references are +run from anywhere. + +Fixes: d7c151717a1e (btrfs: Fix NO_SPACE bug caused by delayed-iput) +Signed-off-by: Filipe Manana +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/ctree.h | 2 +- + fs/btrfs/disk-io.c | 5 ++++- + fs/btrfs/extent-tree.c | 9 +++++---- + fs/btrfs/inode.c | 4 ---- + 4 files changed, 10 insertions(+), 10 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -1572,7 +1572,7 @@ struct btrfs_fs_info { + + spinlock_t delayed_iput_lock; + struct list_head delayed_iputs; +- struct rw_semaphore delayed_iput_sem; ++ struct mutex cleaner_delayed_iput_mutex; + + /* this protects tree_mod_seq_list */ + spinlock_t tree_mod_seq_lock; +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -1796,7 +1796,10 @@ static int cleaner_kthread(void *arg) + goto sleep; + } + ++ mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex); + btrfs_run_delayed_iputs(root); ++ mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex); ++ + again = btrfs_clean_one_deleted_snapshot(root); + mutex_unlock(&root->fs_info->cleaner_mutex); + +@@ -2556,8 +2559,8 @@ int open_ctree(struct super_block *sb, + mutex_init(&fs_info->delete_unused_bgs_mutex); + mutex_init(&fs_info->reloc_mutex); + mutex_init(&fs_info->delalloc_root_mutex); ++ mutex_init(&fs_info->cleaner_delayed_iput_mutex); + seqlock_init(&fs_info->profiles_lock); +- init_rwsem(&fs_info->delayed_iput_sem); + + INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); + INIT_LIST_HEAD(&fs_info->space_info); +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -4100,11 +4100,12 @@ commit_trans: + if (ret) + return ret; + /* +- * make sure that all running delayed iput are +- * done ++ * The cleaner kthread might still be doing iput ++ * operations. Wait for it to finish so that ++ * more space is released. + */ +- down_write(&root->fs_info->delayed_iput_sem); +- up_write(&root->fs_info->delayed_iput_sem); ++ mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex); ++ mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex); + goto again; + } else { + btrfs_end_transaction(trans, root); +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -3142,8 +3142,6 @@ void btrfs_run_delayed_iputs(struct btrf + if (empty) + return; + +- down_read(&fs_info->delayed_iput_sem); +- + spin_lock(&fs_info->delayed_iput_lock); + list_splice_init(&fs_info->delayed_iputs, &list); + spin_unlock(&fs_info->delayed_iput_lock); +@@ -3154,8 +3152,6 @@ void btrfs_run_delayed_iputs(struct btrf + iput(delayed->inode); + kfree(delayed); + } +- +- up_read(&root->fs_info->delayed_iput_sem); + } + + /* diff --git a/queue-4.4/btrfs-fix-no_space-in-write-and-rm-loop.patch b/queue-4.4/btrfs-fix-no_space-in-write-and-rm-loop.patch new file mode 100644 index 00000000000..6197e535a41 --- /dev/null +++ b/queue-4.4/btrfs-fix-no_space-in-write-and-rm-loop.patch @@ -0,0 +1,47 @@ +From e1746e8381cd2af421f75557b5cae3604fc18b35 Mon Sep 17 00:00:00 2001 +From: Zhao Lei +Date: Tue, 1 Dec 2015 18:39:40 +0800 +Subject: btrfs: Fix no_space in write and rm loop + +From: Zhao Lei + +commit e1746e8381cd2af421f75557b5cae3604fc18b35 upstream. + +I see no_space in v4.4-rc1 again in xfstests generic/102. +It happened randomly in some node only. +(one of 4 phy-node, and a kvm with non-virtio block driver) + +By bisect, we can found the first-bad is: + commit bdced438acd8 ("block: setup bi_phys_segments after splitting")' +But above patch only triggered the bug by making bio operation +faster(or slower). + +Main reason is in our space_allocating code, we need to commit +page writeback before wait it complish, this patch fixed above +bug. + +BTW, there is another reason for generic/102 fail, caused by +disable default mixed-blockgroup, I'll fix it in xfstests. + +Signed-off-by: Zhao Lei +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/extent-tree.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -4086,8 +4086,10 @@ commit_trans: + !atomic_read(&root->fs_info->open_ioctl_trans)) { + need_commit--; + +- if (need_commit > 0) ++ if (need_commit > 0) { ++ btrfs_start_delalloc_roots(fs_info, 0, -1); + btrfs_wait_ordered_roots(fs_info, -1); ++ } + + trans = btrfs_join_transaction(root); + if (IS_ERR(trans)) diff --git a/queue-4.4/cifs-fix-out-of-bounds-access-in-lease-parsing.patch b/queue-4.4/cifs-fix-out-of-bounds-access-in-lease-parsing.patch new file mode 100644 index 00000000000..f29a9f1984d --- /dev/null +++ b/queue-4.4/cifs-fix-out-of-bounds-access-in-lease-parsing.patch @@ -0,0 +1,104 @@ +From deb7deff2f00bdbbcb3d560dad2a89ef37df837d Mon Sep 17 00:00:00 2001 +From: Justin Maggard +Date: Tue, 9 Feb 2016 15:52:08 -0800 +Subject: cifs: fix out-of-bounds access in lease parsing + +From: Justin Maggard + +commit deb7deff2f00bdbbcb3d560dad2a89ef37df837d upstream. + +When opening a file, SMB2_open() attempts to parse the lease state from the +SMB2 CREATE Response. However, the parsing code was not careful to ensure +that the create contexts are not empty or invalid, which can lead to out- +of-bounds memory access. This can be seen easily by trying +to read a file from a OSX 10.11 SMB3 server. Here is sample crash output: + +BUG: unable to handle kernel paging request at ffff8800a1a77cc6 +IP: [] SMB2_open+0x804/0x960 +PGD 8f77067 PUD 0 +Oops: 0000 [#1] SMP +Modules linked in: +CPU: 3 PID: 2876 Comm: cp Not tainted 4.5.0-rc3.x86_64.1+ #14 +Hardware name: NETGEAR ReadyNAS 314 /ReadyNAS 314 , BIOS 4.6.5 10/11/2012 +task: ffff880073cdc080 ti: ffff88005b31c000 task.ti: ffff88005b31c000 +RIP: 0010:[] [] SMB2_open+0x804/0x960 +RSP: 0018:ffff88005b31fa08 EFLAGS: 00010282 +RAX: 0000000000000015 RBX: 0000000000000000 RCX: 0000000000000006 +RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff88007eb8c8b0 +RBP: ffff88005b31fad8 R08: 666666203d206363 R09: 6131613030383866 +R10: 3030383866666666 R11: 00000000000002b0 R12: ffff8800660fd800 +R13: ffff8800a1a77cc2 R14: 00000000424d53fe R15: ffff88005f5a28c0 +FS: 00007f7c8a2897c0(0000) GS:ffff88007eb80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +CR2: ffff8800a1a77cc6 CR3: 000000005b281000 CR4: 00000000000006e0 +Stack: + ffff88005b31fa70 ffffffff88278789 00000000000001d3 ffff88005f5a2a80 + ffffffff00000003 ffff88005d029d00 ffff88006fde05a0 0000000000000000 + ffff88005b31fc78 ffff88006fde0780 ffff88005b31fb2f 0000000100000fe0 +Call Trace: + [] ? cifsConvertToUTF16+0x159/0x2d0 + [] smb2_open_file+0x98/0x210 + [] ? __kmalloc+0x1c/0xe0 + [] cifs_open+0x2a4/0x720 + [] do_dentry_open+0x1ff/0x310 + [] ? cifsFileInfo_get+0x30/0x30 + [] vfs_open+0x52/0x60 + [] path_openat+0x170/0xf70 + [] ? remove_wait_queue+0x48/0x50 + [] do_filp_open+0x79/0xd0 + [] ? __alloc_fd+0x3a/0x170 + [] do_sys_open+0x114/0x1e0 + [] SyS_open+0x19/0x20 + [] entry_SYSCALL_64_fastpath+0x12/0x6a +Code: 4d 8d 6c 07 04 31 c0 4c 89 ee e8 47 6f e5 ff 31 c9 41 89 ce 44 89 f1 48 c7 c7 28 b1 bd 88 31 c0 49 01 cd 4c 89 ee e8 2b 6f e5 ff <45> 0f b7 75 04 48 c7 c7 31 b1 bd 88 31 c0 4d 01 ee 4c 89 f6 e8 +RIP [] SMB2_open+0x804/0x960 + RSP +CR2: ffff8800a1a77cc6 +---[ end trace d9f69ba64feee469 ]--- + +Signed-off-by: Justin Maggard +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2pdu.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -1109,21 +1109,25 @@ parse_lease_state(struct TCP_Server_Info + { + char *data_offset; + struct create_context *cc; +- unsigned int next = 0; ++ unsigned int next; ++ unsigned int remaining; + char *name; + + data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset); ++ remaining = le32_to_cpu(rsp->CreateContextsLength); + cc = (struct create_context *)data_offset; +- do { +- cc = (struct create_context *)((char *)cc + next); ++ while (remaining >= sizeof(struct create_context)) { + name = le16_to_cpu(cc->NameOffset) + (char *)cc; +- if (le16_to_cpu(cc->NameLength) != 4 || +- strncmp(name, "RqLs", 4)) { +- next = le32_to_cpu(cc->Next); +- continue; +- } +- return server->ops->parse_lease_buf(cc, epoch); +- } while (next != 0); ++ if (le16_to_cpu(cc->NameLength) == 4 && ++ strncmp(name, "RqLs", 4) == 0) ++ return server->ops->parse_lease_buf(cc, epoch); ++ ++ next = le32_to_cpu(cc->Next); ++ if (!next) ++ break; ++ remaining -= next; ++ cc = (struct create_context *)((char *)cc + next); ++ } + + return 0; + } diff --git a/queue-4.4/cifs-fix-smb2-interim-response-processing-for-read-requests.patch b/queue-4.4/cifs-fix-smb2-interim-response-processing-for-read-requests.patch new file mode 100644 index 00000000000..49789516553 --- /dev/null +++ b/queue-4.4/cifs-fix-smb2-interim-response-processing-for-read-requests.patch @@ -0,0 +1,72 @@ +From 6cc3b24235929b54acd5ecc987ef11a425bd209e Mon Sep 17 00:00:00 2001 +From: Pavel Shilovsky +Date: Sat, 27 Feb 2016 11:58:18 +0300 +Subject: CIFS: Fix SMB2+ interim response processing for read requests + +From: Pavel Shilovsky + +commit 6cc3b24235929b54acd5ecc987ef11a425bd209e upstream. + +For interim responses we only need to parse a header and update +a number credits. Now it is done for all SMB2+ command except +SMB2_READ which is wrong. Fix this by adding such processing. + +Signed-off-by: Pavel Shilovsky +Tested-by: Shirish Pargaonkar +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifssmb.c | 21 ++++++++++++++++++--- + 1 file changed, 18 insertions(+), 3 deletions(-) + +--- a/fs/cifs/cifssmb.c ++++ b/fs/cifs/cifssmb.c +@@ -1396,11 +1396,10 @@ openRetry: + * current bigbuf. + */ + static int +-cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) ++discard_remaining_data(struct TCP_Server_Info *server) + { + unsigned int rfclen = get_rfc1002_length(server->smallbuf); + int remaining = rfclen + 4 - server->total_read; +- struct cifs_readdata *rdata = mid->callback_data; + + while (remaining > 0) { + int length; +@@ -1414,10 +1413,20 @@ cifs_readv_discard(struct TCP_Server_Inf + remaining -= length; + } + +- dequeue_mid(mid, rdata->result); + return 0; + } + ++static int ++cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid) ++{ ++ int length; ++ struct cifs_readdata *rdata = mid->callback_data; ++ ++ length = discard_remaining_data(server); ++ dequeue_mid(mid, rdata->result); ++ return length; ++} ++ + int + cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) + { +@@ -1446,6 +1455,12 @@ cifs_readv_receive(struct TCP_Server_Inf + return length; + server->total_read += length; + ++ if (server->ops->is_status_pending && ++ server->ops->is_status_pending(buf, server, 0)) { ++ discard_remaining_data(server); ++ return -1; ++ } ++ + /* Was the SMB read successful? */ + rdata->result = server->ops->map_error(buf, false); + if (rdata->result != 0) { diff --git a/queue-4.4/drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch b/queue-4.4/drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch new file mode 100644 index 00000000000..e0f47f2dee8 --- /dev/null +++ b/queue-4.4/drivers-sh-restore-legacy-clock-domain-on-superh-platforms.patch @@ -0,0 +1,39 @@ +From 0378ba4899d5fbd8494ed6580cbc81d7b44dbac6 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Wed, 24 Feb 2016 09:43:23 +0100 +Subject: drivers: sh: Restore legacy clock domain on SuperH platforms + +From: Geert Uytterhoeven + +commit 0378ba4899d5fbd8494ed6580cbc81d7b44dbac6 upstream. + +CONFIG_ARCH_SHMOBILE is not only enabled for Renesas ARM platforms +(which are DT based and multi-platform), but also on a select set of +Renesas SuperH platforms (SH7722/SH7723/SH7724/SH7343/SH7366). Hence +since commit 0ba58de231066e47 ("drivers: sh: Get rid of +CONFIG_ARCH_SHMOBILE_MULTI"), the legacy clock domain is no longer +installed on these SuperH platforms, and module clocks may not be +enabled when needed, leading to driver failures. + +To fix this, add an additional check for CONFIG_OF. + +Fixes: 0ba58de231066e47 ("drivers: sh: Get rid of CONFIG_ARCH_SHMOBILE_MULTI"). +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Simon Horman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/sh/pm_runtime.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/sh/pm_runtime.c ++++ b/drivers/sh/pm_runtime.c +@@ -34,7 +34,7 @@ static struct pm_clk_notifier_block plat + + static int __init sh_pm_runtime_init(void) + { +- if (IS_ENABLED(CONFIG_ARCH_SHMOBILE)) { ++ if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_ARCH_SHMOBILE)) { + if (!of_find_compatible_node(NULL, NULL, + "renesas,cpg-mstp-clocks")) + return 0; diff --git a/queue-4.4/drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch b/queue-4.4/drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch new file mode 100644 index 00000000000..fedcd4e3af4 --- /dev/null +++ b/queue-4.4/drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch @@ -0,0 +1,46 @@ +From a187f17f0e15a046aa5d7263b35df55230d92779 Mon Sep 17 00:00:00 2001 +From: Oded Gabbay +Date: Sat, 30 Jan 2016 07:59:34 +0200 +Subject: drm/amdgpu: mask out WC from BO on unsupported arches +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Oded Gabbay + +commit a187f17f0e15a046aa5d7263b35df55230d92779 upstream. + +Reviewed-by: Christian König +Reviewed-by: Michel Dänzer +Signed-off-by: Oded Gabbay +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +@@ -33,6 +33,7 @@ + #include + #include + #include ++#include + #include "amdgpu.h" + #include "amdgpu_trace.h" + +@@ -261,6 +262,13 @@ int amdgpu_bo_create_restricted(struct a + AMDGPU_GEM_DOMAIN_OA); + + bo->flags = flags; ++ ++ /* For architectures that don't support WC memory, ++ * mask out the WC flag from the BO ++ */ ++ if (!drm_arch_can_wc_memory()) ++ bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC; ++ + amdgpu_fill_placement_to_bo(bo, placement); + /* Kernel allocation are uninterruptible */ + r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type, diff --git a/queue-4.4/fbcon-set-a-default-value-to-blink-interval.patch b/queue-4.4/fbcon-set-a-default-value-to-blink-interval.patch new file mode 100644 index 00000000000..4f0067072b4 --- /dev/null +++ b/queue-4.4/fbcon-set-a-default-value-to-blink-interval.patch @@ -0,0 +1,66 @@ +From a1e533ec07d583d01349ef13c0c965b8633e1b91 Mon Sep 17 00:00:00 2001 +From: Jean-Philippe Brucker +Date: Mon, 15 Feb 2016 18:41:33 +0000 +Subject: fbcon: set a default value to blink interval + +From: Jean-Philippe Brucker + +commit a1e533ec07d583d01349ef13c0c965b8633e1b91 upstream. + +Since commit 27a4c827c34ac4256a190cc9d24607f953c1c459 + fbcon: use the cursor blink interval provided by vt + +two attempts have been made at fixing a possible hang caused by +cursor_timer_handler. That function registers a timer to be triggered at +"jiffies + fbcon_ops.cur_blink_jiffies". + +A new case had been encountered during initialisation of clcd-pl11x: + + fbcon_fb_registered + do_fbcon_takeover + + -> do_register_con_driver + fbcon_startup + (A) add_cursor_timer (with cur_blink_jiffies = 0) + + -> do_bind_con_driver + visual_init + fbcon_init + (B) cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms); + +If we take an softirq anywhere between A and B (and we do), +cursor_timer_handler executes indefinitely. + +Instead of patching all possible paths that lead to this case one at a +time, fix the issue at the source and initialise cur_blink_jiffies to +200ms when allocating fbcon_ops. This was its default value before +aforesaid commit. fbcon_cursor or fbcon_init will refine this value +downstream. + +Signed-off-by: Jean-Philippe Brucker +Tested-by: Scot Doyle +Signed-off-by: Tomi Valkeinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/video/console/fbcon.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/video/console/fbcon.c ++++ b/drivers/video/console/fbcon.c +@@ -709,6 +709,7 @@ static int con2fb_acquire_newinfo(struct + } + + if (!err) { ++ ops->cur_blink_jiffies = HZ / 5; + info->fbcon_par = ops; + + if (vc) +@@ -956,6 +957,7 @@ static const char *fbcon_startup(void) + ops->currcon = -1; + ops->graphics = 1; + ops->cur_rotate = -1; ++ ops->cur_blink_jiffies = HZ / 5; + info->fbcon_par = ops; + p->con_rotate = initial_rotation; + set_blitting_type(vc, info); diff --git a/queue-4.4/fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch b/queue-4.4/fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch new file mode 100644 index 00000000000..966e1f1fd63 --- /dev/null +++ b/queue-4.4/fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch @@ -0,0 +1,63 @@ +From 1ee9f4bd1a97026a7b2d7ae9f1f74b45680d0003 Mon Sep 17 00:00:00 2001 +From: Yadan Fan +Date: Mon, 29 Feb 2016 14:44:57 +0800 +Subject: Fix cifs_uniqueid_to_ino_t() function for s390x + +From: Yadan Fan + +commit 1ee9f4bd1a97026a7b2d7ae9f1f74b45680d0003 upstream. + +This issue is caused by commit 02323db17e3a7 ("cifs: fix +cifs_uniqueid_to_ino_t not to ever return 0"), when BITS_PER_LONG +is 64 on s390x, the corresponding cifs_uniqueid_to_ino_t() +function will cast 64-bit fileid to 32-bit by using (ino_t)fileid, +because ino_t (typdefed __kernel_ino_t) is int type. + +It's defined in arch/s390/include/uapi/asm/posix_types.h + + #ifndef __s390x__ + + typedef unsigned long __kernel_ino_t; + ... + #else /* __s390x__ */ + + typedef unsigned int __kernel_ino_t; + +So the #ifdef condition is wrong for s390x, we can just still use +one cifs_uniqueid_to_ino_t() function with comparing sizeof(ino_t) +and sizeof(u64) to choose the correct execution accordingly. + +Signed-off-by: Yadan Fan +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifsfs.h | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +--- a/fs/cifs/cifsfs.h ++++ b/fs/cifs/cifsfs.h +@@ -31,19 +31,15 @@ + * so that it will fit. We use hash_64 to convert the value to 31 bits, and + * then add 1, to ensure that we don't end up with a 0 as the value. + */ +-#if BITS_PER_LONG == 64 + static inline ino_t + cifs_uniqueid_to_ino_t(u64 fileid) + { ++ if ((sizeof(ino_t)) < (sizeof(u64))) ++ return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1; ++ + return (ino_t)fileid; ++ + } +-#else +-static inline ino_t +-cifs_uniqueid_to_ino_t(u64 fileid) +-{ +- return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1; +-} +-#endif + + extern struct file_system_type cifs_fs_type; + extern const struct address_space_operations cifs_addr_ops; diff --git a/queue-4.4/iommu-amd-apply-workaround-for-ats-write-permission-check.patch b/queue-4.4/iommu-amd-apply-workaround-for-ats-write-permission-check.patch new file mode 100644 index 00000000000..2b6ca2147c0 --- /dev/null +++ b/queue-4.4/iommu-amd-apply-workaround-for-ats-write-permission-check.patch @@ -0,0 +1,78 @@ +From 358875fd52ab8f00f66328cbf1a1d2486f265829 Mon Sep 17 00:00:00 2001 +From: Jay Cornwall +Date: Wed, 10 Feb 2016 15:48:01 -0600 +Subject: iommu/amd: Apply workaround for ATS write permission check + +From: Jay Cornwall + +commit 358875fd52ab8f00f66328cbf1a1d2486f265829 upstream. + +The AMD Family 15h Models 30h-3Fh (Kaveri) BIOS and Kernel Developer's +Guide omitted part of the BIOS IOMMU L2 register setup specification. +Without this setup the IOMMU L2 does not fully respect write permissions +when handling an ATS translation request. + +The IOMMU L2 will set PTE dirty bit when handling an ATS translation with +write permission request, even when PTE RW bit is clear. This may occur by +direct translation (which would cause a PPR) or by prefetch request from +the ATC. + +This is observed in practice when the IOMMU L2 modifies a PTE which maps a +pagecache page. The ext4 filesystem driver BUGs when asked to writeback +these (non-modified) pages. + +Enable ATS write permission check in the Kaveri IOMMU L2 if BIOS has not. + +Signed-off-by: Jay Cornwall +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu_init.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -1016,6 +1016,34 @@ static void amd_iommu_erratum_746_workar + } + + /* ++ * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission) ++ * Workaround: ++ * BIOS should enable ATS write permission check by setting ++ * L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b ++ */ ++static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu) ++{ ++ u32 value; ++ ++ if ((boot_cpu_data.x86 != 0x15) || ++ (boot_cpu_data.x86_model < 0x30) || ++ (boot_cpu_data.x86_model > 0x3f)) ++ return; ++ ++ /* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */ ++ value = iommu_read_l2(iommu, 0x47); ++ ++ if (value & BIT(0)) ++ return; ++ ++ /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */ ++ iommu_write_l2(iommu, 0x47, value | BIT(0)); ++ ++ pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n", ++ dev_name(&iommu->dev->dev)); ++} ++ ++/* + * This function clues the initialization function for one IOMMU + * together and also allocates the command buffer and programs the + * hardware. It does NOT enable the IOMMU. This is done afterwards. +@@ -1284,6 +1312,7 @@ static int iommu_init_pci(struct amd_iom + } + + amd_iommu_erratum_746_workaround(iommu); ++ amd_iommu_ats_write_check_workaround(iommu); + + iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu, + amd_iommu_groups, "ivhd%d", diff --git a/queue-4.4/iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch b/queue-4.4/iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch new file mode 100644 index 00000000000..3d0cee238c9 --- /dev/null +++ b/queue-4.4/iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch @@ -0,0 +1,92 @@ +From 38e45d02ea9f194b89d6bf41e52ccafc8e2c2b47 Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit +Date: Tue, 23 Feb 2016 13:03:30 +0100 +Subject: iommu/amd: Fix boot warning when device 00:00.0 is not iommu covered + +From: Suravee Suthikulpanit + +commit 38e45d02ea9f194b89d6bf41e52ccafc8e2c2b47 upstream. + +The setup code for the performance counters in the AMD IOMMU driver +tests whether the counters can be written. It tests to setup a counter +for device 00:00.0, which fails on systems where this particular device +is not covered by the IOMMU. + +Fix this by not relying on device 00:00.0 but only on the IOMMU being +present. + +Signed-off-by: Suravee Suthikulpanit +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu_init.c | 34 ++++++++++++++++++++++------------ + 1 file changed, 22 insertions(+), 12 deletions(-) + +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -228,6 +228,10 @@ static int amd_iommu_enable_interrupts(v + static int __init iommu_go_to_state(enum iommu_init_state state); + static void init_device_table_dma(void); + ++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, ++ u8 bank, u8 cntr, u8 fxn, ++ u64 *value, bool is_write); ++ + static inline void update_last_devid(u16 devid) + { + if (devid > amd_iommu_last_bdf) +@@ -1170,8 +1174,8 @@ static void init_iommu_perf_ctr(struct a + amd_iommu_pc_present = true; + + /* Check if the performance counters can be written to */ +- if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) || +- (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) || ++ if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) || ++ (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) || + (val != val2)) { + pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n"); + amd_iommu_pc_present = false; +@@ -2312,22 +2316,15 @@ u8 amd_iommu_pc_get_max_counters(u16 dev + } + EXPORT_SYMBOL(amd_iommu_pc_get_max_counters); + +-int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, ++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, ++ u8 bank, u8 cntr, u8 fxn, + u64 *value, bool is_write) + { +- struct amd_iommu *iommu; + u32 offset; + u32 max_offset_lim; + +- /* Make sure the IOMMU PC resource is available */ +- if (!amd_iommu_pc_present) +- return -ENODEV; +- +- /* Locate the iommu associated with the device ID */ +- iommu = amd_iommu_rlookup_table[devid]; +- + /* Check for valid iommu and pc register indexing */ +- if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7))) ++ if (WARN_ON((fxn > 0x28) || (fxn & 7))) + return -ENODEV; + + offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn); +@@ -2351,3 +2348,16 @@ int amd_iommu_pc_get_set_reg_val(u16 dev + return 0; + } + EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val); ++ ++int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, ++ u64 *value, bool is_write) ++{ ++ struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; ++ ++ /* Make sure the IOMMU PC resource is available */ ++ if (!amd_iommu_pc_present || iommu == NULL) ++ return -ENODEV; ++ ++ return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn, ++ value, is_write); ++} diff --git a/queue-4.4/iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch b/queue-4.4/iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch new file mode 100644 index 00000000000..9250c977f32 --- /dev/null +++ b/queue-4.4/iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch @@ -0,0 +1,68 @@ +From e6a8c9b337eed56eb481e1b4dd2180c25a1e5310 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Mon, 29 Feb 2016 23:49:47 +0100 +Subject: iommu/vt-d: Use BUS_NOTIFY_REMOVED_DEVICE in hotplug path + +From: Joerg Roedel + +commit e6a8c9b337eed56eb481e1b4dd2180c25a1e5310 upstream. + +In the PCI hotplug path of the Intel IOMMU driver, replace +the usage of the BUS_NOTIFY_DEL_DEVICE notifier, which is +executed before the driver is unbound from the device, with +BUS_NOTIFY_REMOVED_DEVICE, which runs after that. + +This fixes a kernel BUG being triggered in the VT-d code +when the device driver tries to unmap DMA buffers and the +VT-d driver already destroyed all mappings. + +Reported-by: Stefani Seibold +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/dmar.c | 5 +++-- + drivers/iommu/intel-iommu.c | 4 ++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -329,7 +329,8 @@ static int dmar_pci_bus_notifier(struct + /* Only care about add/remove events for physical functions */ + if (pdev->is_virtfn) + return NOTIFY_DONE; +- if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE) ++ if (action != BUS_NOTIFY_ADD_DEVICE && ++ action != BUS_NOTIFY_REMOVED_DEVICE) + return NOTIFY_DONE; + + info = dmar_alloc_pci_notify_info(pdev, action); +@@ -339,7 +340,7 @@ static int dmar_pci_bus_notifier(struct + down_write(&dmar_global_lock); + if (action == BUS_NOTIFY_ADD_DEVICE) + dmar_pci_bus_add_dev(info); +- else if (action == BUS_NOTIFY_DEL_DEVICE) ++ else if (action == BUS_NOTIFY_REMOVED_DEVICE) + dmar_pci_bus_del_dev(info); + up_write(&dmar_global_lock); + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -4367,7 +4367,7 @@ int dmar_iommu_notify_scope_dev(struct d + rmrru->devices_cnt); + if(ret < 0) + return ret; +- } else if (info->event == BUS_NOTIFY_DEL_DEVICE) { ++ } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) { + dmar_remove_dev_scope(info, rmrr->segment, + rmrru->devices, rmrru->devices_cnt); + } +@@ -4387,7 +4387,7 @@ int dmar_iommu_notify_scope_dev(struct d + break; + else if(ret < 0) + return ret; +- } else if (info->event == BUS_NOTIFY_DEL_DEVICE) { ++ } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) { + if (dmar_remove_dev_scope(info, atsr->segment, + atsru->devices, atsru->devices_cnt)) + break; diff --git a/queue-4.4/kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch b/queue-4.4/kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch new file mode 100644 index 00000000000..19c331350a6 --- /dev/null +++ b/queue-4.4/kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch @@ -0,0 +1,56 @@ +From 70e4da7a8ff62f2775337b705f45c804bb450454 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 26 Feb 2016 12:28:40 +0100 +Subject: KVM: x86: fix root cause for missed hardware breakpoints + +From: Paolo Bonzini + +commit 70e4da7a8ff62f2775337b705f45c804bb450454 upstream. + +Commit 172b2386ed16 ("KVM: x86: fix missed hardware breakpoints", +2016-02-10) worked around a case where the debug registers are not loaded +correctly on preemption and on the first entry to KVM_RUN. + +However, Xiao Guangrong pointed out that the root cause must be that +KVM_DEBUGREG_BP_ENABLED is not being set correctly. This can indeed +happen due to the lazy debug exit mechanism, which does not call +kvm_update_dr7. Fix it by replacing the existing loop (more or less +equivalent to kvm_update_dr0123) with calls to all the kvm_update_dr* +functions. + +Fixes: 172b2386ed16a9143d9a456aae5ec87275c61489 +Reviewed-by: Xiao Guangrong +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/x86.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -2736,7 +2736,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu + } + + kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); +- vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD; + } + + void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) +@@ -6545,12 +6544,12 @@ static int vcpu_enter_guest(struct kvm_v + * KVM_DEBUGREG_WONT_EXIT again. + */ + if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) { +- int i; +- + WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP); + kvm_x86_ops->sync_dirty_debug_regs(vcpu); +- for (i = 0; i < KVM_NR_DB_REGS; i++) +- vcpu->arch.eff_db[i] = vcpu->arch.db[i]; ++ kvm_update_dr0123(vcpu); ++ kvm_update_dr6(vcpu); ++ kvm_update_dr7(vcpu); ++ vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD; + } + + /* diff --git a/queue-4.4/kvm-x86-update-tsc-multiplier-on-change.patch b/queue-4.4/kvm-x86-update-tsc-multiplier-on-change.patch new file mode 100644 index 00000000000..ea436218860 --- /dev/null +++ b/queue-4.4/kvm-x86-update-tsc-multiplier-on-change.patch @@ -0,0 +1,56 @@ +From 2680d6da455b636dd006636780c0f235c6561d70 Mon Sep 17 00:00:00 2001 +From: Owen Hofmann +Date: Tue, 1 Mar 2016 13:36:13 -0800 +Subject: kvm: x86: Update tsc multiplier on change. + +From: Owen Hofmann + +commit 2680d6da455b636dd006636780c0f235c6561d70 upstream. + +vmx.c writes the TSC_MULTIPLIER field in vmx_vcpu_load, but only when a +vcpu has migrated physical cpus. Record the last value written and +update in vmx_vcpu_load on any change, otherwise a cpu migration must +occur for TSC frequency scaling to take effect. + +Fixes: ff2c3a1803775cc72dc6f624b59554956396b0ee +Signed-off-by: Owen Hofmann +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -595,6 +595,8 @@ struct vcpu_vmx { + /* Support for PML */ + #define PML_ENTITY_NUM 512 + struct page *pml_pg; ++ ++ u64 current_tsc_ratio; + }; + + enum segment_cache_field { +@@ -2062,14 +2064,16 @@ static void vmx_vcpu_load(struct kvm_vcp + rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp); + vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */ + +- /* Setup TSC multiplier */ +- if (cpu_has_vmx_tsc_scaling()) +- vmcs_write64(TSC_MULTIPLIER, +- vcpu->arch.tsc_scaling_ratio); +- + vmx->loaded_vmcs->cpu = cpu; + } + ++ /* Setup TSC multiplier */ ++ if (kvm_has_tsc_control && ++ vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) { ++ vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio; ++ vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio); ++ } ++ + vmx_vcpu_pi_load(vcpu, cpu); + } + diff --git a/queue-4.4/mips-kvm-fix-ioctl-error-handling.patch b/queue-4.4/mips-kvm-fix-ioctl-error-handling.patch new file mode 100644 index 00000000000..aa79661b7a2 --- /dev/null +++ b/queue-4.4/mips-kvm-fix-ioctl-error-handling.patch @@ -0,0 +1,49 @@ +From 0178fd7dcc4451fcb90bec5e91226586962478d2 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 28 Feb 2016 17:35:59 +0200 +Subject: mips/kvm: fix ioctl error handling + +From: Michael S. Tsirkin + +commit 0178fd7dcc4451fcb90bec5e91226586962478d2 upstream. + +Returning directly whatever copy_to_user(...) or copy_from_user(...) +returns may not do the right thing if there's a pagefault: +copy_to_user/copy_from_user return the number of bytes not copied in +this case, but ioctls need to return -EFAULT instead. + +Fix up kvm on mips to do + return copy_to_user(...)) ? -EFAULT : 0; +and + return copy_from_user(...)) ? -EFAULT : 0; + +everywhere. + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/mips/kvm/mips.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/kvm/mips.c ++++ b/arch/mips/kvm/mips.c +@@ -702,7 +702,7 @@ static int kvm_mips_get_reg(struct kvm_v + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { + void __user *uaddr = (void __user *)(long)reg->addr; + +- return copy_to_user(uaddr, vs, 16); ++ return copy_to_user(uaddr, vs, 16) ? -EFAULT : 0; + } else { + return -EINVAL; + } +@@ -732,7 +732,7 @@ static int kvm_mips_set_reg(struct kvm_v + } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) { + void __user *uaddr = (void __user *)(long)reg->addr; + +- return copy_from_user(vs, uaddr, 16); ++ return copy_from_user(vs, uaddr, 16) ? -EFAULT : 0; + } else { + return -EINVAL; + } diff --git a/queue-4.4/parisc-fix-ptrace-syscall-number-and-return-value-modification.patch b/queue-4.4/parisc-fix-ptrace-syscall-number-and-return-value-modification.patch new file mode 100644 index 00000000000..ef7b3cca548 --- /dev/null +++ b/queue-4.4/parisc-fix-ptrace-syscall-number-and-return-value-modification.patch @@ -0,0 +1,94 @@ +From 98e8b6c9ac9d1b1e9d1122dfa6783d5d566bb8f7 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Tue, 19 Jan 2016 16:08:49 +0100 +Subject: parisc: Fix ptrace syscall number and return value modification + +From: Helge Deller + +commit 98e8b6c9ac9d1b1e9d1122dfa6783d5d566bb8f7 upstream. + +Mike Frysinger reported that his ptrace testcase showed strange +behaviour on parisc: It was not possible to avoid a syscall and the +return value of a syscall couldn't be changed. + +To modify a syscall number, we were missing to save the new syscall +number to gr20 which is then picked up later in assembly again. + +The effect that the return value couldn't be changed is a side-effect of +another bug in the assembly code. When a process is ptraced, userspace +expects each syscall to report entrance and exit of a syscall. If a +syscall number was given which doesn't exist, we jumped to the normal +syscall exit code instead of informing userspace that the (non-existant) +syscall exits. This unexpected behaviour confuses userspace and thus the +bug was misinterpreted as if we can't change the return value. + +This patch fixes both problems and was tested on 64bit kernel with +32bit userspace. + +Signed-off-by: Helge Deller +Cc: Mike Frysinger +Tested-by: Mike Frysinger +Signed-off-by: Greg Kroah-Hartman + +--- + arch/parisc/kernel/ptrace.c | 16 +++++++++++----- + arch/parisc/kernel/syscall.S | 5 ++++- + 2 files changed, 15 insertions(+), 6 deletions(-) + +--- a/arch/parisc/kernel/ptrace.c ++++ b/arch/parisc/kernel/ptrace.c +@@ -269,14 +269,19 @@ long compat_arch_ptrace(struct task_stru + + long do_syscall_trace_enter(struct pt_regs *regs) + { +- long ret = 0; +- + /* Do the secure computing check first. */ + secure_computing_strict(regs->gr[20]); + + if (test_thread_flag(TIF_SYSCALL_TRACE) && +- tracehook_report_syscall_entry(regs)) +- ret = -1L; ++ tracehook_report_syscall_entry(regs)) { ++ /* ++ * Tracing decided this syscall should not happen or the ++ * debugger stored an invalid system call number. Skip ++ * the system call and the system call restart handling. ++ */ ++ regs->gr[20] = -1UL; ++ goto out; ++ } + + #ifdef CONFIG_64BIT + if (!is_compat_task()) +@@ -290,7 +295,8 @@ long do_syscall_trace_enter(struct pt_re + regs->gr[24] & 0xffffffff, + regs->gr[23] & 0xffffffff); + +- return ret ? : regs->gr[20]; ++out: ++ return regs->gr[20]; + } + + void do_syscall_trace_exit(struct pt_regs *regs) +--- a/arch/parisc/kernel/syscall.S ++++ b/arch/parisc/kernel/syscall.S +@@ -343,7 +343,7 @@ tracesys_next: + #endif + + comiclr,>>= __NR_Linux_syscalls, %r20, %r0 +- b,n .Lsyscall_nosys ++ b,n .Ltracesys_nosys + + LDREGX %r20(%r19), %r19 + +@@ -359,6 +359,9 @@ tracesys_next: + be 0(%sr7,%r19) + ldo R%tracesys_exit(%r2),%r2 + ++.Ltracesys_nosys: ++ ldo -ENOSYS(%r0),%r28 /* set errno */ ++ + /* Do *not* call this function on the gateway page, because it + makes a direct call to syscall_trace. */ + diff --git a/queue-4.4/pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch b/queue-4.4/pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch new file mode 100644 index 00000000000..e598869fc04 --- /dev/null +++ b/queue-4.4/pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch @@ -0,0 +1,78 @@ +From 79e3f4a853ed161cd4c06d84b50beebf961a47c6 Mon Sep 17 00:00:00 2001 +From: Murali Karicheri +Date: Mon, 29 Feb 2016 17:18:22 -0600 +Subject: PCI: keystone: Fix MSI code that retrieves struct pcie_port pointer + +From: Murali Karicheri + +commit 79e3f4a853ed161cd4c06d84b50beebf961a47c6 upstream. + +Commit cbce7900598c ("PCI: designware: Make driver arch-agnostic") changed +the host bridge sysdata pointer from the ARM pci_sys_data to the DesignWare +pcie_port structure, and changed pcie-designware.c to reflect that. But it +did not change the corresponding code in pci-keystone-dw.c, so it caused +crashes on Keystone: + + Unable to handle kernel NULL pointer dereference at virtual address 00000030 + pgd = c0003000 + [00000030] *pgd=80000800004003, *pmd=00000000 + Internal error: Oops: 206 [#1] PREEMPT SMP ARM + CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.4.2-00139-gb74f926 #2 + Hardware name: Keystone + PC is at ks_dw_pcie_msi_irq_unmask+0x24/0x58 + +Change pci-keystone-dw.c to expect sysdata to be the struct pcie_port +pointer. + +[bhelgaas: changelog] +Fixes: cbce7900598c ("PCI: designware: Make driver arch-agnostic") +Signed-off-by: Murali Karicheri +Signed-off-by: Bjorn Helgaas +CC: Zhou Wang +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/host/pci-keystone-dw.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- a/drivers/pci/host/pci-keystone-dw.c ++++ b/drivers/pci/host/pci-keystone-dw.c +@@ -58,11 +58,6 @@ + + #define to_keystone_pcie(x) container_of(x, struct keystone_pcie, pp) + +-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) +-{ +- return sys->private_data; +-} +- + static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset, + u32 *bit_pos) + { +@@ -108,7 +103,7 @@ static void ks_dw_pcie_msi_irq_ack(struc + struct pcie_port *pp; + + msi = irq_data_get_msi_desc(d); +- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ++ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); + ks_pcie = to_keystone_pcie(pp); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); + update_reg_offset_bit_pos(offset, ®_offset, &bit_pos); +@@ -146,7 +141,7 @@ static void ks_dw_pcie_msi_irq_mask(stru + u32 offset; + + msi = irq_data_get_msi_desc(d); +- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ++ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); + ks_pcie = to_keystone_pcie(pp); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); + +@@ -167,7 +162,7 @@ static void ks_dw_pcie_msi_irq_unmask(st + u32 offset; + + msi = irq_data_get_msi_desc(d); +- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi)); ++ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi); + ks_pcie = to_keystone_pcie(pp); + offset = d->irq - irq_linear_revmap(pp->irq_domain, 0); + diff --git a/queue-4.4/series b/queue-4.4/series index aa442a6486b..2407707a8a5 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -5,3 +5,17 @@ btrfs-fix-no_space-in-write-and-rm-loop.patch btrfs-async-thread-fix-a-use-after-free-error-for-trace.patch drm-amdgpu-mask-out-wc-from-bo-on-unsupported-arches.patch block-initialize-max_dev_sectors-to-0.patch +pci-keystone-fix-msi-code-that-retrieves-struct-pcie_port-pointer.patch +parisc-fix-ptrace-syscall-number-and-return-value-modification.patch +mips-kvm-fix-ioctl-error-handling.patch +kvm-x86-update-tsc-multiplier-on-change.patch +fbcon-set-a-default-value-to-blink-interval.patch +cifs-fix-out-of-bounds-access-in-lease-parsing.patch +cifs-fix-smb2-interim-response-processing-for-read-requests.patch +fix-cifs_uniqueid_to_ino_t-function-for-s390x.patch +vfio-fix-ioctl-error-handling.patch +kvm-x86-fix-root-cause-for-missed-hardware-breakpoints.patch +arm-arm64-kvm-fix-ioctl-error-handling.patch +iommu-amd-apply-workaround-for-ats-write-permission-check.patch +iommu-amd-fix-boot-warning-when-device-00-00.0-is-not-iommu-covered.patch +iommu-vt-d-use-bus_notify_removed_device-in-hotplug-path.patch diff --git a/queue-4.4/use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch b/queue-4.4/use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch new file mode 100644 index 00000000000..b68d85b97a6 --- /dev/null +++ b/queue-4.4/use-d_seq-to-get-coherency-between-d_inode-and-d_flags.patch @@ -0,0 +1,100 @@ +From a528aca7f359f4b0b1d72ae406097e491a5ba9ea Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 29 Feb 2016 12:12:46 -0500 +Subject: use ->d_seq to get coherency between ->d_inode and ->d_flags + +From: Al Viro + +commit a528aca7f359f4b0b1d72ae406097e491a5ba9ea upstream. + +Games with ordering and barriers are way too brittle. Just +bump ->d_seq before and after updating ->d_inode and ->d_flags +type bits, so that verifying ->d_seq would guarantee they are +coherent. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/dcache.c | 20 +++++--------------- + include/linux/dcache.h | 4 +--- + 2 files changed, 6 insertions(+), 18 deletions(-) + +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -269,9 +269,6 @@ static inline int dname_external(const s + return dentry->d_name.name != dentry->d_iname; + } + +-/* +- * Make sure other CPUs see the inode attached before the type is set. +- */ + static inline void __d_set_inode_and_type(struct dentry *dentry, + struct inode *inode, + unsigned type_flags) +@@ -279,28 +276,18 @@ static inline void __d_set_inode_and_typ + unsigned flags; + + dentry->d_inode = inode; +- smp_wmb(); + flags = READ_ONCE(dentry->d_flags); + flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU); + flags |= type_flags; + WRITE_ONCE(dentry->d_flags, flags); + } + +-/* +- * Ideally, we want to make sure that other CPUs see the flags cleared before +- * the inode is detached, but this is really a violation of RCU principles +- * since the ordering suggests we should always set inode before flags. +- * +- * We should instead replace or discard the entire dentry - but that sucks +- * performancewise on mass deletion/rename. +- */ + static inline void __d_clear_type_and_inode(struct dentry *dentry) + { + unsigned flags = READ_ONCE(dentry->d_flags); + + flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU); + WRITE_ONCE(dentry->d_flags, flags); +- smp_wmb(); + dentry->d_inode = NULL; + } + +@@ -370,9 +357,11 @@ static void dentry_unlink_inode(struct d + __releases(dentry->d_inode->i_lock) + { + struct inode *inode = dentry->d_inode; ++ ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_clear_type_and_inode(dentry); + hlist_del_init(&dentry->d_u.d_alias); +- dentry_rcuwalk_invalidate(dentry); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + spin_unlock(&inode->i_lock); + if (!inode->i_nlink) +@@ -1757,8 +1746,9 @@ static void __d_instantiate(struct dentr + spin_lock(&dentry->d_lock); + if (inode) + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); ++ raw_write_seqcount_begin(&dentry->d_seq); + __d_set_inode_and_type(dentry, inode, add_flags); +- dentry_rcuwalk_invalidate(dentry); ++ raw_write_seqcount_end(&dentry->d_seq); + spin_unlock(&dentry->d_lock); + fsnotify_d_instantiate(dentry, inode); + } +--- a/include/linux/dcache.h ++++ b/include/linux/dcache.h +@@ -409,9 +409,7 @@ static inline bool d_mountpoint(const st + */ + static inline unsigned __d_entry_type(const struct dentry *dentry) + { +- unsigned type = READ_ONCE(dentry->d_flags); +- smp_rmb(); +- return type & DCACHE_ENTRY_TYPE; ++ return dentry->d_flags & DCACHE_ENTRY_TYPE; + } + + static inline bool d_is_miss(const struct dentry *dentry) diff --git a/queue-4.4/vfio-fix-ioctl-error-handling.patch b/queue-4.4/vfio-fix-ioctl-error-handling.patch new file mode 100644 index 00000000000..9b803d1ee38 --- /dev/null +++ b/queue-4.4/vfio-fix-ioctl-error-handling.patch @@ -0,0 +1,116 @@ +From 8160c4e455820d5008a1116d2dca35f0363bb062 Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Sun, 28 Feb 2016 16:31:39 +0200 +Subject: vfio: fix ioctl error handling + +From: Michael S. Tsirkin + +commit 8160c4e455820d5008a1116d2dca35f0363bb062 upstream. + +Calling return copy_to_user(...) in an ioctl will not +do the right thing if there's a pagefault: +copy_to_user returns the number of bytes not copied +in this case. + +Fix up vfio to do + return copy_to_user(...)) ? + -EFAULT : 0; + +everywhere. + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Alex Williamson +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/vfio/pci/vfio_pci.c | 9 ++++++--- + drivers/vfio/platform/vfio_platform_common.c | 9 ++++++--- + drivers/vfio/vfio_iommu_type1.c | 6 ++++-- + 3 files changed, 16 insertions(+), 8 deletions(-) + +--- a/drivers/vfio/pci/vfio_pci.c ++++ b/drivers/vfio/pci/vfio_pci.c +@@ -446,7 +446,8 @@ static long vfio_pci_ioctl(void *device_ + info.num_regions = VFIO_PCI_NUM_REGIONS; + info.num_irqs = VFIO_PCI_NUM_IRQS; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) { + struct pci_dev *pdev = vdev->pdev; +@@ -520,7 +521,8 @@ static long vfio_pci_ioctl(void *device_ + return -EINVAL; + } + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { + struct vfio_irq_info info; +@@ -555,7 +557,8 @@ static long vfio_pci_ioctl(void *device_ + else + info.flags |= VFIO_IRQ_INFO_NORESIZE; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_SET_IRQS) { + struct vfio_irq_set hdr; +--- a/drivers/vfio/platform/vfio_platform_common.c ++++ b/drivers/vfio/platform/vfio_platform_common.c +@@ -219,7 +219,8 @@ static long vfio_platform_ioctl(void *de + info.num_regions = vdev->num_regions; + info.num_irqs = vdev->num_irqs; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) { + struct vfio_region_info info; +@@ -240,7 +241,8 @@ static long vfio_platform_ioctl(void *de + info.size = vdev->regions[info.index].size; + info.flags = vdev->regions[info.index].flags; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) { + struct vfio_irq_info info; +@@ -259,7 +261,8 @@ static long vfio_platform_ioctl(void *de + info.flags = vdev->irqs[info.index].flags; + info.count = vdev->irqs[info.index].count; + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_DEVICE_SET_IRQS) { + struct vfio_irq_set hdr; +--- a/drivers/vfio/vfio_iommu_type1.c ++++ b/drivers/vfio/vfio_iommu_type1.c +@@ -999,7 +999,8 @@ static long vfio_iommu_type1_ioctl(void + + info.iova_pgsizes = vfio_pgsize_bitmap(iommu); + +- return copy_to_user((void __user *)arg, &info, minsz); ++ return copy_to_user((void __user *)arg, &info, minsz) ? ++ -EFAULT : 0; + + } else if (cmd == VFIO_IOMMU_MAP_DMA) { + struct vfio_iommu_type1_dma_map map; +@@ -1032,7 +1033,8 @@ static long vfio_iommu_type1_ioctl(void + if (ret) + return ret; + +- return copy_to_user((void __user *)arg, &unmap, minsz); ++ return copy_to_user((void __user *)arg, &unmap, minsz) ? ++ -EFAULT : 0; + } + + return -ENOTTY;