From: Greg Kroah-Hartman Date: Thu, 27 Feb 2020 09:01:13 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.215~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=945073841afa200c89222aaf32ac741be892a1d0;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: ext4-add-cond_resched-to-__ext4_find_entry.patch ext4-fix-a-data-race-in-ext4_i-inode-i_disksize.patch ext4-fix-mount-failure-with-quota-configured-as-module.patch ext4-fix-race-between-writepages-and-enabling-ext4_extents_fl.patch ext4-rename-s_journal_flag_rwsem-to-s_writepages_rwsem.patch kvm-nvmx-check-io-instruction-vm-exit-conditions.patch kvm-nvmx-refactor-io-bitmap-checks-into-helper-function.patch kvm-x86-emulate-rdpid.patch --- diff --git a/queue-4.14/ext4-add-cond_resched-to-__ext4_find_entry.patch b/queue-4.14/ext4-add-cond_resched-to-__ext4_find_entry.patch new file mode 100644 index 00000000000..1480ffaf187 --- /dev/null +++ b/queue-4.14/ext4-add-cond_resched-to-__ext4_find_entry.patch @@ -0,0 +1,71 @@ +From 9424ef56e13a1f14c57ea161eed3ecfdc7b2770e Mon Sep 17 00:00:00 2001 +From: Shijie Luo +Date: Sat, 15 Feb 2020 03:02:06 -0500 +Subject: ext4: add cond_resched() to __ext4_find_entry() + +From: Shijie Luo + +commit 9424ef56e13a1f14c57ea161eed3ecfdc7b2770e upstream. + +We tested a soft lockup problem in linux 4.19 which could also +be found in linux 5.x. + +When dir inode takes up a large number of blocks, and if the +directory is growing when we are searching, it's possible the +restart branch could be called many times, and the do while loop +could hold cpu a long time. + +Here is the call trace in linux 4.19. + +[ 473.756186] Call trace: +[ 473.756196] dump_backtrace+0x0/0x198 +[ 473.756199] show_stack+0x24/0x30 +[ 473.756205] dump_stack+0xa4/0xcc +[ 473.756210] watchdog_timer_fn+0x300/0x3e8 +[ 473.756215] __hrtimer_run_queues+0x114/0x358 +[ 473.756217] hrtimer_interrupt+0x104/0x2d8 +[ 473.756222] arch_timer_handler_virt+0x38/0x58 +[ 473.756226] handle_percpu_devid_irq+0x90/0x248 +[ 473.756231] generic_handle_irq+0x34/0x50 +[ 473.756234] __handle_domain_irq+0x68/0xc0 +[ 473.756236] gic_handle_irq+0x6c/0x150 +[ 473.756238] el1_irq+0xb8/0x140 +[ 473.756286] ext4_es_lookup_extent+0xdc/0x258 [ext4] +[ 473.756310] ext4_map_blocks+0x64/0x5c0 [ext4] +[ 473.756333] ext4_getblk+0x6c/0x1d0 [ext4] +[ 473.756356] ext4_bread_batch+0x7c/0x1f8 [ext4] +[ 473.756379] ext4_find_entry+0x124/0x3f8 [ext4] +[ 473.756402] ext4_lookup+0x8c/0x258 [ext4] +[ 473.756407] __lookup_hash+0x8c/0xe8 +[ 473.756411] filename_create+0xa0/0x170 +[ 473.756413] do_mkdirat+0x6c/0x140 +[ 473.756415] __arm64_sys_mkdirat+0x28/0x38 +[ 473.756419] el0_svc_common+0x78/0x130 +[ 473.756421] el0_svc_handler+0x38/0x78 +[ 473.756423] el0_svc+0x8/0xc +[ 485.755156] watchdog: BUG: soft lockup - CPU#2 stuck for 22s! [tmp:5149] + +Add cond_resched() to avoid soft lockup and to provide a better +system responding. + +Link: https://lore.kernel.org/r/20200215080206.13293-1-luoshijie1@huawei.com +Signed-off-by: Shijie Luo +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/namei.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -1430,6 +1430,7 @@ restart: + /* + * We deal with the read-ahead logic here. + */ ++ cond_resched(); + if (ra_ptr >= ra_max) { + /* Refill the readahead buffer */ + ra_ptr = 0; diff --git a/queue-4.14/ext4-fix-a-data-race-in-ext4_i-inode-i_disksize.patch b/queue-4.14/ext4-fix-a-data-race-in-ext4_i-inode-i_disksize.patch new file mode 100644 index 00000000000..8d367812dc5 --- /dev/null +++ b/queue-4.14/ext4-fix-a-data-race-in-ext4_i-inode-i_disksize.patch @@ -0,0 +1,87 @@ +From 35df4299a6487f323b0aca120ea3f485dfee2ae3 Mon Sep 17 00:00:00 2001 +From: Qian Cai +Date: Fri, 7 Feb 2020 09:29:11 -0500 +Subject: ext4: fix a data race in EXT4_I(inode)->i_disksize + +From: Qian Cai + +commit 35df4299a6487f323b0aca120ea3f485dfee2ae3 upstream. + +EXT4_I(inode)->i_disksize could be accessed concurrently as noticed by +KCSAN, + + BUG: KCSAN: data-race in ext4_write_end [ext4] / ext4_writepages [ext4] + + write to 0xffff91c6713b00f8 of 8 bytes by task 49268 on cpu 127: + ext4_write_end+0x4e3/0x750 [ext4] + ext4_update_i_disksize at fs/ext4/ext4.h:3032 + (inlined by) ext4_update_inode_size at fs/ext4/ext4.h:3046 + (inlined by) ext4_write_end at fs/ext4/inode.c:1287 + generic_perform_write+0x208/0x2a0 + ext4_buffered_write_iter+0x11f/0x210 [ext4] + ext4_file_write_iter+0xce/0x9e0 [ext4] + new_sync_write+0x29c/0x3b0 + __vfs_write+0x92/0xa0 + vfs_write+0x103/0x260 + ksys_write+0x9d/0x130 + __x64_sys_write+0x4c/0x60 + do_syscall_64+0x91/0xb47 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + + read to 0xffff91c6713b00f8 of 8 bytes by task 24872 on cpu 37: + ext4_writepages+0x10ac/0x1d00 [ext4] + mpage_map_and_submit_extent at fs/ext4/inode.c:2468 + (inlined by) ext4_writepages at fs/ext4/inode.c:2772 + do_writepages+0x5e/0x130 + __writeback_single_inode+0xeb/0xb20 + writeback_sb_inodes+0x429/0x900 + __writeback_inodes_wb+0xc4/0x150 + wb_writeback+0x4bd/0x870 + wb_workfn+0x6b4/0x960 + process_one_work+0x54c/0xbe0 + worker_thread+0x80/0x650 + kthread+0x1e0/0x200 + ret_from_fork+0x27/0x50 + + Reported by Kernel Concurrency Sanitizer on: + CPU: 37 PID: 24872 Comm: kworker/u261:2 Tainted: G W O L 5.5.0-next-20200204+ #5 + Hardware name: HPE ProLiant DL385 Gen10/ProLiant DL385 Gen10, BIOS A40 07/10/2019 + Workqueue: writeback wb_workfn (flush-7:0) + +Since only the read is operating as lockless (outside of the +"i_data_sem"), load tearing could introduce a logic bug. Fix it by +adding READ_ONCE() for the read and WRITE_ONCE() for the write. + +Signed-off-by: Qian Cai +Link: https://lore.kernel.org/r/1581085751-31793-1-git-send-email-cai@lca.pw +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 2 +- + fs/ext4/inode.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2867,7 +2867,7 @@ static inline void ext4_update_i_disksiz + !inode_is_locked(inode)); + down_write(&EXT4_I(inode)->i_data_sem); + if (newsize > EXT4_I(inode)->i_disksize) +- EXT4_I(inode)->i_disksize = newsize; ++ WRITE_ONCE(EXT4_I(inode)->i_disksize, newsize); + up_write(&EXT4_I(inode)->i_data_sem); + } + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -2564,7 +2564,7 @@ update_disksize: + * truncate are avoided by checking i_size under i_data_sem. + */ + disksize = ((loff_t)mpd->first_page) << PAGE_SHIFT; +- if (disksize > EXT4_I(inode)->i_disksize) { ++ if (disksize > READ_ONCE(EXT4_I(inode)->i_disksize)) { + int err2; + loff_t i_size; + diff --git a/queue-4.14/ext4-fix-mount-failure-with-quota-configured-as-module.patch b/queue-4.14/ext4-fix-mount-failure-with-quota-configured-as-module.patch new file mode 100644 index 00000000000..2d448b814b8 --- /dev/null +++ b/queue-4.14/ext4-fix-mount-failure-with-quota-configured-as-module.patch @@ -0,0 +1,36 @@ +From 9db176bceb5c5df4990486709da386edadc6bd1d Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 21 Feb 2020 11:08:35 +0100 +Subject: ext4: fix mount failure with quota configured as module + +From: Jan Kara + +commit 9db176bceb5c5df4990486709da386edadc6bd1d upstream. + +When CONFIG_QFMT_V2 is configured as a module, the test in +ext4_feature_set_ok() fails and so mount of filesystems with quota or +project features fails. Fix the test to use IS_ENABLED macro which +works properly even for modules. + +Link: https://lore.kernel.org/r/20200221100835.9332-1-jack@suse.cz +Fixes: d65d87a07476 ("ext4: improve explanation of a mount failure caused by a misconfigured kernel") +Signed-off-by: Jan Kara +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/super.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2863,7 +2863,7 @@ static int ext4_feature_set_ok(struct su + return 0; + } + +-#if !defined(CONFIG_QUOTA) || !defined(CONFIG_QFMT_V2) ++#if !IS_ENABLED(CONFIG_QUOTA) || !IS_ENABLED(CONFIG_QFMT_V2) + if (!readonly && (ext4_has_feature_quota(sb) || + ext4_has_feature_project(sb))) { + ext4_msg(sb, KERN_ERR, diff --git a/queue-4.14/ext4-fix-race-between-writepages-and-enabling-ext4_extents_fl.patch b/queue-4.14/ext4-fix-race-between-writepages-and-enabling-ext4_extents_fl.patch new file mode 100644 index 00000000000..3e35d929a43 --- /dev/null +++ b/queue-4.14/ext4-fix-race-between-writepages-and-enabling-ext4_extents_fl.patch @@ -0,0 +1,167 @@ +From cb85f4d23f794e24127f3e562cb3b54b0803f456 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 19 Feb 2020 10:30:47 -0800 +Subject: ext4: fix race between writepages and enabling EXT4_EXTENTS_FL + +From: Eric Biggers + +commit cb85f4d23f794e24127f3e562cb3b54b0803f456 upstream. + +If EXT4_EXTENTS_FL is set on an inode while ext4_writepages() is running +on it, the following warning in ext4_add_complete_io() can be hit: + +WARNING: CPU: 1 PID: 0 at fs/ext4/page-io.c:234 ext4_put_io_end_defer+0xf0/0x120 + +Here's a minimal reproducer (not 100% reliable) (root isn't required): + + while true; do + sync + done & + while true; do + rm -f file + touch file + chattr -e file + echo X >> file + chattr +e file + done + +The problem is that in ext4_writepages(), ext4_should_dioread_nolock() +(which only returns true on extent-based files) is checked once to set +the number of reserved journal credits, and also again later to select +the flags for ext4_map_blocks() and copy the reserved journal handle to +ext4_io_end::handle. But if EXT4_EXTENTS_FL is being concurrently set, +the first check can see dioread_nolock disabled while the later one can +see it enabled, causing the reserved handle to unexpectedly be NULL. + +Since changing EXT4_EXTENTS_FL is uncommon, and there may be other races +related to doing so as well, fix this by synchronizing changing +EXT4_EXTENTS_FL with ext4_writepages() via the existing +s_writepages_rwsem (previously called s_journal_flag_rwsem). + +This was originally reported by syzbot without a reproducer at +https://syzkaller.appspot.com/bug?extid=2202a584a00fffd19fbf, +but now that dioread_nolock is the default I also started seeing this +when running syzkaller locally. + +Link: https://lore.kernel.org/r/20200219183047.47417-3-ebiggers@kernel.org +Reported-by: syzbot+2202a584a00fffd19fbf@syzkaller.appspotmail.com +Fixes: 6b523df4fb5a ("ext4: use transaction reservation for extent conversion in ext4_end_io") +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 5 ++++- + fs/ext4/migrate.c | 27 +++++++++++++++++++-------- + 2 files changed, 23 insertions(+), 9 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1532,7 +1532,10 @@ struct ext4_sb_info { + struct ratelimit_state s_warning_ratelimit_state; + struct ratelimit_state s_msg_ratelimit_state; + +- /* Barrier between changing inodes' journal flags and writepages ops. */ ++ /* ++ * Barrier between writepages ops and changing any inode's JOURNAL_DATA ++ * or EXTENTS flag. ++ */ + struct percpu_rw_semaphore s_writepages_rwsem; + struct dax_device *s_daxdev; + }; +--- a/fs/ext4/migrate.c ++++ b/fs/ext4/migrate.c +@@ -434,6 +434,7 @@ static int free_ext_block(handle_t *hand + + int ext4_ext_migrate(struct inode *inode) + { ++ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); + handle_t *handle; + int retval = 0, i; + __le32 *i_data; +@@ -458,6 +459,8 @@ int ext4_ext_migrate(struct inode *inode + */ + return retval; + ++ percpu_down_write(&sbi->s_writepages_rwsem); ++ + /* + * Worst case we can touch the allocation bitmaps, a bgd + * block, and a block to link in the orphan list. We do need +@@ -468,7 +471,7 @@ int ext4_ext_migrate(struct inode *inode + + if (IS_ERR(handle)) { + retval = PTR_ERR(handle); +- return retval; ++ goto out_unlock; + } + goal = (((inode->i_ino - 1) / EXT4_INODES_PER_GROUP(inode->i_sb)) * + EXT4_INODES_PER_GROUP(inode->i_sb)) + 1; +@@ -479,7 +482,7 @@ int ext4_ext_migrate(struct inode *inode + if (IS_ERR(tmp_inode)) { + retval = PTR_ERR(tmp_inode); + ext4_journal_stop(handle); +- return retval; ++ goto out_unlock; + } + i_size_write(tmp_inode, i_size_read(inode)); + /* +@@ -521,7 +524,7 @@ int ext4_ext_migrate(struct inode *inode + */ + ext4_orphan_del(NULL, tmp_inode); + retval = PTR_ERR(handle); +- goto out; ++ goto out_tmp_inode; + } + + ei = EXT4_I(inode); +@@ -602,10 +605,11 @@ err_out: + /* Reset the extent details */ + ext4_ext_tree_init(handle, tmp_inode); + ext4_journal_stop(handle); +-out: ++out_tmp_inode: + unlock_new_inode(tmp_inode); + iput(tmp_inode); +- ++out_unlock: ++ percpu_up_write(&sbi->s_writepages_rwsem); + return retval; + } + +@@ -615,7 +619,8 @@ out: + int ext4_ind_migrate(struct inode *inode) + { + struct ext4_extent_header *eh; +- struct ext4_super_block *es = EXT4_SB(inode->i_sb)->s_es; ++ struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); ++ struct ext4_super_block *es = sbi->s_es; + struct ext4_inode_info *ei = EXT4_I(inode); + struct ext4_extent *ex; + unsigned int i, len; +@@ -639,9 +644,13 @@ int ext4_ind_migrate(struct inode *inode + if (test_opt(inode->i_sb, DELALLOC)) + ext4_alloc_da_blocks(inode); + ++ percpu_down_write(&sbi->s_writepages_rwsem); ++ + handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); +- if (IS_ERR(handle)) +- return PTR_ERR(handle); ++ if (IS_ERR(handle)) { ++ ret = PTR_ERR(handle); ++ goto out_unlock; ++ } + + down_write(&EXT4_I(inode)->i_data_sem); + ret = ext4_ext_check_inode(inode); +@@ -676,5 +685,7 @@ int ext4_ind_migrate(struct inode *inode + errout: + ext4_journal_stop(handle); + up_write(&EXT4_I(inode)->i_data_sem); ++out_unlock: ++ percpu_up_write(&sbi->s_writepages_rwsem); + return ret; + } diff --git a/queue-4.14/ext4-rename-s_journal_flag_rwsem-to-s_writepages_rwsem.patch b/queue-4.14/ext4-rename-s_journal_flag_rwsem-to-s_writepages_rwsem.patch new file mode 100644 index 00000000000..ff9f42102f4 --- /dev/null +++ b/queue-4.14/ext4-rename-s_journal_flag_rwsem-to-s_writepages_rwsem.patch @@ -0,0 +1,114 @@ +From bbd55937de8f2754adc5792b0f8e5ff7d9c0420e Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 19 Feb 2020 10:30:46 -0800 +Subject: ext4: rename s_journal_flag_rwsem to s_writepages_rwsem + +From: Eric Biggers + +commit bbd55937de8f2754adc5792b0f8e5ff7d9c0420e upstream. + +In preparation for making s_journal_flag_rwsem synchronize +ext4_writepages() with changes to both the EXTENTS and JOURNAL_DATA +flags (rather than just JOURNAL_DATA as it does currently), rename it to +s_writepages_rwsem. + +Link: https://lore.kernel.org/r/20200219183047.47417-2-ebiggers@kernel.org +Signed-off-by: Eric Biggers +Signed-off-by: Theodore Ts'o +Reviewed-by: Jan Kara +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4.h | 2 +- + fs/ext4/inode.c | 10 +++++----- + fs/ext4/super.c | 6 +++--- + 3 files changed, 9 insertions(+), 9 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -1533,7 +1533,7 @@ struct ext4_sb_info { + struct ratelimit_state s_msg_ratelimit_state; + + /* Barrier between changing inodes' journal flags and writepages ops. */ +- struct percpu_rw_semaphore s_journal_flag_rwsem; ++ struct percpu_rw_semaphore s_writepages_rwsem; + struct dax_device *s_daxdev; + }; + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -2744,7 +2744,7 @@ static int ext4_writepages(struct addres + if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) + return -EIO; + +- percpu_down_read(&sbi->s_journal_flag_rwsem); ++ percpu_down_read(&sbi->s_writepages_rwsem); + trace_ext4_writepages(inode, wbc); + + if (dax_mapping(mapping)) { +@@ -2974,7 +2974,7 @@ unplug: + out_writepages: + trace_ext4_writepages_result(inode, wbc, ret, + nr_to_write - wbc->nr_to_write); +- percpu_up_read(&sbi->s_journal_flag_rwsem); ++ percpu_up_read(&sbi->s_writepages_rwsem); + return ret; + } + +@@ -6050,7 +6050,7 @@ int ext4_change_inode_journal_flag(struc + } + } + +- percpu_down_write(&sbi->s_journal_flag_rwsem); ++ percpu_down_write(&sbi->s_writepages_rwsem); + jbd2_journal_lock_updates(journal); + + /* +@@ -6067,7 +6067,7 @@ int ext4_change_inode_journal_flag(struc + err = jbd2_journal_flush(journal); + if (err < 0) { + jbd2_journal_unlock_updates(journal); +- percpu_up_write(&sbi->s_journal_flag_rwsem); ++ percpu_up_write(&sbi->s_writepages_rwsem); + ext4_inode_resume_unlocked_dio(inode); + return err; + } +@@ -6076,7 +6076,7 @@ int ext4_change_inode_journal_flag(struc + ext4_set_aops(inode); + + jbd2_journal_unlock_updates(journal); +- percpu_up_write(&sbi->s_journal_flag_rwsem); ++ percpu_up_write(&sbi->s_writepages_rwsem); + + if (val) + up_write(&EXT4_I(inode)->i_mmap_sem); +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -939,7 +939,7 @@ static void ext4_put_super(struct super_ + percpu_counter_destroy(&sbi->s_freeinodes_counter); + percpu_counter_destroy(&sbi->s_dirs_counter); + percpu_counter_destroy(&sbi->s_dirtyclusters_counter); +- percpu_free_rwsem(&sbi->s_journal_flag_rwsem); ++ percpu_free_rwsem(&sbi->s_writepages_rwsem); + #ifdef CONFIG_QUOTA + for (i = 0; i < EXT4_MAXQUOTAS; i++) + kfree(get_qf_name(sb, sbi, i)); +@@ -4396,7 +4396,7 @@ no_journal: + err = percpu_counter_init(&sbi->s_dirtyclusters_counter, 0, + GFP_KERNEL); + if (!err) +- err = percpu_init_rwsem(&sbi->s_journal_flag_rwsem); ++ err = percpu_init_rwsem(&sbi->s_writepages_rwsem); + + if (err) { + ext4_msg(sb, KERN_ERR, "insufficient memory"); +@@ -4490,7 +4490,7 @@ failed_mount6: + percpu_counter_destroy(&sbi->s_freeinodes_counter); + percpu_counter_destroy(&sbi->s_dirs_counter); + percpu_counter_destroy(&sbi->s_dirtyclusters_counter); +- percpu_free_rwsem(&sbi->s_journal_flag_rwsem); ++ percpu_free_rwsem(&sbi->s_writepages_rwsem); + failed_mount5: + ext4_ext_release(sb); + ext4_release_system_zone(sb); diff --git a/queue-4.14/kvm-nvmx-check-io-instruction-vm-exit-conditions.patch b/queue-4.14/kvm-nvmx-check-io-instruction-vm-exit-conditions.patch new file mode 100644 index 00000000000..0baba9f545b --- /dev/null +++ b/queue-4.14/kvm-nvmx-check-io-instruction-vm-exit-conditions.patch @@ -0,0 +1,110 @@ +From 35a571346a94fb93b5b3b6a599675ef3384bc75c Mon Sep 17 00:00:00 2001 +From: Oliver Upton +Date: Tue, 4 Feb 2020 15:26:31 -0800 +Subject: KVM: nVMX: Check IO instruction VM-exit conditions + +From: Oliver Upton + +commit 35a571346a94fb93b5b3b6a599675ef3384bc75c upstream. + +Consult the 'unconditional IO exiting' and 'use IO bitmaps' VM-execution +controls when checking instruction interception. If the 'use IO bitmaps' +VM-execution control is 1, check the instruction access against the IO +bitmaps to determine if the instruction causes a VM-exit. + +Signed-off-by: Oliver Upton +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 52 insertions(+), 7 deletions(-) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -4997,7 +4997,7 @@ static bool nested_vmx_exit_handled_io(s + struct vmcs12 *vmcs12) + { + unsigned long exit_qualification; +- unsigned int port; ++ unsigned short port; + int size; + + if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) +@@ -12335,6 +12335,39 @@ static void nested_vmx_entry_failure(str + to_vmx(vcpu)->nested.sync_shadow_vmcs = true; + } + ++static int vmx_check_intercept_io(struct kvm_vcpu *vcpu, ++ struct x86_instruction_info *info) ++{ ++ struct vmcs12 *vmcs12 = get_vmcs12(vcpu); ++ unsigned short port; ++ bool intercept; ++ int size; ++ ++ if (info->intercept == x86_intercept_in || ++ info->intercept == x86_intercept_ins) { ++ port = info->src_val; ++ size = info->dst_bytes; ++ } else { ++ port = info->dst_val; ++ size = info->src_bytes; ++ } ++ ++ /* ++ * If the 'use IO bitmaps' VM-execution control is 0, IO instruction ++ * VM-exits depend on the 'unconditional IO exiting' VM-execution ++ * control. ++ * ++ * Otherwise, IO instruction VM-exits are controlled by the IO bitmaps. ++ */ ++ if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) ++ intercept = nested_cpu_has(vmcs12, ++ CPU_BASED_UNCOND_IO_EXITING); ++ else ++ intercept = nested_vmx_check_io_bitmaps(vcpu, port, size); ++ ++ return intercept ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; ++} ++ + static int vmx_check_intercept(struct kvm_vcpu *vcpu, + struct x86_instruction_info *info, + enum x86_intercept_stage stage) +@@ -12342,18 +12375,30 @@ static int vmx_check_intercept(struct kv + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; + ++ switch (info->intercept) { + /* + * RDPID causes #UD if disabled through secondary execution controls. + * Because it is marked as EmulateOnUD, we need to intercept it here. + */ +- if (info->intercept == x86_intercept_rdtscp && +- !nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { +- ctxt->exception.vector = UD_VECTOR; +- ctxt->exception.error_code_valid = false; +- return X86EMUL_PROPAGATE_FAULT; +- } ++ case x86_intercept_rdtscp: ++ if (!nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { ++ ctxt->exception.vector = UD_VECTOR; ++ ctxt->exception.error_code_valid = false; ++ return X86EMUL_PROPAGATE_FAULT; ++ } ++ break; ++ ++ case x86_intercept_in: ++ case x86_intercept_ins: ++ case x86_intercept_out: ++ case x86_intercept_outs: ++ return vmx_check_intercept_io(vcpu, info); + + /* TODO: check more intercepts... */ ++ default: ++ break; ++ } ++ + return X86EMUL_UNHANDLEABLE; + } + diff --git a/queue-4.14/kvm-nvmx-don-t-emulate-instructions-in-guest-mode.patch b/queue-4.14/kvm-nvmx-don-t-emulate-instructions-in-guest-mode.patch index 1bc7b7f0b41..2dbd14cf5f6 100644 --- a/queue-4.14/kvm-nvmx-don-t-emulate-instructions-in-guest-mode.patch +++ b/queue-4.14/kvm-nvmx-don-t-emulate-instructions-in-guest-mode.patch @@ -17,22 +17,17 @@ Signed-off-by: Oliver Upton Signed-off-by: Paolo Bonzini Signed-off-by: Sasha Levin --- - arch/x86/kvm/vmx.c | 2 +- + arch/x86/kvm/vmx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c -index a116548a4ade1..fc00fbffcd7fc 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c -@@ -12325,7 +12325,7 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, - struct x86_instruction_info *info, - enum x86_intercept_stage stage) - { +@@ -12340,7 +12340,7 @@ static int vmx_check_intercept(struct kv + } + + /* TODO: check more intercepts... */ - return X86EMUL_CONTINUE; + return X86EMUL_UNHANDLEABLE; } #ifdef CONFIG_X86_64 --- -2.20.1 - diff --git a/queue-4.14/kvm-nvmx-refactor-io-bitmap-checks-into-helper-function.patch b/queue-4.14/kvm-nvmx-refactor-io-bitmap-checks-into-helper-function.patch new file mode 100644 index 00000000000..68a57a66c38 --- /dev/null +++ b/queue-4.14/kvm-nvmx-refactor-io-bitmap-checks-into-helper-function.patch @@ -0,0 +1,82 @@ +From e71237d3ff1abf9f3388337cfebf53b96df2020d Mon Sep 17 00:00:00 2001 +From: Oliver Upton +Date: Tue, 4 Feb 2020 15:26:30 -0800 +Subject: KVM: nVMX: Refactor IO bitmap checks into helper function + +From: Oliver Upton + +commit e71237d3ff1abf9f3388337cfebf53b96df2020d upstream. + +Checks against the IO bitmap are useful for both instruction emulation +and VM-exit reflection. Refactor the IO bitmap checks into a helper +function. + +Signed-off-by: Oliver Upton +Reviewed-by: Vitaly Kuznetsov +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 40 +++++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 13 deletions(-) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -4991,6 +4991,26 @@ static bool cs_ss_rpl_check(struct kvm_v + (ss.selector & SEGMENT_RPL_MASK)); + } + ++static bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, ++ unsigned int port, int size); ++static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, ++ struct vmcs12 *vmcs12) ++{ ++ unsigned long exit_qualification; ++ unsigned int port; ++ int size; ++ ++ if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) ++ return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING); ++ ++ exit_qualification = vmcs_readl(EXIT_QUALIFICATION); ++ ++ port = exit_qualification >> 16; ++ size = (exit_qualification & 7) + 1; ++ ++ return nested_vmx_check_io_bitmaps(vcpu, port, size); ++} ++ + /* + * Check if guest state is valid. Returns true if valid, false if + * not. +@@ -8521,23 +8541,17 @@ static int (*const kvm_vmx_exit_handlers + static const int kvm_vmx_max_exit_handlers = + ARRAY_SIZE(kvm_vmx_exit_handlers); + +-static bool nested_vmx_exit_handled_io(struct kvm_vcpu *vcpu, +- struct vmcs12 *vmcs12) ++/* ++ * Return true if an IO instruction with the specified port and size should cause ++ * a VM-exit into L1. ++ */ ++bool nested_vmx_check_io_bitmaps(struct kvm_vcpu *vcpu, unsigned int port, ++ int size) + { +- unsigned long exit_qualification; ++ struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + gpa_t bitmap, last_bitmap; +- unsigned int port; +- int size; + u8 b; + +- if (!nested_cpu_has(vmcs12, CPU_BASED_USE_IO_BITMAPS)) +- return nested_cpu_has(vmcs12, CPU_BASED_UNCOND_IO_EXITING); +- +- exit_qualification = vmcs_readl(EXIT_QUALIFICATION); +- +- port = exit_qualification >> 16; +- size = (exit_qualification & 7) + 1; +- + last_bitmap = (gpa_t)-1; + b = -1; + diff --git a/queue-4.14/kvm-x86-emulate-rdpid.patch b/queue-4.14/kvm-x86-emulate-rdpid.patch new file mode 100644 index 00000000000..2b33b6f7a7b --- /dev/null +++ b/queue-4.14/kvm-x86-emulate-rdpid.patch @@ -0,0 +1,110 @@ +From fb6d4d340e0532032c808a9933eaaa7b8de435ab Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 12 Jul 2016 11:04:26 +0200 +Subject: KVM: x86: emulate RDPID + +From: Paolo Bonzini + +commit fb6d4d340e0532032c808a9933eaaa7b8de435ab upstream. + +This is encoded as F3 0F C7 /7 with a register argument. The register +argument is the second array in the group9 GroupDual, while F3 is the +fourth element of a Prefix. + +Reviewed-by: Wanpeng Li +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/cpuid.c | 7 ++++++- + arch/x86/kvm/emulate.c | 22 +++++++++++++++++++++- + arch/x86/kvm/vmx.c | 15 +++++++++++++++ + 3 files changed, 42 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -291,13 +291,18 @@ static int __do_cpuid_ent_emulated(struc + { + switch (func) { + case 0: +- entry->eax = 1; /* only one leaf currently */ ++ entry->eax = 7; + ++*nent; + break; + case 1: + entry->ecx = F(MOVBE); + ++*nent; + break; ++ case 7: ++ entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; ++ if (index == 0) ++ entry->ecx = F(RDPID); ++ ++*nent; + default: + break; + } +--- a/arch/x86/kvm/emulate.c ++++ b/arch/x86/kvm/emulate.c +@@ -3539,6 +3539,16 @@ static int em_cwd(struct x86_emulate_ctx + return X86EMUL_CONTINUE; + } + ++static int em_rdpid(struct x86_emulate_ctxt *ctxt) ++{ ++ u64 tsc_aux = 0; ++ ++ if (ctxt->ops->get_msr(ctxt, MSR_TSC_AUX, &tsc_aux)) ++ return emulate_gp(ctxt, 0); ++ ctxt->dst.val = tsc_aux; ++ return X86EMUL_CONTINUE; ++} ++ + static int em_rdtsc(struct x86_emulate_ctxt *ctxt) + { + u64 tsc = 0; +@@ -4431,10 +4441,20 @@ static const struct opcode group8[] = { + F(DstMem | SrcImmByte | Lock | PageTable, em_btc), + }; + ++/* ++ * The "memory" destination is actually always a register, since we come ++ * from the register case of group9. ++ */ ++static const struct gprefix pfx_0f_c7_7 = { ++ N, N, N, II(DstMem | ModRM | Op3264 | EmulateOnUD, em_rdpid, rdtscp), ++}; ++ ++ + static const struct group_dual group9 = { { + N, I(DstMem64 | Lock | PageTable, em_cmpxchg8b), N, N, N, N, N, N, + }, { +- N, N, N, N, N, N, N, N, ++ N, N, N, N, N, N, N, ++ GP(0, &pfx_0f_c7_7), + } }; + + static const struct opcode group11[] = { +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -12322,6 +12322,21 @@ static int vmx_check_intercept(struct kv + struct x86_instruction_info *info, + enum x86_intercept_stage stage) + { ++ struct vmcs12 *vmcs12 = get_vmcs12(vcpu); ++ struct x86_emulate_ctxt *ctxt = &vcpu->arch.emulate_ctxt; ++ ++ /* ++ * RDPID causes #UD if disabled through secondary execution controls. ++ * Because it is marked as EmulateOnUD, we need to intercept it here. ++ */ ++ if (info->intercept == x86_intercept_rdtscp && ++ !nested_cpu_has2(vmcs12, SECONDARY_EXEC_RDTSCP)) { ++ ctxt->exception.vector = UD_VECTOR; ++ ctxt->exception.error_code_valid = false; ++ return X86EMUL_PROPAGATE_FAULT; ++ } ++ ++ /* TODO: check more intercepts... */ + return X86EMUL_CONTINUE; + } + diff --git a/queue-4.14/series b/queue-4.14/series index 7a78cf7226d..da8f164f82f 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -1,3 +1,4 @@ +kvm-x86-emulate-rdpid.patch iommu-qcom-fix-bogus-detach-logic.patch alsa-hda-use-scnprintf-for-printing-texts-for-sysfs-procfs.patch asoc-sun8i-codec-fix-setting-dai-data-format.patch @@ -207,3 +208,10 @@ serial-8250-check-upf_irq_shared-in-advance.patch lib-stackdepot-fix-outdated-comments.patch lib-stackdepot.c-fix-global-out-of-bounds-in-stack_s.patch kvm-nvmx-don-t-emulate-instructions-in-guest-mode.patch +ext4-fix-a-data-race-in-ext4_i-inode-i_disksize.patch +ext4-add-cond_resched-to-__ext4_find_entry.patch +ext4-fix-mount-failure-with-quota-configured-as-module.patch +ext4-rename-s_journal_flag_rwsem-to-s_writepages_rwsem.patch +ext4-fix-race-between-writepages-and-enabling-ext4_extents_fl.patch +kvm-nvmx-refactor-io-bitmap-checks-into-helper-function.patch +kvm-nvmx-check-io-instruction-vm-exit-conditions.patch