]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 5.5
authorSasha Levin <sashal@kernel.org>
Sun, 9 Feb 2020 22:18:06 +0000 (17:18 -0500)
committerSasha Levin <sashal@kernel.org>
Sun, 9 Feb 2020 22:18:06 +0000 (17:18 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.5/drm-dp_mst-remove-vcpi-while-disabling-topology-mgr.patch [new file with mode: 0644]
queue-5.5/io_uring-enable-option-to-only-trigger-eventfd-for-a.patch [new file with mode: 0644]
queue-5.5/io_uring-prevent-potential-eventfd-recursion-on-poll.patch [new file with mode: 0644]
queue-5.5/kvm-nvmx-vmread-should-not-set-rflags-to-specify-suc.patch [new file with mode: 0644]
queue-5.5/kvm-play-nice-with-read-only-memslots-when-querying-.patch [new file with mode: 0644]
queue-5.5/kvm-use-vcpu-specific-gva-hva-translation-when-query.patch [new file with mode: 0644]
queue-5.5/kvm-x86-protect-exit_reason-from-being-used-in-spect.patch [new file with mode: 0644]
queue-5.5/series

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 (file)
index 0000000..49984fe
--- /dev/null
@@ -0,0 +1,92 @@
+From c4178d0812bd5f527887399068bd140088e524fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 5 Dec 2019 17:00:43 +0800
+Subject: drm/dp_mst: Remove VCPI while disabling topology mgr
+
+From: Wayne Lin <Wayne.Lin@amd.com>
+
+[ 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 <Wayne.Lin@amd.com>
+[added cc to stable]
+Signed-off-by: Lyude Paul <lyude@redhat.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20191205090043.7580-1-Wayne.Lin@amd.com
+Cc: <stable@vger.kernel.org> # v3.17+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..12f930f
--- /dev/null
@@ -0,0 +1,93 @@
+From c4c0dcdb50ad05f7000a01346f78a2c3c2d8e9b5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <markuspapadakis@icloud.com>
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..02a9fed
--- /dev/null
@@ -0,0 +1,104 @@
+From 880668254d7a1af40a1d61935c320ef6aa09c19f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 1 Feb 2020 21:30:11 -0700
+Subject: io_uring: prevent potential eventfd recursion on poll
+
+From: Jens Axboe <axboe@kernel.dk>
+
+[ 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 <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..08b42a7
--- /dev/null
@@ -0,0 +1,43 @@
+From 09e3f0530749ac7f1af70eafb55a3406e7e4e118 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <linmiaohe@huawei.com>
+
+[ 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 <liran.alon@oracle.com>
+Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..14bdedc
--- /dev/null
@@ -0,0 +1,46 @@
+From 80004a1a11dca14573c250af4b42d2871a6b25c5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <sean.j.christopherson@intel.com>
+
+[ 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 <sean.j.christopherson@intel.com>
+[Redone using kvm_vcpu_gfn_to_memslot_prot. - Paolo]
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..1e698f8
--- /dev/null
@@ -0,0 +1,103 @@
+From eed6e811c175b70e1c8bd362c90d2a20c54ad92a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <sean.j.christopherson@intel.com>
+
+[ 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 <sean.j.christopherson@intel.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..aa56204
--- /dev/null
@@ -0,0 +1,100 @@
+From abc50133003946808122549929225fa1caa4c976 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <pomonis@google.com>
+
+[ 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 <pomonis@google.com>
+Signed-off-by: Nick Finco <nifi@google.com>
+Suggested-by: Sean Christopherson <sean.j.christopherson@intel.com>
+Reviewed-by: Andrew Honig <ahonig@google.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 22c6f4b392589adbf2a8d783a3a9802e7bff6fb7..e7147c19598ca49dccadee1d76bd663d6f5f9004 100644 (file)
@@ -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