From: Greg Kroah-Hartman Date: Sun, 3 Apr 2022 08:46:54 +0000 (+0200) Subject: 5.17-stable patches X-Git-Tag: v5.17.2~153 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae08e08cec93155269bed21a2e0657c2ce5d6ede;p=thirdparty%2Fkernel%2Fstable-queue.git 5.17-stable patches added patches: kvm-avoid-double-put_page-with-gfn-to-pfn-cache.patch kvm-prevent-module-exit-until-all-vms-are-freed.patch kvm-svm-fix-panic-on-out-of-bounds-guest-irq.patch kvm-x86-avoid-theoretical-null-pointer-dereference-in-kvm_irq_delivery_to_apic_fast.patch kvm-x86-check-lapic_in_kernel-before-attempting-to-set-a-synic-irq.patch kvm-x86-fix-sending-pv-ipi.patch kvm-x86-forbid-vmm-to-set-synic-stimer-msrs-when-synic-wasn-t-activated.patch kvm-x86-mmu-do-compare-and-exchange-of-gpte-via-the-user-address.patch mips-crypto-fix-crc32-code.patch platform-chrome-split-trace-include-file.patch --- diff --git a/queue-5.17/kvm-avoid-double-put_page-with-gfn-to-pfn-cache.patch b/queue-5.17/kvm-avoid-double-put_page-with-gfn-to-pfn-cache.patch new file mode 100644 index 00000000000..ff7643393b5 --- /dev/null +++ b/queue-5.17/kvm-avoid-double-put_page-with-gfn-to-pfn-cache.patch @@ -0,0 +1,34 @@ +From 79593c086eb95eb2886f36ee6f78a1d6845e1bdf Mon Sep 17 00:00:00 2001 +From: David Woodhouse +Date: Tue, 29 Mar 2022 13:11:47 -0400 +Subject: KVM: avoid double put_page with gfn-to-pfn cache + +From: David Woodhouse + +commit 79593c086eb95eb2886f36ee6f78a1d6845e1bdf upstream. + +If the cache's user host virtual address becomes invalid, there +is still a path from kvm_gfn_to_pfn_cache_refresh() where __release_gpc() +could release the pfn but the gpc->pfn field has not been overwritten +with an error value. If this happens, kvm_gfn_to_pfn_cache_unmap will +call put_page again on the same page. + +Cc: stable@vger.kernel.org +Fixes: 982ed0de4753 ("KVM: Reinstate gfn_to_pfn_cache with invalidation support") +Signed-off-by: David Woodhouse +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/pfncache.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/virt/kvm/pfncache.c ++++ b/virt/kvm/pfncache.c +@@ -191,6 +191,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct + gpc->uhva = gfn_to_hva_memslot(gpc->memslot, gfn); + + if (kvm_is_error_hva(gpc->uhva)) { ++ gpc->pfn = KVM_PFN_ERR_FAULT; + ret = -EFAULT; + goto out; + } diff --git a/queue-5.17/kvm-prevent-module-exit-until-all-vms-are-freed.patch b/queue-5.17/kvm-prevent-module-exit-until-all-vms-are-freed.patch new file mode 100644 index 00000000000..c0ae0f58a32 --- /dev/null +++ b/queue-5.17/kvm-prevent-module-exit-until-all-vms-are-freed.patch @@ -0,0 +1,75 @@ +From 5f6de5cbebee925a612856fce6f9182bb3eee0db Mon Sep 17 00:00:00 2001 +From: David Matlack +Date: Thu, 3 Mar 2022 18:33:27 +0000 +Subject: KVM: Prevent module exit until all VMs are freed + +From: David Matlack + +commit 5f6de5cbebee925a612856fce6f9182bb3eee0db upstream. + +Tie the lifetime the KVM module to the lifetime of each VM via +kvm.users_count. This way anything that grabs a reference to the VM via +kvm_get_kvm() cannot accidentally outlive the KVM module. + +Prior to this commit, the lifetime of the KVM module was tied to the +lifetime of /dev/kvm file descriptors, VM file descriptors, and vCPU +file descriptors by their respective file_operations "owner" field. +This approach is insufficient because references grabbed via +kvm_get_kvm() do not prevent closing any of the aforementioned file +descriptors. + +This fixes a long standing theoretical bug in KVM that at least affects +async page faults. kvm_setup_async_pf() grabs a reference via +kvm_get_kvm(), and drops it in an asynchronous work callback. Nothing +prevents the VM file descriptor from being closed and the KVM module +from being unloaded before this callback runs. + +Fixes: af585b921e5d ("KVM: Halt vcpu if page it tries to access is swapped out") +Fixes: 3d3aab1b973b ("KVM: set owner of cpu and vm file operations") +Cc: stable@vger.kernel.org +Suggested-by: Ben Gardon +[ Based on a patch from Ben implemented for Google's kernel. ] +Signed-off-by: David Matlack +Message-Id: <20220303183328.1499189-2-dmatlack@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + virt/kvm/kvm_main.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -117,6 +117,8 @@ EXPORT_SYMBOL_GPL(kvm_debugfs_dir); + + static const struct file_operations stat_fops_per_vm; + ++static struct file_operations kvm_chardev_ops; ++ + static long kvm_vcpu_ioctl(struct file *file, unsigned int ioctl, + unsigned long arg); + #ifdef CONFIG_KVM_COMPAT +@@ -1137,6 +1139,16 @@ static struct kvm *kvm_create_vm(unsigne + preempt_notifier_inc(); + kvm_init_pm_notifier(kvm); + ++ /* ++ * When the fd passed to this ioctl() is opened it pins the module, ++ * but try_module_get() also prevents getting a reference if the module ++ * is in MODULE_STATE_GOING (e.g. if someone ran "rmmod --wait"). ++ */ ++ if (!try_module_get(kvm_chardev_ops.owner)) { ++ r = -ENODEV; ++ goto out_err; ++ } ++ + return kvm; + + out_err: +@@ -1226,6 +1238,7 @@ static void kvm_destroy_vm(struct kvm *k + preempt_notifier_dec(); + hardware_disable_all(); + mmdrop(mm); ++ module_put(kvm_chardev_ops.owner); + } + + void kvm_get_kvm(struct kvm *kvm) diff --git a/queue-5.17/kvm-svm-fix-panic-on-out-of-bounds-guest-irq.patch b/queue-5.17/kvm-svm-fix-panic-on-out-of-bounds-guest-irq.patch new file mode 100644 index 00000000000..5d57a6b0857 --- /dev/null +++ b/queue-5.17/kvm-svm-fix-panic-on-out-of-bounds-guest-irq.patch @@ -0,0 +1,81 @@ +From a80ced6ea514000d34bf1239d47553de0d1ee89e Mon Sep 17 00:00:00 2001 +From: Yi Wang +Date: Wed, 9 Mar 2022 19:30:25 +0800 +Subject: KVM: SVM: fix panic on out-of-bounds guest IRQ + +From: Yi Wang + +commit a80ced6ea514000d34bf1239d47553de0d1ee89e upstream. + +As guest_irq is coming from KVM_IRQFD API call, it may trigger +crash in svm_update_pi_irte() due to out-of-bounds: + +crash> bt +PID: 22218 TASK: ffff951a6ad74980 CPU: 73 COMMAND: "vcpu8" + #0 [ffffb1ba6707fa40] machine_kexec at ffffffff8565b397 + #1 [ffffb1ba6707fa90] __crash_kexec at ffffffff85788a6d + #2 [ffffb1ba6707fb58] crash_kexec at ffffffff8578995d + #3 [ffffb1ba6707fb70] oops_end at ffffffff85623c0d + #4 [ffffb1ba6707fb90] no_context at ffffffff856692c9 + #5 [ffffb1ba6707fbf8] exc_page_fault at ffffffff85f95b51 + #6 [ffffb1ba6707fc50] asm_exc_page_fault at ffffffff86000ace + [exception RIP: svm_update_pi_irte+227] + RIP: ffffffffc0761b53 RSP: ffffb1ba6707fd08 RFLAGS: 00010086 + RAX: ffffb1ba6707fd78 RBX: ffffb1ba66d91000 RCX: 0000000000000001 + RDX: 00003c803f63f1c0 RSI: 000000000000019a RDI: ffffb1ba66db2ab8 + RBP: 000000000000019a R8: 0000000000000040 R9: ffff94ca41b82200 + R10: ffffffffffffffcf R11: 0000000000000001 R12: 0000000000000001 + R13: 0000000000000001 R14: ffffffffffffffcf R15: 000000000000005f + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + #7 [ffffb1ba6707fdb8] kvm_irq_routing_update at ffffffffc09f19a1 [kvm] + #8 [ffffb1ba6707fde0] kvm_set_irq_routing at ffffffffc09f2133 [kvm] + #9 [ffffb1ba6707fe18] kvm_vm_ioctl at ffffffffc09ef544 [kvm] + RIP: 00007f143c36488b RSP: 00007f143a4e04b8 RFLAGS: 00000246 + RAX: ffffffffffffffda RBX: 00007f05780041d0 RCX: 00007f143c36488b + RDX: 00007f05780041d0 RSI: 000000004008ae6a RDI: 0000000000000020 + RBP: 00000000000004e8 R8: 0000000000000008 R9: 00007f05780041e0 + R10: 00007f0578004560 R11: 0000000000000246 R12: 00000000000004e0 + R13: 000000000000001a R14: 00007f1424001c60 R15: 00007f0578003bc0 + ORIG_RAX: 0000000000000010 CS: 0033 SS: 002b + +Vmx have been fix this in commit 3a8b0677fc61 (KVM: VMX: Do not BUG() on +out-of-bounds guest IRQ), so we can just copy source from that to fix +this. + +Co-developed-by: Yi Liu +Signed-off-by: Yi Liu +Signed-off-by: Yi Wang +Message-Id: <20220309113025.44469-1-wang.yi59@zte.com.cn> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/svm/avic.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/x86/kvm/svm/avic.c ++++ b/arch/x86/kvm/svm/avic.c +@@ -783,7 +783,7 @@ int svm_update_pi_irte(struct kvm *kvm, + { + struct kvm_kernel_irq_routing_entry *e; + struct kvm_irq_routing_table *irq_rt; +- int idx, ret = -EINVAL; ++ int idx, ret = 0; + + if (!kvm_arch_has_assigned_device(kvm) || + !irq_remapping_cap(IRQ_POSTING_CAP)) +@@ -794,7 +794,13 @@ int svm_update_pi_irte(struct kvm *kvm, + + idx = srcu_read_lock(&kvm->irq_srcu); + irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); +- WARN_ON(guest_irq >= irq_rt->nr_rt_entries); ++ ++ if (guest_irq >= irq_rt->nr_rt_entries || ++ hlist_empty(&irq_rt->map[guest_irq])) { ++ pr_warn_once("no route for guest_irq %u/%u (broken user space?)\n", ++ guest_irq, irq_rt->nr_rt_entries); ++ goto out; ++ } + + hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) { + struct vcpu_data vcpu_info; diff --git a/queue-5.17/kvm-x86-avoid-theoretical-null-pointer-dereference-in-kvm_irq_delivery_to_apic_fast.patch b/queue-5.17/kvm-x86-avoid-theoretical-null-pointer-dereference-in-kvm_irq_delivery_to_apic_fast.patch new file mode 100644 index 00000000000..fb8006e1e0e --- /dev/null +++ b/queue-5.17/kvm-x86-avoid-theoretical-null-pointer-dereference-in-kvm_irq_delivery_to_apic_fast.patch @@ -0,0 +1,35 @@ +From 00b5f37189d24ac3ed46cb7f11742094778c46ce Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 25 Mar 2022 14:21:39 +0100 +Subject: KVM: x86: Avoid theoretical NULL pointer dereference in kvm_irq_delivery_to_apic_fast() + +From: Vitaly Kuznetsov + +commit 00b5f37189d24ac3ed46cb7f11742094778c46ce upstream. + +When kvm_irq_delivery_to_apic_fast() is called with APIC_DEST_SELF +shorthand, 'src' must not be NULL. Crash the VM with KVM_BUG_ON() +instead of crashing the host. + +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220325132140.25650-3-vkuznets@redhat.com> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/lapic.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -992,6 +992,10 @@ bool kvm_irq_delivery_to_apic_fast(struc + *r = -1; + + if (irq->shorthand == APIC_DEST_SELF) { ++ if (KVM_BUG_ON(!src, kvm)) { ++ *r = 0; ++ return true; ++ } + *r = kvm_apic_set_irq(src->vcpu, irq, dest_map); + return true; + } diff --git a/queue-5.17/kvm-x86-check-lapic_in_kernel-before-attempting-to-set-a-synic-irq.patch b/queue-5.17/kvm-x86-check-lapic_in_kernel-before-attempting-to-set-a-synic-irq.patch new file mode 100644 index 00000000000..774b5349157 --- /dev/null +++ b/queue-5.17/kvm-x86-check-lapic_in_kernel-before-attempting-to-set-a-synic-irq.patch @@ -0,0 +1,39 @@ +From 7ec37d1cbe17d8189d9562178d8b29167fe1c31a Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 25 Mar 2022 14:21:38 +0100 +Subject: KVM: x86: Check lapic_in_kernel() before attempting to set a SynIC irq + +From: Vitaly Kuznetsov + +commit 7ec37d1cbe17d8189d9562178d8b29167fe1c31a upstream. + +When KVM_CAP_HYPERV_SYNIC{,2} is activated, KVM already checks for +irqchip_in_kernel() so normally SynIC irqs should never be set. It is, +however, possible for a misbehaving VMM to write to SYNIC/STIMER MSRs +causing erroneous behavior. + +The immediate issue being fixed is that kvm_irq_delivery_to_apic() +(kvm_irq_delivery_to_apic_fast()) crashes when called with +'irq.shorthand = APIC_DEST_SELF' and 'src == NULL'. + +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220325132140.25650-2-vkuznets@redhat.com> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/hyperv.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -446,6 +446,9 @@ static int synic_set_irq(struct kvm_vcpu + struct kvm_lapic_irq irq; + int ret, vector; + ++ if (KVM_BUG_ON(!lapic_in_kernel(vcpu), vcpu->kvm)) ++ return -EINVAL; ++ + if (sint >= ARRAY_SIZE(synic->sint)) + return -EINVAL; + diff --git a/queue-5.17/kvm-x86-fix-sending-pv-ipi.patch b/queue-5.17/kvm-x86-fix-sending-pv-ipi.patch new file mode 100644 index 00000000000..3a2e3274b03 --- /dev/null +++ b/queue-5.17/kvm-x86-fix-sending-pv-ipi.patch @@ -0,0 +1,38 @@ +From c15e0ae42c8e5a61e9aca8aac920517cf7b3e94e Mon Sep 17 00:00:00 2001 +From: Li RongQing +Date: Wed, 9 Mar 2022 16:35:44 +0800 +Subject: KVM: x86: fix sending PV IPI + +From: Li RongQing + +commit c15e0ae42c8e5a61e9aca8aac920517cf7b3e94e upstream. + +If apic_id is less than min, and (max - apic_id) is greater than +KVM_IPI_CLUSTER_SIZE, then the third check condition is satisfied but +the new apic_id does not fit the bitmask. In this case __send_ipi_mask +should send the IPI. + +This is mostly theoretical, but it can happen if the apic_ids on three +iterations of the loop are for example 1, KVM_IPI_CLUSTER_SIZE, 0. + +Fixes: aaffcfd1e82 ("KVM: X86: Implement PV IPIs in linux guest") +Signed-off-by: Li RongQing +Message-Id: <1646814944-51801-1-git-send-email-lirongqing@baidu.com> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/kvm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/kvm.c ++++ b/arch/x86/kernel/kvm.c +@@ -517,7 +517,7 @@ static void __send_ipi_mask(const struct + } else if (apic_id < min && max - apic_id < KVM_IPI_CLUSTER_SIZE) { + ipi_bitmap <<= min - apic_id; + min = apic_id; +- } else if (apic_id < min + KVM_IPI_CLUSTER_SIZE) { ++ } else if (apic_id > min && apic_id < min + KVM_IPI_CLUSTER_SIZE) { + max = apic_id < max ? max : apic_id; + } else { + ret = kvm_hypercall4(KVM_HC_SEND_IPI, (unsigned long)ipi_bitmap, diff --git a/queue-5.17/kvm-x86-forbid-vmm-to-set-synic-stimer-msrs-when-synic-wasn-t-activated.patch b/queue-5.17/kvm-x86-forbid-vmm-to-set-synic-stimer-msrs-when-synic-wasn-t-activated.patch new file mode 100644 index 00000000000..5be0c194657 --- /dev/null +++ b/queue-5.17/kvm-x86-forbid-vmm-to-set-synic-stimer-msrs-when-synic-wasn-t-activated.patch @@ -0,0 +1,66 @@ +From b1e34d325397a33d97d845e312d7cf2a8b646b44 Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Fri, 25 Mar 2022 14:21:40 +0100 +Subject: KVM: x86: Forbid VMM to set SYNIC/STIMER MSRs when SynIC wasn't activated + +From: Vitaly Kuznetsov + +commit b1e34d325397a33d97d845e312d7cf2a8b646b44 upstream. + +Setting non-zero values to SYNIC/STIMER MSRs activates certain features, +this should not happen when KVM_CAP_HYPERV_SYNIC{,2} was not activated. + +Note, it would've been better to forbid writing anything to SYNIC/STIMER +MSRs, including zeroes, however, at least QEMU tries clearing +HV_X64_MSR_STIMER0_CONFIG without SynIC. HV_X64_MSR_EOM MSR is somewhat +'special' as writing zero there triggers an action, this also should not +happen when SynIC wasn't activated. + +Signed-off-by: Vitaly Kuznetsov +Message-Id: <20220325132140.25650-4-vkuznets@redhat.com> +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/hyperv.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/arch/x86/kvm/hyperv.c ++++ b/arch/x86/kvm/hyperv.c +@@ -236,7 +236,7 @@ static int synic_set_msr(struct kvm_vcpu + struct kvm_vcpu *vcpu = hv_synic_to_vcpu(synic); + int ret; + +- if (!synic->active && !host) ++ if (!synic->active && (!host || data)) + return 1; + + trace_kvm_hv_synic_set_msr(vcpu->vcpu_id, msr, data, host); +@@ -282,6 +282,9 @@ static int synic_set_msr(struct kvm_vcpu + case HV_X64_MSR_EOM: { + int i; + ++ if (!synic->active) ++ break; ++ + for (i = 0; i < ARRAY_SIZE(synic->sint); i++) + kvm_hv_notify_acked_sint(vcpu, i); + break; +@@ -661,7 +664,7 @@ static int stimer_set_config(struct kvm_ + struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu); + struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu); + +- if (!synic->active && !host) ++ if (!synic->active && (!host || config)) + return 1; + + if (unlikely(!host && hv_vcpu->enforce_cpuid && new_config.direct_mode && +@@ -690,7 +693,7 @@ static int stimer_set_count(struct kvm_v + struct kvm_vcpu *vcpu = hv_stimer_to_vcpu(stimer); + struct kvm_vcpu_hv_synic *synic = to_hv_synic(vcpu); + +- if (!synic->active && !host) ++ if (!synic->active && (!host || count)) + return 1; + + trace_kvm_hv_stimer_set_count(hv_stimer_to_vcpu(stimer)->vcpu_id, diff --git a/queue-5.17/kvm-x86-mmu-do-compare-and-exchange-of-gpte-via-the-user-address.patch b/queue-5.17/kvm-x86-mmu-do-compare-and-exchange-of-gpte-via-the-user-address.patch new file mode 100644 index 00000000000..4471f048002 --- /dev/null +++ b/queue-5.17/kvm-x86-mmu-do-compare-and-exchange-of-gpte-via-the-user-address.patch @@ -0,0 +1,149 @@ +From 2a8859f373b0a86f0ece8ec8312607eacf12485d Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 29 Mar 2022 12:56:24 -0400 +Subject: KVM: x86/mmu: do compare-and-exchange of gPTE via the user address + +From: Paolo Bonzini + +commit 2a8859f373b0a86f0ece8ec8312607eacf12485d upstream. + +FNAME(cmpxchg_gpte) is an inefficient mess. It is at least decent if it +can go through get_user_pages_fast(), but if it cannot then it tries to +use memremap(); that is not just terribly slow, it is also wrong because +it assumes that the VM_PFNMAP VMA is contiguous. + +The right way to do it would be to do the same thing as +hva_to_pfn_remapped() does since commit add6a0cd1c5b ("KVM: MMU: try to +fix up page faults before giving up", 2016-07-05), using follow_pte() +and fixup_user_fault() to determine the correct address to use for +memremap(). To do this, one could for example extract hva_to_pfn() +for use outside virt/kvm/kvm_main.c. But really there is no reason to +do that either, because there is already a perfectly valid address to +do the cmpxchg() on, only it is a userspace address. That means doing +user_access_begin()/user_access_end() and writing the code in assembly +to handle exceptions correctly. Worse, the guest PTE can be 8-byte +even on i686 so there is the extra complication of using cmpxchg8b to +account for. But at least it is an efficient mess. + +(Thanks to Linus for suggesting improvement on the inline assembly). + +Reported-by: Qiuhao Li +Reported-by: Gaoning Pan +Reported-by: Yongkang Jia +Reported-by: syzbot+6cde2282daa792c49ab8@syzkaller.appspotmail.com +Debugged-by: Tadeusz Struk +Tested-by: Maxim Levitsky +Cc: stable@vger.kernel.org +Fixes: bd53cb35a3e9 ("X86/KVM: Handle PFNs outside of kernel reach when touching GPTEs") +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kvm/mmu/paging_tmpl.h | 74 ++++++++++++++++++----------------------- + 1 file changed, 34 insertions(+), 40 deletions(-) + +--- a/arch/x86/kvm/mmu/paging_tmpl.h ++++ b/arch/x86/kvm/mmu/paging_tmpl.h +@@ -34,9 +34,8 @@ + #define PT_HAVE_ACCESSED_DIRTY(mmu) true + #ifdef CONFIG_X86_64 + #define PT_MAX_FULL_LEVELS PT64_ROOT_MAX_LEVEL +- #define CMPXCHG cmpxchg ++ #define CMPXCHG "cmpxchgq" + #else +- #define CMPXCHG cmpxchg64 + #define PT_MAX_FULL_LEVELS 2 + #endif + #elif PTTYPE == 32 +@@ -52,7 +51,7 @@ + #define PT_GUEST_DIRTY_SHIFT PT_DIRTY_SHIFT + #define PT_GUEST_ACCESSED_SHIFT PT_ACCESSED_SHIFT + #define PT_HAVE_ACCESSED_DIRTY(mmu) true +- #define CMPXCHG cmpxchg ++ #define CMPXCHG "cmpxchgl" + #elif PTTYPE == PTTYPE_EPT + #define pt_element_t u64 + #define guest_walker guest_walkerEPT +@@ -65,7 +64,9 @@ + #define PT_GUEST_DIRTY_SHIFT 9 + #define PT_GUEST_ACCESSED_SHIFT 8 + #define PT_HAVE_ACCESSED_DIRTY(mmu) ((mmu)->ept_ad) +- #define CMPXCHG cmpxchg64 ++ #ifdef CONFIG_X86_64 ++ #define CMPXCHG "cmpxchgq" ++ #endif + #define PT_MAX_FULL_LEVELS PT64_ROOT_MAX_LEVEL + #else + #error Invalid PTTYPE value +@@ -147,43 +148,36 @@ static int FNAME(cmpxchg_gpte)(struct kv + pt_element_t __user *ptep_user, unsigned index, + pt_element_t orig_pte, pt_element_t new_pte) + { +- int npages; +- pt_element_t ret; +- pt_element_t *table; +- struct page *page; +- +- npages = get_user_pages_fast((unsigned long)ptep_user, 1, FOLL_WRITE, &page); +- if (likely(npages == 1)) { +- table = kmap_atomic(page); +- ret = CMPXCHG(&table[index], orig_pte, new_pte); +- kunmap_atomic(table); +- +- kvm_release_page_dirty(page); +- } else { +- struct vm_area_struct *vma; +- unsigned long vaddr = (unsigned long)ptep_user & PAGE_MASK; +- unsigned long pfn; +- unsigned long paddr; +- +- mmap_read_lock(current->mm); +- vma = find_vma_intersection(current->mm, vaddr, vaddr + PAGE_SIZE); +- if (!vma || !(vma->vm_flags & VM_PFNMAP)) { +- mmap_read_unlock(current->mm); +- return -EFAULT; +- } +- pfn = ((vaddr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; +- paddr = pfn << PAGE_SHIFT; +- table = memremap(paddr, PAGE_SIZE, MEMREMAP_WB); +- if (!table) { +- mmap_read_unlock(current->mm); +- return -EFAULT; +- } +- ret = CMPXCHG(&table[index], orig_pte, new_pte); +- memunmap(table); +- mmap_read_unlock(current->mm); +- } ++ signed char r; ++ ++ if (!user_access_begin(ptep_user, sizeof(pt_element_t))) ++ return -EFAULT; ++ ++#ifdef CMPXCHG ++ asm volatile("1:" LOCK_PREFIX CMPXCHG " %[new], %[ptr]\n" ++ "setnz %b[r]\n" ++ "2:" ++ _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %k[r]) ++ : [ptr] "+m" (*ptep_user), ++ [old] "+a" (orig_pte), ++ [r] "=q" (r) ++ : [new] "r" (new_pte) ++ : "memory"); ++#else ++ asm volatile("1:" LOCK_PREFIX "cmpxchg8b %[ptr]\n" ++ "setnz %b[r]\n" ++ "2:" ++ _ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_EFAULT_REG, %k[r]) ++ : [ptr] "+m" (*ptep_user), ++ [old] "+A" (orig_pte), ++ [r] "=q" (r) ++ : [new_lo] "b" ((u32)new_pte), ++ [new_hi] "c" ((u32)(new_pte >> 32)) ++ : "memory"); ++#endif + +- return (ret != orig_pte); ++ user_access_end(); ++ return r; + } + + static bool FNAME(prefetch_invalid_gpte)(struct kvm_vcpu *vcpu, diff --git a/queue-5.17/mips-crypto-fix-crc32-code.patch b/queue-5.17/mips-crypto-fix-crc32-code.patch new file mode 100644 index 00000000000..d4f718bf1f5 --- /dev/null +++ b/queue-5.17/mips-crypto-fix-crc32-code.patch @@ -0,0 +1,96 @@ +From 41022eff9c2d21e658c7a6fcd31005bf514d28b7 Mon Sep 17 00:00:00 2001 +From: Paul Cercueil +Date: Thu, 31 Mar 2022 17:42:00 +0100 +Subject: MIPS: crypto: Fix CRC32 code + +From: Paul Cercueil + +commit 41022eff9c2d21e658c7a6fcd31005bf514d28b7 upstream. + +Commit 67512a8cf5a7 ("MIPS: Avoid macro redefinitions") changed how the +MIPS register macros were defined, in order to allow the code to compile +under LLVM/Clang. + +The MIPS CRC32 code however wasn't updated accordingly, causing a build +bug when using a MIPS32r6 toolchain without CRC support. + +Update the CRC32 code to use the macros correctly, to fix the build +failures. + +Fixes: 67512a8cf5a7 ("MIPS: Avoid macro redefinitions") +Cc: +Signed-off-by: Paul Cercueil +Reported-by: kernel test robot +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/crypto/crc32-mips.c | 46 +++++++++++++++++++++++------------------- + 1 file changed, 26 insertions(+), 20 deletions(-) + +--- a/arch/mips/crypto/crc32-mips.c ++++ b/arch/mips/crypto/crc32-mips.c +@@ -28,7 +28,7 @@ enum crc_type { + }; + + #ifndef TOOLCHAIN_SUPPORTS_CRC +-#define _ASM_MACRO_CRC32(OP, SZ, TYPE) \ ++#define _ASM_SET_CRC(OP, SZ, TYPE) \ + _ASM_MACRO_3R(OP, rt, rs, rt2, \ + ".ifnc \\rt, \\rt2\n\t" \ + ".error \"invalid operands \\\"" #OP " \\rt,\\rs,\\rt2\\\"\"\n\t" \ +@@ -37,30 +37,36 @@ _ASM_MACRO_3R(OP, rt, rs, rt2, \ + ((SZ) << 6) | ((TYPE) << 8)) \ + _ASM_INSN32_IF_MM(0x00000030 | (__rs << 16) | (__rt << 21) | \ + ((SZ) << 14) | ((TYPE) << 3))) +-_ASM_MACRO_CRC32(crc32b, 0, 0); +-_ASM_MACRO_CRC32(crc32h, 1, 0); +-_ASM_MACRO_CRC32(crc32w, 2, 0); +-_ASM_MACRO_CRC32(crc32d, 3, 0); +-_ASM_MACRO_CRC32(crc32cb, 0, 1); +-_ASM_MACRO_CRC32(crc32ch, 1, 1); +-_ASM_MACRO_CRC32(crc32cw, 2, 1); +-_ASM_MACRO_CRC32(crc32cd, 3, 1); +-#define _ASM_SET_CRC "" ++#define _ASM_UNSET_CRC(op, SZ, TYPE) ".purgem " #op "\n\t" + #else /* !TOOLCHAIN_SUPPORTS_CRC */ +-#define _ASM_SET_CRC ".set\tcrc\n\t" ++#define _ASM_SET_CRC(op, SZ, TYPE) ".set\tcrc\n\t" ++#define _ASM_UNSET_CRC(op, SZ, TYPE) + #endif + +-#define _CRC32(crc, value, size, type) \ +-do { \ +- __asm__ __volatile__( \ +- ".set push\n\t" \ +- _ASM_SET_CRC \ +- #type #size " %0, %1, %0\n\t" \ +- ".set pop" \ +- : "+r" (crc) \ +- : "r" (value)); \ ++#define __CRC32(crc, value, op, SZ, TYPE) \ ++do { \ ++ __asm__ __volatile__( \ ++ ".set push\n\t" \ ++ _ASM_SET_CRC(op, SZ, TYPE) \ ++ #op " %0, %1, %0\n\t" \ ++ _ASM_UNSET_CRC(op, SZ, TYPE) \ ++ ".set pop" \ ++ : "+r" (crc) \ ++ : "r" (value)); \ + } while (0) + ++#define _CRC32_crc32b(crc, value) __CRC32(crc, value, crc32b, 0, 0) ++#define _CRC32_crc32h(crc, value) __CRC32(crc, value, crc32h, 1, 0) ++#define _CRC32_crc32w(crc, value) __CRC32(crc, value, crc32w, 2, 0) ++#define _CRC32_crc32d(crc, value) __CRC32(crc, value, crc32d, 3, 0) ++#define _CRC32_crc32cb(crc, value) __CRC32(crc, value, crc32cb, 0, 1) ++#define _CRC32_crc32ch(crc, value) __CRC32(crc, value, crc32ch, 1, 1) ++#define _CRC32_crc32cw(crc, value) __CRC32(crc, value, crc32cw, 2, 1) ++#define _CRC32_crc32cd(crc, value) __CRC32(crc, value, crc32cd, 3, 1) ++ ++#define _CRC32(crc, value, size, op) \ ++ _CRC32_##op##size(crc, value) ++ + #define CRC32(crc, value, size) \ + _CRC32(crc, value, size, crc32) + diff --git a/queue-5.17/platform-chrome-split-trace-include-file.patch b/queue-5.17/platform-chrome-split-trace-include-file.patch new file mode 100644 index 00000000000..c16f57744bc --- /dev/null +++ b/queue-5.17/platform-chrome-split-trace-include-file.patch @@ -0,0 +1,303 @@ +From eabd9a3807e17e211690e6c40f1405b427b64c48 Mon Sep 17 00:00:00 2001 +From: Gwendal Grignou +Date: Fri, 21 Jan 2022 16:13:01 -0800 +Subject: platform: chrome: Split trace include file + +From: Gwendal Grignou + +commit eabd9a3807e17e211690e6c40f1405b427b64c48 upstream. + +cros_ec_trace.h defined 5 tracing events, 2 for cros_ec_proto and +3 for cros_ec_sensorhub_ring. +These 2 files are in different kernel modules, the traces are defined +twice in the kernel which leads to problem enabling only some traces. + +Move sensorhub traces from cros_ec_trace.h to cros_ec_sensorhub_trace.h +and enable them only in cros_ec_sensorhub kernel module. + +Check we can now enable any single traces: without this patch, +we can only enable all sensorhub traces or none. + +Fixes: d453ceb6549a ("platform/chrome: sensorhub: Add trace events for sample") + +Signed-off-by: Gwendal Grignou +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20220122001301.640337-1-gwendal@chromium.org +Signed-off-by: Benson Leung +Signed-off-by: Greg Kroah-Hartman +--- + drivers/platform/chrome/Makefile | 3 + drivers/platform/chrome/cros_ec_sensorhub_ring.c | 3 + drivers/platform/chrome/cros_ec_sensorhub_trace.h | 123 ++++++++++++++++++++++ + drivers/platform/chrome/cros_ec_trace.h | 95 ---------------- + 4 files changed, 127 insertions(+), 97 deletions(-) + create mode 100644 drivers/platform/chrome/cros_ec_sensorhub_trace.h + +--- a/drivers/platform/chrome/Makefile ++++ b/drivers/platform/chrome/Makefile +@@ -2,6 +2,7 @@ + + # tell define_trace.h where to find the cros ec trace header + CFLAGS_cros_ec_trace.o:= -I$(src) ++CFLAGS_cros_ec_sensorhub_ring.o:= -I$(src) + + obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o + obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o +@@ -20,7 +21,7 @@ obj-$(CONFIG_CROS_EC_CHARDEV) += cros_e + obj-$(CONFIG_CROS_EC_LIGHTBAR) += cros_ec_lightbar.o + obj-$(CONFIG_CROS_EC_VBC) += cros_ec_vbc.o + obj-$(CONFIG_CROS_EC_DEBUGFS) += cros_ec_debugfs.o +-cros-ec-sensorhub-objs := cros_ec_sensorhub.o cros_ec_sensorhub_ring.o cros_ec_trace.o ++cros-ec-sensorhub-objs := cros_ec_sensorhub.o cros_ec_sensorhub_ring.o + obj-$(CONFIG_CROS_EC_SENSORHUB) += cros-ec-sensorhub.o + obj-$(CONFIG_CROS_EC_SYSFS) += cros_ec_sysfs.o + obj-$(CONFIG_CROS_USBPD_LOGGER) += cros_usbpd_logger.o +--- a/drivers/platform/chrome/cros_ec_sensorhub_ring.c ++++ b/drivers/platform/chrome/cros_ec_sensorhub_ring.c +@@ -17,7 +17,8 @@ + #include + #include + +-#include "cros_ec_trace.h" ++#define CREATE_TRACE_POINTS ++#include "cros_ec_sensorhub_trace.h" + + /* Precision of fixed point for the m values from the filter */ + #define M_PRECISION BIT(23) +--- /dev/null ++++ b/drivers/platform/chrome/cros_ec_sensorhub_trace.h +@@ -0,0 +1,123 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Trace events for the ChromeOS Sensorhub kernel module ++ * ++ * Copyright 2021 Google LLC. ++ */ ++ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM cros_ec ++ ++#if !defined(_CROS_EC_SENSORHUB_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) ++#define _CROS_EC_SENSORHUB_TRACE_H_ ++ ++#include ++#include ++ ++#include ++ ++TRACE_EVENT(cros_ec_sensorhub_timestamp, ++ TP_PROTO(u32 ec_sample_timestamp, u32 ec_fifo_timestamp, s64 fifo_timestamp, ++ s64 current_timestamp, s64 current_time), ++ TP_ARGS(ec_sample_timestamp, ec_fifo_timestamp, fifo_timestamp, current_timestamp, ++ current_time), ++ TP_STRUCT__entry( ++ __field(u32, ec_sample_timestamp) ++ __field(u32, ec_fifo_timestamp) ++ __field(s64, fifo_timestamp) ++ __field(s64, current_timestamp) ++ __field(s64, current_time) ++ __field(s64, delta) ++ ), ++ TP_fast_assign( ++ __entry->ec_sample_timestamp = ec_sample_timestamp; ++ __entry->ec_fifo_timestamp = ec_fifo_timestamp; ++ __entry->fifo_timestamp = fifo_timestamp; ++ __entry->current_timestamp = current_timestamp; ++ __entry->current_time = current_time; ++ __entry->delta = current_timestamp - current_time; ++ ), ++ TP_printk("ec_ts: %9u, ec_fifo_ts: %9u, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", ++ __entry->ec_sample_timestamp, ++ __entry->ec_fifo_timestamp, ++ __entry->fifo_timestamp, ++ __entry->current_timestamp, ++ __entry->current_time, ++ __entry->delta ++ ) ++); ++ ++TRACE_EVENT(cros_ec_sensorhub_data, ++ TP_PROTO(u32 ec_sensor_num, u32 ec_fifo_timestamp, s64 fifo_timestamp, ++ s64 current_timestamp, s64 current_time), ++ TP_ARGS(ec_sensor_num, ec_fifo_timestamp, fifo_timestamp, current_timestamp, current_time), ++ TP_STRUCT__entry( ++ __field(u32, ec_sensor_num) ++ __field(u32, ec_fifo_timestamp) ++ __field(s64, fifo_timestamp) ++ __field(s64, current_timestamp) ++ __field(s64, current_time) ++ __field(s64, delta) ++ ), ++ TP_fast_assign( ++ __entry->ec_sensor_num = ec_sensor_num; ++ __entry->ec_fifo_timestamp = ec_fifo_timestamp; ++ __entry->fifo_timestamp = fifo_timestamp; ++ __entry->current_timestamp = current_timestamp; ++ __entry->current_time = current_time; ++ __entry->delta = current_timestamp - current_time; ++ ), ++ TP_printk("ec_num: %4u, ec_fifo_ts: %9u, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", ++ __entry->ec_sensor_num, ++ __entry->ec_fifo_timestamp, ++ __entry->fifo_timestamp, ++ __entry->current_timestamp, ++ __entry->current_time, ++ __entry->delta ++ ) ++); ++ ++TRACE_EVENT(cros_ec_sensorhub_filter, ++ TP_PROTO(struct cros_ec_sensors_ts_filter_state *state, s64 dx, s64 dy), ++ TP_ARGS(state, dx, dy), ++ TP_STRUCT__entry( ++ __field(s64, dx) ++ __field(s64, dy) ++ __field(s64, median_m) ++ __field(s64, median_error) ++ __field(s64, history_len) ++ __field(s64, x) ++ __field(s64, y) ++ ), ++ TP_fast_assign( ++ __entry->dx = dx; ++ __entry->dy = dy; ++ __entry->median_m = state->median_m; ++ __entry->median_error = state->median_error; ++ __entry->history_len = state->history_len; ++ __entry->x = state->x_offset; ++ __entry->y = state->y_offset; ++ ), ++ TP_printk("dx: %12lld. dy: %12lld median_m: %12lld median_error: %12lld len: %lld x: %12lld y: %12lld", ++ __entry->dx, ++ __entry->dy, ++ __entry->median_m, ++ __entry->median_error, ++ __entry->history_len, ++ __entry->x, ++ __entry->y ++ ) ++); ++ ++ ++#endif /* _CROS_EC_SENSORHUB_TRACE_H_ */ ++ ++/* this part must be outside header guard */ ++ ++#undef TRACE_INCLUDE_PATH ++#define TRACE_INCLUDE_PATH . ++ ++#undef TRACE_INCLUDE_FILE ++#define TRACE_INCLUDE_FILE cros_ec_sensorhub_trace ++ ++#include +--- a/drivers/platform/chrome/cros_ec_trace.h ++++ b/drivers/platform/chrome/cros_ec_trace.h +@@ -15,7 +15,6 @@ + #include + #include + #include +-#include + + #include + +@@ -71,100 +70,6 @@ TRACE_EVENT(cros_ec_request_done, + __entry->retval) + ); + +-TRACE_EVENT(cros_ec_sensorhub_timestamp, +- TP_PROTO(u32 ec_sample_timestamp, u32 ec_fifo_timestamp, s64 fifo_timestamp, +- s64 current_timestamp, s64 current_time), +- TP_ARGS(ec_sample_timestamp, ec_fifo_timestamp, fifo_timestamp, current_timestamp, +- current_time), +- TP_STRUCT__entry( +- __field(u32, ec_sample_timestamp) +- __field(u32, ec_fifo_timestamp) +- __field(s64, fifo_timestamp) +- __field(s64, current_timestamp) +- __field(s64, current_time) +- __field(s64, delta) +- ), +- TP_fast_assign( +- __entry->ec_sample_timestamp = ec_sample_timestamp; +- __entry->ec_fifo_timestamp = ec_fifo_timestamp; +- __entry->fifo_timestamp = fifo_timestamp; +- __entry->current_timestamp = current_timestamp; +- __entry->current_time = current_time; +- __entry->delta = current_timestamp - current_time; +- ), +- TP_printk("ec_ts: %9u, ec_fifo_ts: %9u, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", +- __entry->ec_sample_timestamp, +- __entry->ec_fifo_timestamp, +- __entry->fifo_timestamp, +- __entry->current_timestamp, +- __entry->current_time, +- __entry->delta +- ) +-); +- +-TRACE_EVENT(cros_ec_sensorhub_data, +- TP_PROTO(u32 ec_sensor_num, u32 ec_fifo_timestamp, s64 fifo_timestamp, +- s64 current_timestamp, s64 current_time), +- TP_ARGS(ec_sensor_num, ec_fifo_timestamp, fifo_timestamp, current_timestamp, current_time), +- TP_STRUCT__entry( +- __field(u32, ec_sensor_num) +- __field(u32, ec_fifo_timestamp) +- __field(s64, fifo_timestamp) +- __field(s64, current_timestamp) +- __field(s64, current_time) +- __field(s64, delta) +- ), +- TP_fast_assign( +- __entry->ec_sensor_num = ec_sensor_num; +- __entry->ec_fifo_timestamp = ec_fifo_timestamp; +- __entry->fifo_timestamp = fifo_timestamp; +- __entry->current_timestamp = current_timestamp; +- __entry->current_time = current_time; +- __entry->delta = current_timestamp - current_time; +- ), +- TP_printk("ec_num: %4u, ec_fifo_ts: %9u, fifo_ts: %12lld, curr_ts: %12lld, curr_time: %12lld, delta %12lld", +- __entry->ec_sensor_num, +- __entry->ec_fifo_timestamp, +- __entry->fifo_timestamp, +- __entry->current_timestamp, +- __entry->current_time, +- __entry->delta +- ) +-); +- +-TRACE_EVENT(cros_ec_sensorhub_filter, +- TP_PROTO(struct cros_ec_sensors_ts_filter_state *state, s64 dx, s64 dy), +- TP_ARGS(state, dx, dy), +- TP_STRUCT__entry( +- __field(s64, dx) +- __field(s64, dy) +- __field(s64, median_m) +- __field(s64, median_error) +- __field(s64, history_len) +- __field(s64, x) +- __field(s64, y) +- ), +- TP_fast_assign( +- __entry->dx = dx; +- __entry->dy = dy; +- __entry->median_m = state->median_m; +- __entry->median_error = state->median_error; +- __entry->history_len = state->history_len; +- __entry->x = state->x_offset; +- __entry->y = state->y_offset; +- ), +- TP_printk("dx: %12lld. dy: %12lld median_m: %12lld median_error: %12lld len: %lld x: %12lld y: %12lld", +- __entry->dx, +- __entry->dy, +- __entry->median_m, +- __entry->median_error, +- __entry->history_len, +- __entry->x, +- __entry->y +- ) +-); +- +- + #endif /* _CROS_EC_TRACE_H_ */ + + /* this part must be outside header guard */ diff --git a/queue-5.17/series b/queue-5.17/series index 8ee97a98d1d..0111518848c 100644 --- a/queue-5.17/series +++ b/queue-5.17/series @@ -992,3 +992,13 @@ scsi-qla2xxx-fix-n2n-inconsistent-plogi.patch scsi-qla2xxx-fix-stuck-session-of-prli-reject.patch scsi-qla2xxx-reduce-false-trigger-to-login.patch scsi-qla2xxx-use-correct-feature-type-field-during-rff_id-processing.patch +platform-chrome-split-trace-include-file.patch +mips-crypto-fix-crc32-code.patch +kvm-x86-check-lapic_in_kernel-before-attempting-to-set-a-synic-irq.patch +kvm-x86-avoid-theoretical-null-pointer-dereference-in-kvm_irq_delivery_to_apic_fast.patch +kvm-x86-forbid-vmm-to-set-synic-stimer-msrs-when-synic-wasn-t-activated.patch +kvm-x86-mmu-do-compare-and-exchange-of-gpte-via-the-user-address.patch +kvm-prevent-module-exit-until-all-vms-are-freed.patch +kvm-x86-fix-sending-pv-ipi.patch +kvm-svm-fix-panic-on-out-of-bounds-guest-irq.patch +kvm-avoid-double-put_page-with-gfn-to-pfn-cache.patch