From: Greg Kroah-Hartman Date: Tue, 13 Aug 2024 12:48:31 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v6.1.105~18 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0bbd2aeb0f38301c66dc7e7f3982e9d1b7a65fd3;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: drm-i915-gem-fix-virtual-memory-mapping-boundaries-calculation.patch powerpc-avoid-nmi_enter-nmi_exit-in-real-mode-interrupt.patch --- diff --git a/queue-5.10/drm-i915-gem-fix-virtual-memory-mapping-boundaries-calculation.patch b/queue-5.10/drm-i915-gem-fix-virtual-memory-mapping-boundaries-calculation.patch new file mode 100644 index 00000000000..6d67524069f --- /dev/null +++ b/queue-5.10/drm-i915-gem-fix-virtual-memory-mapping-boundaries-calculation.patch @@ -0,0 +1,126 @@ +From 8bdd9ef7e9b1b2a73e394712b72b22055e0e26c3 Mon Sep 17 00:00:00 2001 +From: Andi Shyti +Date: Fri, 2 Aug 2024 10:38:50 +0200 +Subject: drm/i915/gem: Fix Virtual Memory mapping boundaries calculation + +From: Andi Shyti + +commit 8bdd9ef7e9b1b2a73e394712b72b22055e0e26c3 upstream. + +Calculating the size of the mapped area as the lesser value +between the requested size and the actual size does not consider +the partial mapping offset. This can cause page fault access. + +Fix the calculation of the starting and ending addresses, the +total size is now deduced from the difference between the end and +start addresses. + +Additionally, the calculations have been rewritten in a clearer +and more understandable form. + +Fixes: c58305af1835 ("drm/i915: Use remap_io_mapping() to prefault all PTE in a single pass") +Reported-by: Jann Horn +Co-developed-by: Chris Wilson +Signed-off-by: Chris Wilson +Signed-off-by: Andi Shyti +Cc: Joonas Lahtinen +Cc: Matthew Auld +Cc: Rodrigo Vivi +Cc: # v4.9+ +Reviewed-by: Jann Horn +Reviewed-by: Jonathan Cavitt +[Joonas: Add Requires: tag] +Requires: 60a2066c5005 ("drm/i915/gem: Adjust vma offset for framebuffer mmap offset") +Signed-off-by: Joonas Lahtinen +Link: https://patchwork.freedesktop.org/patch/msgid/20240802083850.103694-3-andi.shyti@linux.intel.com +(cherry picked from commit 97b6784753da06d9d40232328efc5c5367e53417) +Signed-off-by: Joonas Lahtinen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/i915/gem/i915_gem_mman.c | 53 +++++++++++++++++++++++++++---- + 1 file changed, 47 insertions(+), 6 deletions(-) + +--- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c ++++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c +@@ -273,6 +273,41 @@ out: + return i915_error_to_vmf_fault(err); + } + ++static void set_address_limits(struct vm_area_struct *area, ++ struct i915_vma *vma, ++ unsigned long obj_offset, ++ unsigned long *start_vaddr, ++ unsigned long *end_vaddr) ++{ ++ unsigned long vm_start, vm_end, vma_size; /* user's memory parameters */ ++ long start, end; /* memory boundaries */ ++ ++ /* ++ * Let's move into the ">> PAGE_SHIFT" ++ * domain to be sure not to lose bits ++ */ ++ vm_start = area->vm_start >> PAGE_SHIFT; ++ vm_end = area->vm_end >> PAGE_SHIFT; ++ vma_size = vma->size >> PAGE_SHIFT; ++ ++ /* ++ * Calculate the memory boundaries by considering the offset ++ * provided by the user during memory mapping and the offset ++ * provided for the partial mapping. ++ */ ++ start = vm_start; ++ start -= obj_offset; ++ start += vma->ggtt_view.partial.offset; ++ end = start + vma_size; ++ ++ start = max_t(long, start, vm_start); ++ end = min_t(long, end, vm_end); ++ ++ /* Let's move back into the "<< PAGE_SHIFT" domain */ ++ *start_vaddr = (unsigned long)start << PAGE_SHIFT; ++ *end_vaddr = (unsigned long)end << PAGE_SHIFT; ++} ++ + static vm_fault_t vm_fault_gtt(struct vm_fault *vmf) + { + #define MIN_CHUNK_PAGES (SZ_1M >> PAGE_SHIFT) +@@ -285,14 +320,18 @@ static vm_fault_t vm_fault_gtt(struct vm + struct i915_ggtt *ggtt = &i915->ggtt; + bool write = area->vm_flags & VM_WRITE; + struct i915_gem_ww_ctx ww; ++ unsigned long obj_offset; ++ unsigned long start, end; /* memory boundaries */ + intel_wakeref_t wakeref; + struct i915_vma *vma; + pgoff_t page_offset; ++ unsigned long pfn; + int srcu; + int ret; + +- /* We don't use vmf->pgoff since that has the fake offset */ ++ obj_offset = area->vm_pgoff - drm_vma_node_start(&mmo->vma_node); + page_offset = (vmf->address - area->vm_start) >> PAGE_SHIFT; ++ page_offset += obj_offset; + + trace_i915_gem_object_fault(obj, page_offset, true, write); + +@@ -363,12 +402,14 @@ retry: + if (ret) + goto err_unpin; + ++ set_address_limits(area, vma, obj_offset, &start, &end); ++ ++ pfn = (ggtt->gmadr.start + i915_ggtt_offset(vma)) >> PAGE_SHIFT; ++ pfn += (start - area->vm_start) >> PAGE_SHIFT; ++ pfn += obj_offset - vma->ggtt_view.partial.offset; ++ + /* Finally, remap it using the new GTT offset */ +- ret = remap_io_mapping(area, +- area->vm_start + (vma->ggtt_view.partial.offset << PAGE_SHIFT), +- (ggtt->gmadr.start + vma->node.start) >> PAGE_SHIFT, +- min_t(u64, vma->size, area->vm_end - area->vm_start), +- &ggtt->iomap); ++ ret = remap_io_mapping(area, start, pfn, end - start, &ggtt->iomap); + if (ret) + goto err_fence; + diff --git a/queue-5.10/powerpc-avoid-nmi_enter-nmi_exit-in-real-mode-interrupt.patch b/queue-5.10/powerpc-avoid-nmi_enter-nmi_exit-in-real-mode-interrupt.patch new file mode 100644 index 00000000000..08e1d0c7af7 --- /dev/null +++ b/queue-5.10/powerpc-avoid-nmi_enter-nmi_exit-in-real-mode-interrupt.patch @@ -0,0 +1,134 @@ +From 0db880fc865ffb522141ced4bfa66c12ab1fbb70 Mon Sep 17 00:00:00 2001 +From: Mahesh Salgaonkar +Date: Wed, 10 Apr 2024 10:00:06 +0530 +Subject: powerpc: Avoid nmi_enter/nmi_exit in real mode interrupt. + +From: Mahesh Salgaonkar + +commit 0db880fc865ffb522141ced4bfa66c12ab1fbb70 upstream. + +nmi_enter()/nmi_exit() touches per cpu variables which can lead to kernel +crash when invoked during real mode interrupt handling (e.g. early HMI/MCE +interrupt handler) if percpu allocation comes from vmalloc area. + +Early HMI/MCE handlers are called through DEFINE_INTERRUPT_HANDLER_NMI() +wrapper which invokes nmi_enter/nmi_exit calls. We don't see any issue when +percpu allocation is from the embedded first chunk. However with +CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled there are chances where percpu +allocation can come from the vmalloc area. + +With kernel command line "percpu_alloc=page" we can force percpu allocation +to come from vmalloc area and can see kernel crash in machine_check_early: + +[ 1.215714] NIP [c000000000e49eb4] rcu_nmi_enter+0x24/0x110 +[ 1.215717] LR [c0000000000461a0] machine_check_early+0xf0/0x2c0 +[ 1.215719] --- interrupt: 200 +[ 1.215720] [c000000fffd73180] [0000000000000000] 0x0 (unreliable) +[ 1.215722] [c000000fffd731b0] [0000000000000000] 0x0 +[ 1.215724] [c000000fffd73210] [c000000000008364] machine_check_early_common+0x134/0x1f8 + +Fix this by avoiding use of nmi_enter()/nmi_exit() in real mode if percpu +first chunk is not embedded. + +Reviewed-by: Christophe Leroy +Tested-by: Shirisha Ganta +Signed-off-by: Mahesh Salgaonkar +Signed-off-by: Michael Ellerman +Link: https://msgid.link/20240410043006.81577-1-mahesh@linux.ibm.com +[ Conflicts in arch/powerpc/include/asm/interrupt.h + because machine_check_early() and machine_check_exception() + has been refactored. ] +Signed-off-by: Jinjie Ruan +Signed-off-by: Greg Kroah-Hartman +--- + arch/powerpc/include/asm/percpu.h | 10 ++++++++++ + arch/powerpc/kernel/mce.c | 14 +++++++++++--- + arch/powerpc/kernel/setup_64.c | 2 ++ + arch/powerpc/kernel/traps.c | 8 +++++++- + 4 files changed, 30 insertions(+), 4 deletions(-) + +--- a/arch/powerpc/include/asm/percpu.h ++++ b/arch/powerpc/include/asm/percpu.h +@@ -15,6 +15,16 @@ + #endif /* CONFIG_SMP */ + #endif /* __powerpc64__ */ + ++#if defined(CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK) && defined(CONFIG_SMP) ++#include ++DECLARE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged); ++ ++#define percpu_first_chunk_is_paged \ ++ (static_key_enabled(&__percpu_first_chunk_is_paged.key)) ++#else ++#define percpu_first_chunk_is_paged false ++#endif /* CONFIG_PPC64 && CONFIG_SMP */ ++ + #include + + #include +--- a/arch/powerpc/kernel/mce.c ++++ b/arch/powerpc/kernel/mce.c +@@ -594,8 +594,15 @@ long notrace machine_check_early(struct + u8 ftrace_enabled = this_cpu_get_ftrace_enabled(); + + this_cpu_set_ftrace_enabled(0); +- /* Do not use nmi_enter/exit for pseries hpte guest */ +- if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) ++ /* ++ * Do not use nmi_enter/exit for pseries hpte guest ++ * ++ * Likewise, do not use it in real mode if percpu first chunk is not ++ * embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled there ++ * are chances where percpu allocation can come from vmalloc area. ++ */ ++ if ((radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) && ++ !percpu_first_chunk_is_paged) + nmi_enter(); + + hv_nmi_check_nonrecoverable(regs); +@@ -606,7 +613,8 @@ long notrace machine_check_early(struct + if (ppc_md.machine_check_early) + handled = ppc_md.machine_check_early(regs); + +- if (radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) ++ if ((radix_enabled() || !firmware_has_feature(FW_FEATURE_LPAR)) && ++ !percpu_first_chunk_is_paged) + nmi_exit(); + + this_cpu_set_ftrace_enabled(ftrace_enabled); +--- a/arch/powerpc/kernel/setup_64.c ++++ b/arch/powerpc/kernel/setup_64.c +@@ -824,6 +824,7 @@ static int pcpu_cpu_distance(unsigned in + + unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; + EXPORT_SYMBOL(__per_cpu_offset); ++DEFINE_STATIC_KEY_FALSE(__percpu_first_chunk_is_paged); + + static void __init pcpu_populate_pte(unsigned long addr) + { +@@ -903,6 +904,7 @@ void __init setup_per_cpu_areas(void) + if (rc < 0) + panic("cannot initialize percpu area (err=%d)", rc); + ++ static_key_enable(&__percpu_first_chunk_is_paged.key); + delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; + for_each_possible_cpu(cpu) { + __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; +--- a/arch/powerpc/kernel/traps.c ++++ b/arch/powerpc/kernel/traps.c +@@ -835,8 +835,14 @@ void machine_check_exception(struct pt_r + * This is silly. The BOOK3S_64 should just call a different function + * rather than expecting semantics to magically change. Something + * like 'non_nmi_machine_check_exception()', perhaps? ++ * ++ * Do not use nmi_enter/exit in real mode if percpu first chunk is ++ * not embedded. With CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK enabled ++ * there are chances where percpu allocation can come from ++ * vmalloc area. + */ +- const bool nmi = !IS_ENABLED(CONFIG_PPC_BOOK3S_64); ++ const bool nmi = !IS_ENABLED(CONFIG_PPC_BOOK3S_64) && ++ !percpu_first_chunk_is_paged; + + if (nmi) nmi_enter(); + diff --git a/queue-5.10/series b/queue-5.10/series index 2a684876e46..79bac552005 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -351,3 +351,5 @@ netfilter-nf_tables-set-element-extended-ack-reporting-support.patch netfilter-nf_tables-use-timestamp-to-check-for-set-element-timeout.patch netfilter-nf_tables-allow-clone-callbacks-to-sleep.patch netfilter-nf_tables-prefer-nft_chain_validate.patch +drm-i915-gem-fix-virtual-memory-mapping-boundaries-calculation.patch +powerpc-avoid-nmi_enter-nmi_exit-in-real-mode-interrupt.patch