From: Sasha Levin Date: Sun, 9 Feb 2020 22:18:06 +0000 (-0500) Subject: fixes for 5.5 X-Git-Tag: v4.19.103~22^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ba738259841b4a20969aab4d2e454d1c0ca2d506;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.5 Signed-off-by: Sasha Levin --- diff --git a/queue-5.5/drm-dp_mst-remove-vcpi-while-disabling-topology-mgr.patch b/queue-5.5/drm-dp_mst-remove-vcpi-while-disabling-topology-mgr.patch new file mode 100644 index 00000000000..49984fe771a --- /dev/null +++ b/queue-5.5/drm-dp_mst-remove-vcpi-while-disabling-topology-mgr.patch @@ -0,0 +1,92 @@ +From c4178d0812bd5f527887399068bd140088e524fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Dec 2019 17:00:43 +0800 +Subject: drm/dp_mst: Remove VCPI while disabling topology mgr + +From: Wayne Lin + +[ Upstream commit 64e62bdf04ab8529f45ed0a85122c703035dec3a ] + +[Why] + +This patch is trying to address the issue observed when hotplug DP +daisy chain monitors. + +e.g. +src-mstb-mstb-sst -> src (unplug) mstb-mstb-sst -> src-mstb-mstb-sst +(plug in again) + +Once unplug a DP MST capable device, driver will call +drm_dp_mst_topology_mgr_set_mst() to disable MST. In this function, +it cleans data of topology manager while disabling mst_state. However, +it doesn't clean up the proposed_vcpis of topology manager. +If proposed_vcpi is not reset, once plug in MST daisy chain monitors +later, code will fail at checking port validation while trying to +allocate payloads. + +When MST capable device is plugged in again and try to allocate +payloads by calling drm_dp_update_payload_part1(), this +function will iterate over all proposed virtual channels to see if +any proposed VCPI's num_slots is greater than 0. If any proposed +VCPI's num_slots is greater than 0 and the port which the +specific virtual channel directed to is not in the topology, code then +fails at the port validation. Since there are stale VCPI allocations +from the previous topology enablement in proposed_vcpi[], code will fail +at port validation and reurn EINVAL. + +[How] + +Clean up the data of stale proposed_vcpi[] and reset mgr->proposed_vcpis +to NULL while disabling mst in drm_dp_mst_topology_mgr_set_mst(). + +Changes since v1: +*Add on more details in commit message to describe the issue which the +patch is trying to fix + +Signed-off-by: Wayne Lin +[added cc to stable] +Signed-off-by: Lyude Paul +Link: https://patchwork.freedesktop.org/patch/msgid/20191205090043.7580-1-Wayne.Lin@amd.com +Cc: # v3.17+ +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/drm_dp_mst_topology.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c +index e6afe4faeca6d..141ba31cf5486 100644 +--- a/drivers/gpu/drm/drm_dp_mst_topology.c ++++ b/drivers/gpu/drm/drm_dp_mst_topology.c +@@ -3435,6 +3435,7 @@ static int drm_dp_get_vc_payload_bw(u8 dp_link_bw, u8 dp_link_count) + int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool mst_state) + { + int ret = 0; ++ int i = 0; + struct drm_dp_mst_branch *mstb = NULL; + + mutex_lock(&mgr->lock); +@@ -3495,10 +3496,21 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms + /* this can fail if the device is gone */ + drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, 0); + ret = 0; ++ mutex_lock(&mgr->payload_lock); + memset(mgr->payloads, 0, mgr->max_payloads * sizeof(struct drm_dp_payload)); + mgr->payload_mask = 0; + set_bit(0, &mgr->payload_mask); ++ for (i = 0; i < mgr->max_payloads; i++) { ++ struct drm_dp_vcpi *vcpi = mgr->proposed_vcpis[i]; ++ ++ if (vcpi) { ++ vcpi->vcpi = 0; ++ vcpi->num_slots = 0; ++ } ++ mgr->proposed_vcpis[i] = NULL; ++ } + mgr->vcpi_mask = 0; ++ mutex_unlock(&mgr->payload_lock); + } + + out_unlock: +-- +2.20.1 + diff --git a/queue-5.5/io_uring-enable-option-to-only-trigger-eventfd-for-a.patch b/queue-5.5/io_uring-enable-option-to-only-trigger-eventfd-for-a.patch new file mode 100644 index 00000000000..12f930f2af7 --- /dev/null +++ b/queue-5.5/io_uring-enable-option-to-only-trigger-eventfd-for-a.patch @@ -0,0 +1,93 @@ +From c4c0dcdb50ad05f7000a01346f78a2c3c2d8e9b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Feb 2020 13:30:59 -0500 +Subject: io_uring: enable option to only trigger eventfd for async completions + +[ Upstream commit f2842ab5b72d7ee5f7f8385c2d4f32c133f5837b ] + +If an application is using eventfd notifications with poll to know when +new SQEs can be issued, it's expecting the following read/writes to +complete inline. And with that, it knows that there are events available, +and don't want spurious wakeups on the eventfd for those requests. + +This adds IORING_REGISTER_EVENTFD_ASYNC, which works just like +IORING_REGISTER_EVENTFD, except it only triggers notifications for events +that happen from async completions (IRQ, or io-wq worker completions). +Any completions inline from the submission itself will not trigger +notifications. + +Suggested-by: Mark Papadakis +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + fs/io_uring.c | 17 ++++++++++++++++- + include/uapi/linux/io_uring.h | 1 + + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 95fc5c5a85968..131087782bec9 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -188,6 +188,7 @@ struct io_ring_ctx { + bool account_mem; + bool cq_overflow_flushed; + bool drain_next; ++ bool eventfd_async; + + /* + * Ring buffer of indices into array of io_uring_sqe, which is +@@ -735,13 +736,20 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx) + return &rings->cqes[tail & ctx->cq_mask]; + } + ++static inline bool io_should_trigger_evfd(struct io_ring_ctx *ctx) ++{ ++ if (!ctx->eventfd_async) ++ return true; ++ return io_wq_current_is_worker() || in_interrupt(); ++} ++ + static void io_cqring_ev_posted(struct io_ring_ctx *ctx) + { + if (waitqueue_active(&ctx->wait)) + wake_up(&ctx->wait); + if (waitqueue_active(&ctx->sqo_wait)) + wake_up(&ctx->sqo_wait); +- if (ctx->cq_ev_fd) ++ if (ctx->cq_ev_fd && io_should_trigger_evfd(ctx)) + eventfd_signal(ctx->cq_ev_fd, 1); + } + +@@ -5486,10 +5494,17 @@ static int __io_uring_register(struct io_ring_ctx *ctx, unsigned opcode, + ret = io_sqe_files_update(ctx, arg, nr_args); + break; + case IORING_REGISTER_EVENTFD: ++ case IORING_REGISTER_EVENTFD_ASYNC: + ret = -EINVAL; + if (nr_args != 1) + break; + ret = io_eventfd_register(ctx, arg); ++ if (ret) ++ break; ++ if (opcode == IORING_REGISTER_EVENTFD_ASYNC) ++ ctx->eventfd_async = 1; ++ else ++ ctx->eventfd_async = 0; + break; + case IORING_UNREGISTER_EVENTFD: + ret = -EINVAL; +diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h +index 55cfcb71606db..88693fed2c4b4 100644 +--- a/include/uapi/linux/io_uring.h ++++ b/include/uapi/linux/io_uring.h +@@ -175,6 +175,7 @@ struct io_uring_params { + #define IORING_REGISTER_EVENTFD 4 + #define IORING_UNREGISTER_EVENTFD 5 + #define IORING_REGISTER_FILES_UPDATE 6 ++#define IORING_REGISTER_EVENTFD_ASYNC 7 + + struct io_uring_files_update { + __u32 offset; +-- +2.20.1 + diff --git a/queue-5.5/io_uring-prevent-potential-eventfd-recursion-on-poll.patch b/queue-5.5/io_uring-prevent-potential-eventfd-recursion-on-poll.patch new file mode 100644 index 00000000000..02a9fedb116 --- /dev/null +++ b/queue-5.5/io_uring-prevent-potential-eventfd-recursion-on-poll.patch @@ -0,0 +1,104 @@ +From 880668254d7a1af40a1d61935c320ef6aa09c19f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Feb 2020 21:30:11 -0700 +Subject: io_uring: prevent potential eventfd recursion on poll + +From: Jens Axboe + +[ Upstream commit f0b493e6b9a8959356983f57112229e69c2f7b8c ] + +If we have nested or circular eventfd wakeups, then we can deadlock if +we run them inline from our poll waitqueue wakeup handler. It's also +possible to have very long chains of notifications, to the extent where +we could risk blowing the stack. + +Check the eventfd recursion count before calling eventfd_signal(). If +it's non-zero, then punt the signaling to async context. This is always +safe, as it takes us out-of-line in terms of stack and locking context. + +Cc: stable@vger.kernel.org # 5.1+ +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + fs/io_uring.c | 35 +++++++++++++++++++++++++++++------ + 1 file changed, 29 insertions(+), 6 deletions(-) + +diff --git a/fs/io_uring.c b/fs/io_uring.c +index 131087782bec9..f470fb21467e4 100644 +--- a/fs/io_uring.c ++++ b/fs/io_uring.c +@@ -738,21 +738,28 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx) + + static inline bool io_should_trigger_evfd(struct io_ring_ctx *ctx) + { ++ if (!ctx->cq_ev_fd) ++ return false; + if (!ctx->eventfd_async) + return true; + return io_wq_current_is_worker() || in_interrupt(); + } + +-static void io_cqring_ev_posted(struct io_ring_ctx *ctx) ++static void __io_cqring_ev_posted(struct io_ring_ctx *ctx, bool trigger_ev) + { + if (waitqueue_active(&ctx->wait)) + wake_up(&ctx->wait); + if (waitqueue_active(&ctx->sqo_wait)) + wake_up(&ctx->sqo_wait); +- if (ctx->cq_ev_fd && io_should_trigger_evfd(ctx)) ++ if (trigger_ev) + eventfd_signal(ctx->cq_ev_fd, 1); + } + ++static void io_cqring_ev_posted(struct io_ring_ctx *ctx) ++{ ++ __io_cqring_ev_posted(ctx, io_should_trigger_evfd(ctx)); ++} ++ + /* Returns true if there are no backlogged entries after the flush */ + static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force) + { +@@ -2645,6 +2652,14 @@ static void io_poll_complete_work(struct io_wq_work **workptr) + io_wq_assign_next(workptr, nxt); + } + ++static void io_poll_trigger_evfd(struct io_wq_work **workptr) ++{ ++ struct io_kiocb *req = container_of(*workptr, struct io_kiocb, work); ++ ++ eventfd_signal(req->ctx->cq_ev_fd, 1); ++ io_put_req(req); ++} ++ + static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, + void *key) + { +@@ -2667,13 +2682,21 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, + * for finalizing the request, mark us as having grabbed that already. + */ + if (mask && spin_trylock_irqsave(&ctx->completion_lock, flags)) { ++ bool trigger_ev; ++ + hash_del(&req->hash_node); + io_poll_complete(req, mask, 0); +- req->flags |= REQ_F_COMP_LOCKED; +- io_put_req(req); ++ trigger_ev = io_should_trigger_evfd(ctx); ++ if (trigger_ev && eventfd_signal_count()) { ++ trigger_ev = false; ++ req->work.func = io_poll_trigger_evfd; ++ } else { ++ req->flags |= REQ_F_COMP_LOCKED; ++ io_put_req(req); ++ req = NULL; ++ } + spin_unlock_irqrestore(&ctx->completion_lock, flags); +- +- io_cqring_ev_posted(ctx); ++ __io_cqring_ev_posted(ctx, trigger_ev); + } else { + io_queue_async_work(req); + } +-- +2.20.1 + diff --git a/queue-5.5/kvm-nvmx-vmread-should-not-set-rflags-to-specify-suc.patch b/queue-5.5/kvm-nvmx-vmread-should-not-set-rflags-to-specify-suc.patch new file mode 100644 index 00000000000..08b42a7693b --- /dev/null +++ b/queue-5.5/kvm-nvmx-vmread-should-not-set-rflags-to-specify-suc.patch @@ -0,0 +1,43 @@ +From 09e3f0530749ac7f1af70eafb55a3406e7e4e118 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 28 Dec 2019 14:25:24 +0800 +Subject: KVM: nVMX: vmread should not set rflags to specify success in case of + #PF + +From: Miaohe Lin + +[ Upstream commit a4d956b9390418623ae5d07933e2679c68b6f83c ] + +In case writing to vmread destination operand result in a #PF, vmread +should not call nested_vmx_succeed() to set rflags to specify success. +Similar to as done in VMPTRST (See handle_vmptrst()). + +Reviewed-by: Liran Alon +Signed-off-by: Miaohe Lin +Cc: stable@vger.kernel.org +Reviewed-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/vmx/nested.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c +index 4aea7d304bebd..5bfa8228f0c74 100644 +--- a/arch/x86/kvm/vmx/nested.c ++++ b/arch/x86/kvm/vmx/nested.c +@@ -4807,8 +4807,10 @@ static int handle_vmread(struct kvm_vcpu *vcpu) + vmx_instruction_info, true, len, &gva)) + return 1; + /* _system ok, nested_vmx_check_permission has verified cpl=0 */ +- if (kvm_write_guest_virt_system(vcpu, gva, &field_value, len, &e)) ++ if (kvm_write_guest_virt_system(vcpu, gva, &field_value, len, &e)) { + kvm_inject_page_fault(vcpu, &e); ++ return 1; ++ } + } + + return nested_vmx_succeed(vcpu); +-- +2.20.1 + diff --git a/queue-5.5/kvm-play-nice-with-read-only-memslots-when-querying-.patch b/queue-5.5/kvm-play-nice-with-read-only-memslots-when-querying-.patch new file mode 100644 index 00000000000..14bdedc0989 --- /dev/null +++ b/queue-5.5/kvm-play-nice-with-read-only-memslots-when-querying-.patch @@ -0,0 +1,46 @@ +From 80004a1a11dca14573c250af4b42d2871a6b25c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2020 12:24:38 -0800 +Subject: KVM: Play nice with read-only memslots when querying host page size + +From: Sean Christopherson + +[ Upstream commit 42cde48b2d39772dba47e680781a32a6c4b7dc33 ] + +Avoid the "writable" check in __gfn_to_hva_many(), which will always fail +on read-only memslots due to gfn_to_hva() assuming writes. Functionally, +this allows x86 to create large mappings for read-only memslots that +are backed by HugeTLB mappings. + +Note, the changelog for commit 05da45583de9 ("KVM: MMU: large page +support") states "If the largepage contains write-protected pages, a +large pte is not used.", but "write-protected" refers to pages that are +temporarily read-only, e.g. read-only memslots didn't even exist at the +time. + +Fixes: 4d8b81abc47b ("KVM: introduce readonly memslot") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +[Redone using kvm_vcpu_gfn_to_memslot_prot. - Paolo] +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + virt/kvm/kvm_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index cb1a4bbe3b30f..2b3f36df3d855 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1413,7 +1413,7 @@ unsigned long kvm_host_page_size(struct kvm_vcpu *vcpu, gfn_t gfn) + + size = PAGE_SIZE; + +- addr = kvm_vcpu_gfn_to_hva(vcpu, gfn); ++ addr = kvm_vcpu_gfn_to_hva_prot(vcpu, gfn, NULL); + if (kvm_is_error_hva(addr)) + return PAGE_SIZE; + +-- +2.20.1 + diff --git a/queue-5.5/kvm-use-vcpu-specific-gva-hva-translation-when-query.patch b/queue-5.5/kvm-use-vcpu-specific-gva-hva-translation-when-query.patch new file mode 100644 index 00000000000..1e698f8c232 --- /dev/null +++ b/queue-5.5/kvm-use-vcpu-specific-gva-hva-translation-when-query.patch @@ -0,0 +1,103 @@ +From eed6e811c175b70e1c8bd362c90d2a20c54ad92a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2020 12:24:37 -0800 +Subject: KVM: Use vcpu-specific gva->hva translation when querying host page + size + +From: Sean Christopherson + +[ Upstream commit f9b84e19221efc5f493156ee0329df3142085f28 ] + +Use kvm_vcpu_gfn_to_hva() when retrieving the host page size so that the +correct set of memslots is used when handling x86 page faults in SMM. + +Fixes: 54bf36aac520 ("KVM: x86: use vcpu-specific functions to read/write/translate GFNs") +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/powerpc/kvm/book3s_xive_native.c | 2 +- + arch/x86/kvm/mmu/mmu.c | 6 +++--- + include/linux/kvm_host.h | 2 +- + virt/kvm/kvm_main.c | 4 ++-- + 4 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c +index d83adb1e14902..6ef0151ff70a9 100644 +--- a/arch/powerpc/kvm/book3s_xive_native.c ++++ b/arch/powerpc/kvm/book3s_xive_native.c +@@ -631,7 +631,7 @@ static int kvmppc_xive_native_set_queue_config(struct kvmppc_xive *xive, + srcu_idx = srcu_read_lock(&kvm->srcu); + gfn = gpa_to_gfn(kvm_eq.qaddr); + +- page_size = kvm_host_page_size(kvm, gfn); ++ page_size = kvm_host_page_size(vcpu, gfn); + if (1ull << kvm_eq.qshift > page_size) { + srcu_read_unlock(&kvm->srcu, srcu_idx); + pr_warn("Incompatible host page size %lx!\n", page_size); +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index 5eb14442929c8..d21b69bbd6f48 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -1286,12 +1286,12 @@ static bool mmu_gfn_lpage_is_disallowed(struct kvm_vcpu *vcpu, gfn_t gfn, + return __mmu_gfn_lpage_is_disallowed(gfn, level, slot); + } + +-static int host_mapping_level(struct kvm *kvm, gfn_t gfn) ++static int host_mapping_level(struct kvm_vcpu *vcpu, gfn_t gfn) + { + unsigned long page_size; + int i, ret = 0; + +- page_size = kvm_host_page_size(kvm, gfn); ++ page_size = kvm_host_page_size(vcpu, gfn); + + for (i = PT_PAGE_TABLE_LEVEL; i <= PT_MAX_HUGEPAGE_LEVEL; ++i) { + if (page_size >= KVM_HPAGE_SIZE(i)) +@@ -1341,7 +1341,7 @@ static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn, + if (unlikely(*force_pt_level)) + return PT_PAGE_TABLE_LEVEL; + +- host_level = host_mapping_level(vcpu->kvm, large_gfn); ++ host_level = host_mapping_level(vcpu, large_gfn); + + if (host_level == PT_PAGE_TABLE_LEVEL) + return host_level; +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 7a4e346b0cb38..eacb8c48e7689 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -768,7 +768,7 @@ int kvm_clear_guest_page(struct kvm *kvm, gfn_t gfn, int offset, int len); + int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); + struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); + bool kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn); +-unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn); ++unsigned long kvm_host_page_size(struct kvm_vcpu *vcpu, gfn_t gfn); + void mark_page_dirty(struct kvm *kvm, gfn_t gfn); + + struct kvm_memslots *kvm_vcpu_memslots(struct kvm_vcpu *vcpu); +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 68a3e0aa625f4..cb1a4bbe3b30f 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1406,14 +1406,14 @@ bool kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn) + } + EXPORT_SYMBOL_GPL(kvm_is_visible_gfn); + +-unsigned long kvm_host_page_size(struct kvm *kvm, gfn_t gfn) ++unsigned long kvm_host_page_size(struct kvm_vcpu *vcpu, gfn_t gfn) + { + struct vm_area_struct *vma; + unsigned long addr, size; + + size = PAGE_SIZE; + +- addr = gfn_to_hva(kvm, gfn); ++ addr = kvm_vcpu_gfn_to_hva(vcpu, gfn); + if (kvm_is_error_hva(addr)) + return PAGE_SIZE; + +-- +2.20.1 + diff --git a/queue-5.5/kvm-x86-protect-exit_reason-from-being-used-in-spect.patch b/queue-5.5/kvm-x86-protect-exit_reason-from-being-used-in-spect.patch new file mode 100644 index 00000000000..aa562043fb5 --- /dev/null +++ b/queue-5.5/kvm-x86-protect-exit_reason-from-being-used-in-spect.patch @@ -0,0 +1,100 @@ +From abc50133003946808122549929225fa1caa4c976 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Dec 2019 12:47:51 -0800 +Subject: KVM: x86: Protect exit_reason from being used in Spectre-v1/L1TF + attacks + +From: Marios Pomonis + +[ Upstream commit c926f2f7230b1a29e31914b51db680f8cbf3103f ] + +This fixes a Spectre-v1/L1TF vulnerability in vmx_handle_exit(). +While exit_reason is set by the hardware and therefore should not be +attacker-influenced, an unknown exit_reason could potentially be used to +perform such an attack. + +Fixes: 55d2375e58a6 ("KVM: nVMX: Move nested code to dedicated files") + +Signed-off-by: Marios Pomonis +Signed-off-by: Nick Finco +Suggested-by: Sean Christopherson +Reviewed-by: Andrew Honig +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/vmx/vmx.c | 55 +++++++++++++++++++++++------------------- + 1 file changed, 30 insertions(+), 25 deletions(-) + +diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c +index 83464a86ac405..78e01e2524bc3 100644 +--- a/arch/x86/kvm/vmx/vmx.c ++++ b/arch/x86/kvm/vmx/vmx.c +@@ -5904,34 +5904,39 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) + } + } + +- if (exit_reason < kvm_vmx_max_exit_handlers +- && kvm_vmx_exit_handlers[exit_reason]) { ++ if (exit_reason >= kvm_vmx_max_exit_handlers) ++ goto unexpected_vmexit; + #ifdef CONFIG_RETPOLINE +- if (exit_reason == EXIT_REASON_MSR_WRITE) +- return kvm_emulate_wrmsr(vcpu); +- else if (exit_reason == EXIT_REASON_PREEMPTION_TIMER) +- return handle_preemption_timer(vcpu); +- else if (exit_reason == EXIT_REASON_PENDING_INTERRUPT) +- return handle_interrupt_window(vcpu); +- else if (exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) +- return handle_external_interrupt(vcpu); +- else if (exit_reason == EXIT_REASON_HLT) +- return kvm_emulate_halt(vcpu); +- else if (exit_reason == EXIT_REASON_EPT_MISCONFIG) +- return handle_ept_misconfig(vcpu); ++ if (exit_reason == EXIT_REASON_MSR_WRITE) ++ return kvm_emulate_wrmsr(vcpu); ++ else if (exit_reason == EXIT_REASON_PREEMPTION_TIMER) ++ return handle_preemption_timer(vcpu); ++ else if (exit_reason == EXIT_REASON_PENDING_INTERRUPT) ++ return handle_interrupt_window(vcpu); ++ else if (exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) ++ return handle_external_interrupt(vcpu); ++ else if (exit_reason == EXIT_REASON_HLT) ++ return kvm_emulate_halt(vcpu); ++ else if (exit_reason == EXIT_REASON_EPT_MISCONFIG) ++ return handle_ept_misconfig(vcpu); + #endif +- return kvm_vmx_exit_handlers[exit_reason](vcpu); +- } else { +- vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n", +- exit_reason); +- dump_vmcs(); +- vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; +- vcpu->run->internal.suberror = ++ ++ exit_reason = array_index_nospec(exit_reason, ++ kvm_vmx_max_exit_handlers); ++ if (!kvm_vmx_exit_handlers[exit_reason]) ++ goto unexpected_vmexit; ++ ++ return kvm_vmx_exit_handlers[exit_reason](vcpu); ++ ++unexpected_vmexit: ++ vcpu_unimpl(vcpu, "vmx: unexpected exit reason 0x%x\n", exit_reason); ++ dump_vmcs(); ++ vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR; ++ vcpu->run->internal.suberror = + KVM_INTERNAL_ERROR_UNEXPECTED_EXIT_REASON; +- vcpu->run->internal.ndata = 1; +- vcpu->run->internal.data[0] = exit_reason; +- return 0; +- } ++ vcpu->run->internal.ndata = 1; ++ vcpu->run->internal.data[0] = exit_reason; ++ return 0; + } + + /* +-- +2.20.1 + diff --git a/queue-5.5/series b/queue-5.5/series index 22c6f4b3925..e7147c19598 100644 --- a/queue-5.5/series +++ b/queue-5.5/series @@ -344,3 +344,10 @@ net-mlx5-fix-deadlock-in-fs_core.patch net-mlx5-deprecate-usage-of-generic-tls-hw-capability-bit.patch r8169-fix-performance-regression-related-to-pcie-max-read-request-size.patch net-mlx5e-tx-error-completion-is-for-last-wqe-in-batch.patch +drm-dp_mst-remove-vcpi-while-disabling-topology-mgr.patch +io_uring-enable-option-to-only-trigger-eventfd-for-a.patch +io_uring-prevent-potential-eventfd-recursion-on-poll.patch +kvm-x86-protect-exit_reason-from-being-used-in-spect.patch +kvm-nvmx-vmread-should-not-set-rflags-to-specify-suc.patch +kvm-use-vcpu-specific-gva-hva-translation-when-query.patch +kvm-play-nice-with-read-only-memslots-when-querying-.patch