Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux into master

Pull arm64 fixes from Will Deacon:
"A batch of arm64 fixes.

Although the diffstat is a bit larger than we'd usually have at this
stage, a decent amount of it is the addition of comments describing
our syscall tracing behaviour, and also a sweep across all the modular
arm64 PMU drivers to make them rebust against unloading and unbinding.

There are a couple of minor things kicking around at the moment (CPU
errata and module PLTs for very large modules), but I'm not expecting
any significant changes now for us in 5.8.

- Fix kernel text addresses for relocatable images booting using EFI
and with KASLR disabled so that they match the vmlinux ELF binary.

- Fix unloading and unbinding of PMU driver modules.

- Fix generic mmiowb() when writeX() is called from preemptible
context (reported by the riscv folks).

- Fix ptrace hardware single-step interactions with signal handlers,
system calls and reverse debugging.

- Fix reporting of 64-bit x0 register for 32-bit tasks via
'perf_regs'.

- Add comments describing syscall entry/exit tracing ABI"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
drivers/perf: Prevent forced unbinding of PMU drivers
asm-generic/mmiowb: Allow mmiowb_set_pending() when preemptible()
arm64: Use test_tsk_thread_flag() for checking TIF_SINGLESTEP
arm64: ptrace: Use NO_SYSCALL instead of -1 in syscall_trace_enter()
arm64: syscall: Expand the comment about ptrace and syscall(-1)
arm64: ptrace: Add a comment describing our syscall entry/exit trap ABI
arm64: compat: Ensure upper 32 bits of x0 are zero on syscall return
arm64: ptrace: Override SPSR.SS when single-stepping is enabled
arm64: ptrace: Consistently use pseudo-singlestep exceptions
drivers/perf: Fix kernel panic when rmmod PMU modules during perf sampling
efi/libstub/arm64: Retain 2MB kernel Image alignment if !KASLR

+127 -44
+2
arch/arm64/include/asm/debug-monitors.h
··· 109 109 110 110 void user_rewind_single_step(struct task_struct *task); 111 111 void user_fastforward_single_step(struct task_struct *task); 112 + void user_regs_reset_single_step(struct user_pt_regs *regs, 113 + struct task_struct *task); 112 114 113 115 void kernel_enable_single_step(struct pt_regs *regs); 114 116 void kernel_disable_single_step(void);
+11 -1
arch/arm64/include/asm/syscall.h
··· 34 34 struct pt_regs *regs) 35 35 { 36 36 unsigned long error = regs->regs[0]; 37 + 38 + if (is_compat_thread(task_thread_info(task))) 39 + error = sign_extend64(error, 31); 40 + 37 41 return IS_ERR_VALUE(error) ? error : 0; 38 42 } 39 43 ··· 51 47 struct pt_regs *regs, 52 48 int error, long val) 53 49 { 54 - regs->regs[0] = (long) error ? error : val; 50 + if (error) 51 + val = error; 52 + 53 + if (is_compat_thread(task_thread_info(task))) 54 + val = lower_32_bits(val); 55 + 56 + regs->regs[0] = val; 55 57 } 56 58 57 59 #define SYSCALL_MAX_ARGS 6
+1
arch/arm64/include/asm/thread_info.h
··· 93 93 #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) 94 94 #define _TIF_UPROBE (1 << TIF_UPROBE) 95 95 #define _TIF_FSCHECK (1 << TIF_FSCHECK) 96 + #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) 96 97 #define _TIF_32BIT (1 << TIF_32BIT) 97 98 #define _TIF_SVE (1 << TIF_SVE) 98 99
+18 -6
arch/arm64/kernel/debug-monitors.c
··· 141 141 /* 142 142 * Single step API and exception handling. 143 143 */ 144 - static void set_regs_spsr_ss(struct pt_regs *regs) 144 + static void set_user_regs_spsr_ss(struct user_pt_regs *regs) 145 145 { 146 146 regs->pstate |= DBG_SPSR_SS; 147 147 } 148 - NOKPROBE_SYMBOL(set_regs_spsr_ss); 148 + NOKPROBE_SYMBOL(set_user_regs_spsr_ss); 149 149 150 - static void clear_regs_spsr_ss(struct pt_regs *regs) 150 + static void clear_user_regs_spsr_ss(struct user_pt_regs *regs) 151 151 { 152 152 regs->pstate &= ~DBG_SPSR_SS; 153 153 } 154 - NOKPROBE_SYMBOL(clear_regs_spsr_ss); 154 + NOKPROBE_SYMBOL(clear_user_regs_spsr_ss); 155 + 156 + #define set_regs_spsr_ss(r) set_user_regs_spsr_ss(&(r)->user_regs) 157 + #define clear_regs_spsr_ss(r) clear_user_regs_spsr_ss(&(r)->user_regs) 155 158 156 159 static DEFINE_SPINLOCK(debug_hook_lock); 157 160 static LIST_HEAD(user_step_hook); ··· 394 391 * If single step is active for this thread, then set SPSR.SS 395 392 * to 1 to avoid returning to the active-pending state. 396 393 */ 397 - if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)) 394 + if (test_tsk_thread_flag(task, TIF_SINGLESTEP)) 398 395 set_regs_spsr_ss(task_pt_regs(task)); 399 396 } 400 397 NOKPROBE_SYMBOL(user_rewind_single_step); 401 398 402 399 void user_fastforward_single_step(struct task_struct *task) 403 400 { 404 - if (test_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP)) 401 + if (test_tsk_thread_flag(task, TIF_SINGLESTEP)) 405 402 clear_regs_spsr_ss(task_pt_regs(task)); 403 + } 404 + 405 + void user_regs_reset_single_step(struct user_pt_regs *regs, 406 + struct task_struct *task) 407 + { 408 + if (test_tsk_thread_flag(task, TIF_SINGLESTEP)) 409 + set_user_regs_spsr_ss(regs); 410 + else 411 + clear_user_regs_spsr_ss(regs); 406 412 } 407 413 408 414 /* Kernel API */
+37 -12
arch/arm64/kernel/ptrace.c
··· 1811 1811 unsigned long saved_reg; 1812 1812 1813 1813 /* 1814 - * A scratch register (ip(r12) on AArch32, x7 on AArch64) is 1815 - * used to denote syscall entry/exit: 1814 + * We have some ABI weirdness here in the way that we handle syscall 1815 + * exit stops because we indicate whether or not the stop has been 1816 + * signalled from syscall entry or syscall exit by clobbering a general 1817 + * purpose register (ip/r12 for AArch32, x7 for AArch64) in the tracee 1818 + * and restoring its old value after the stop. This means that: 1819 + * 1820 + * - Any writes by the tracer to this register during the stop are 1821 + * ignored/discarded. 1822 + * 1823 + * - The actual value of the register is not available during the stop, 1824 + * so the tracer cannot save it and restore it later. 1825 + * 1826 + * - Syscall stops behave differently to seccomp and pseudo-step traps 1827 + * (the latter do not nobble any registers). 1816 1828 */ 1817 1829 regno = (is_compat_task() ? 12 : 7); 1818 1830 saved_reg = regs->regs[regno]; 1819 1831 regs->regs[regno] = dir; 1820 1832 1821 - if (dir == PTRACE_SYSCALL_EXIT) 1833 + if (dir == PTRACE_SYSCALL_ENTER) { 1834 + if (tracehook_report_syscall_entry(regs)) 1835 + forget_syscall(regs); 1836 + regs->regs[regno] = saved_reg; 1837 + } else if (!test_thread_flag(TIF_SINGLESTEP)) { 1822 1838 tracehook_report_syscall_exit(regs, 0); 1823 - else if (tracehook_report_syscall_entry(regs)) 1824 - forget_syscall(regs); 1839 + regs->regs[regno] = saved_reg; 1840 + } else { 1841 + regs->regs[regno] = saved_reg; 1825 1842 1826 - regs->regs[regno] = saved_reg; 1843 + /* 1844 + * Signal a pseudo-step exception since we are stepping but 1845 + * tracer modifications to the registers may have rewound the 1846 + * state machine. 1847 + */ 1848 + tracehook_report_syscall_exit(regs, 1); 1849 + } 1827 1850 } 1828 1851 1829 1852 int syscall_trace_enter(struct pt_regs *regs) ··· 1856 1833 if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { 1857 1834 tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER); 1858 1835 if (!in_syscall(regs) || (flags & _TIF_SYSCALL_EMU)) 1859 - return -1; 1836 + return NO_SYSCALL; 1860 1837 } 1861 1838 1862 1839 /* Do the secure computing after ptrace; failures should be fast. */ 1863 1840 if (secure_computing() == -1) 1864 - return -1; 1841 + return NO_SYSCALL; 1865 1842 1866 1843 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 1867 1844 trace_sys_enter(regs, regs->syscallno); ··· 1874 1851 1875 1852 void syscall_trace_exit(struct pt_regs *regs) 1876 1853 { 1854 + unsigned long flags = READ_ONCE(current_thread_info()->flags); 1855 + 1877 1856 audit_syscall_exit(regs); 1878 1857 1879 - if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 1858 + if (flags & _TIF_SYSCALL_TRACEPOINT) 1880 1859 trace_sys_exit(regs, regs_return_value(regs)); 1881 1860 1882 - if (test_thread_flag(TIF_SYSCALL_TRACE)) 1861 + if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)) 1883 1862 tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT); 1884 1863 1885 1864 rseq_syscall(regs); ··· 1959 1934 */ 1960 1935 int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task) 1961 1936 { 1962 - if (!test_tsk_thread_flag(task, TIF_SINGLESTEP)) 1963 - regs->pstate &= ~DBG_SPSR_SS; 1937 + /* https://lore.kernel.org/lkml/20191118131525.GA4180@willie-the-truck */ 1938 + user_regs_reset_single_step(regs, task); 1964 1939 1965 1940 if (is_compat_thread(task_thread_info(task))) 1966 1941 return valid_compat_regs(regs);
+2 -9
arch/arm64/kernel/signal.c
··· 800 800 */ 801 801 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) 802 802 { 803 - struct task_struct *tsk = current; 804 803 sigset_t *oldset = sigmask_to_save(); 805 804 int usig = ksig->sig; 806 805 int ret; ··· 823 824 */ 824 825 ret |= !valid_user_regs(&regs->user_regs, current); 825 826 826 - /* 827 - * Fast forward the stepping logic so we step into the signal 828 - * handler. 829 - */ 830 - if (!ret) 831 - user_fastforward_single_step(tsk); 832 - 833 - signal_setup_done(ret, ksig, 0); 827 + /* Step into the signal handler if we are stepping */ 828 + signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); 834 829 } 835 830 836 831 /*
+19 -2
arch/arm64/kernel/syscall.c
··· 50 50 ret = do_ni_syscall(regs, scno); 51 51 } 52 52 53 + if (is_compat_task()) 54 + ret = lower_32_bits(ret); 55 + 53 56 regs->regs[0] = ret; 54 57 } 55 58 ··· 124 121 user_exit(); 125 122 126 123 if (has_syscall_work(flags)) { 127 - /* set default errno for user-issued syscall(-1) */ 124 + /* 125 + * The de-facto standard way to skip a system call using ptrace 126 + * is to set the system call to -1 (NO_SYSCALL) and set x0 to a 127 + * suitable error code for consumption by userspace. However, 128 + * this cannot be distinguished from a user-issued syscall(-1) 129 + * and so we must set x0 to -ENOSYS here in case the tracer doesn't 130 + * issue the skip and we fall into trace_exit with x0 preserved. 131 + * 132 + * This is slightly odd because it also means that if a tracer 133 + * sets the system call number to -1 but does not initialise x0, 134 + * then x0 will be preserved for all system calls apart from a 135 + * user-issued syscall(-1). However, requesting a skip and not 136 + * setting the return value is unlikely to do anything sensible 137 + * anyway. 138 + */ 128 139 if (scno == NO_SYSCALL) 129 140 regs->regs[0] = -ENOSYS; 130 141 scno = syscall_trace_enter(regs); ··· 156 139 if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { 157 140 local_daif_mask(); 158 141 flags = current_thread_info()->flags; 159 - if (!has_syscall_work(flags)) { 142 + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { 160 143 /* 161 144 * We're off to userspace, where interrupts are 162 145 * always enabled after we restore the flags from
+14 -11
drivers/firmware/efi/libstub/arm64-stub.c
··· 35 35 } 36 36 37 37 /* 38 - * Relocatable kernels can fix up the misalignment with respect to 39 - * MIN_KIMG_ALIGN, so they only require a minimum alignment of EFI_KIMG_ALIGN 40 - * (which accounts for the alignment of statically allocated objects such as 41 - * the swapper stack.) 38 + * Although relocatable kernels can fix up the misalignment with respect to 39 + * MIN_KIMG_ALIGN, the resulting virtual text addresses are subtly out of 40 + * sync with those recorded in the vmlinux when kaslr is disabled but the 41 + * image required relocation anyway. Therefore retain 2M alignment unless 42 + * KASLR is in use. 42 43 */ 43 - static const u64 min_kimg_align = IS_ENABLED(CONFIG_RELOCATABLE) ? EFI_KIMG_ALIGN 44 - : MIN_KIMG_ALIGN; 44 + static u64 min_kimg_align(void) 45 + { 46 + return efi_nokaslr ? MIN_KIMG_ALIGN : EFI_KIMG_ALIGN; 47 + } 45 48 46 49 efi_status_t handle_kernel_image(unsigned long *image_addr, 47 50 unsigned long *image_size, ··· 77 74 78 75 kernel_size = _edata - _text; 79 76 kernel_memsize = kernel_size + (_end - _edata); 80 - *reserve_size = kernel_memsize + TEXT_OFFSET % min_kimg_align; 77 + *reserve_size = kernel_memsize + TEXT_OFFSET % min_kimg_align(); 81 78 82 79 if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && phys_seed != 0) { 83 80 /* 84 81 * If KASLR is enabled, and we have some randomness available, 85 82 * locate the kernel at a randomized offset in physical memory. 86 83 */ 87 - status = efi_random_alloc(*reserve_size, min_kimg_align, 84 + status = efi_random_alloc(*reserve_size, min_kimg_align(), 88 85 reserve_addr, phys_seed); 89 86 } else { 90 87 status = EFI_OUT_OF_RESOURCES; 91 88 } 92 89 93 90 if (status != EFI_SUCCESS) { 94 - if (IS_ALIGNED((u64)_text - TEXT_OFFSET, min_kimg_align)) { 91 + if (IS_ALIGNED((u64)_text - TEXT_OFFSET, min_kimg_align())) { 95 92 /* 96 93 * Just execute from wherever we were loaded by the 97 94 * UEFI PE/COFF loader if the alignment is suitable. ··· 102 99 } 103 100 104 101 status = efi_allocate_pages_aligned(*reserve_size, reserve_addr, 105 - ULONG_MAX, min_kimg_align); 102 + ULONG_MAX, min_kimg_align()); 106 103 107 104 if (status != EFI_SUCCESS) { 108 105 efi_err("Failed to relocate kernel\n"); ··· 111 108 } 112 109 } 113 110 114 - *image_addr = *reserve_addr + TEXT_OFFSET % min_kimg_align; 111 + *image_addr = *reserve_addr + TEXT_OFFSET % min_kimg_align(); 115 112 memcpy((void *)*image_addr, _text, kernel_size); 116 113 117 114 return EFI_SUCCESS;
+1 -1
drivers/firmware/efi/libstub/efi-stub-helper.c
··· 19 19 #include "efistub.h" 20 20 21 21 bool efi_nochunk; 22 - bool efi_nokaslr; 22 + bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); 23 23 bool efi_noinitrd; 24 24 int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; 25 25 bool efi_novamap;
+1
drivers/perf/arm-cci.c
··· 1718 1718 .driver = { 1719 1719 .name = DRIVER_NAME, 1720 1720 .of_match_table = arm_cci_pmu_matches, 1721 + .suppress_bind_attrs = true, 1721 1722 }, 1722 1723 .probe = cci_pmu_probe, 1723 1724 .remove = cci_pmu_remove,
+1
drivers/perf/arm-ccn.c
··· 1545 1545 .driver = { 1546 1546 .name = "arm-ccn", 1547 1547 .of_match_table = arm_ccn_match, 1548 + .suppress_bind_attrs = true, 1548 1549 }, 1549 1550 .probe = arm_ccn_probe, 1550 1551 .remove = arm_ccn_remove,
+1
drivers/perf/arm_dsu_pmu.c
··· 757 757 .driver = { 758 758 .name = DRVNAME, 759 759 .of_match_table = of_match_ptr(dsu_pmu_of_match), 760 + .suppress_bind_attrs = true, 760 761 }, 761 762 .probe = dsu_pmu_device_probe, 762 763 .remove = dsu_pmu_device_remove,
+2
drivers/perf/arm_smmuv3_pmu.c
··· 742 742 platform_set_drvdata(pdev, smmu_pmu); 743 743 744 744 smmu_pmu->pmu = (struct pmu) { 745 + .module = THIS_MODULE, 745 746 .task_ctx_nr = perf_invalid_context, 746 747 .pmu_enable = smmu_pmu_enable, 747 748 .pmu_disable = smmu_pmu_disable, ··· 860 859 static struct platform_driver smmu_pmu_driver = { 861 860 .driver = { 862 861 .name = "arm-smmu-v3-pmcg", 862 + .suppress_bind_attrs = true, 863 863 }, 864 864 .probe = smmu_pmu_probe, 865 865 .remove = smmu_pmu_remove,
+1
drivers/perf/arm_spe_pmu.c
··· 1226 1226 .driver = { 1227 1227 .name = DRVNAME, 1228 1228 .of_match_table = of_match_ptr(arm_spe_pmu_of_match), 1229 + .suppress_bind_attrs = true, 1229 1230 }, 1230 1231 .probe = arm_spe_pmu_device_probe, 1231 1232 .remove = arm_spe_pmu_device_remove,
+2
drivers/perf/fsl_imx8_ddr_perf.c
··· 512 512 { 513 513 *pmu = (struct ddr_pmu) { 514 514 .pmu = (struct pmu) { 515 + .module = THIS_MODULE, 515 516 .capabilities = PERF_PMU_CAP_NO_EXCLUDE, 516 517 .task_ctx_nr = perf_invalid_context, 517 518 .attr_groups = attr_groups, ··· 707 706 .driver = { 708 707 .name = "imx-ddr-pmu", 709 708 .of_match_table = imx_ddr_pmu_dt_ids, 709 + .suppress_bind_attrs = true, 710 710 }, 711 711 .probe = ddr_perf_probe, 712 712 .remove = ddr_perf_remove,
+2
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
··· 378 378 ddrc_pmu->sccl_id, ddrc_pmu->index_id); 379 379 ddrc_pmu->pmu = (struct pmu) { 380 380 .name = name, 381 + .module = THIS_MODULE, 381 382 .task_ctx_nr = perf_invalid_context, 382 383 .event_init = hisi_uncore_pmu_event_init, 383 384 .pmu_enable = hisi_uncore_pmu_enable, ··· 419 418 .driver = { 420 419 .name = "hisi_ddrc_pmu", 421 420 .acpi_match_table = ACPI_PTR(hisi_ddrc_pmu_acpi_match), 421 + .suppress_bind_attrs = true, 422 422 }, 423 423 .probe = hisi_ddrc_pmu_probe, 424 424 .remove = hisi_ddrc_pmu_remove,
+2
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
··· 390 390 hha_pmu->sccl_id, hha_pmu->index_id); 391 391 hha_pmu->pmu = (struct pmu) { 392 392 .name = name, 393 + .module = THIS_MODULE, 393 394 .task_ctx_nr = perf_invalid_context, 394 395 .event_init = hisi_uncore_pmu_event_init, 395 396 .pmu_enable = hisi_uncore_pmu_enable, ··· 431 430 .driver = { 432 431 .name = "hisi_hha_pmu", 433 432 .acpi_match_table = ACPI_PTR(hisi_hha_pmu_acpi_match), 433 + .suppress_bind_attrs = true, 434 434 }, 435 435 .probe = hisi_hha_pmu_probe, 436 436 .remove = hisi_hha_pmu_remove,
+2
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
··· 380 380 l3c_pmu->sccl_id, l3c_pmu->index_id); 381 381 l3c_pmu->pmu = (struct pmu) { 382 382 .name = name, 383 + .module = THIS_MODULE, 383 384 .task_ctx_nr = perf_invalid_context, 384 385 .event_init = hisi_uncore_pmu_event_init, 385 386 .pmu_enable = hisi_uncore_pmu_enable, ··· 421 420 .driver = { 422 421 .name = "hisi_l3c_pmu", 423 422 .acpi_match_table = ACPI_PTR(hisi_l3c_pmu_acpi_match), 423 + .suppress_bind_attrs = true, 424 424 }, 425 425 .probe = hisi_l3c_pmu_probe, 426 426 .remove = hisi_l3c_pmu_remove,
+1
drivers/perf/qcom_l2_pmu.c
··· 1028 1028 .driver = { 1029 1029 .name = "qcom-l2cache-pmu", 1030 1030 .acpi_match_table = ACPI_PTR(l2_cache_pmu_acpi_match), 1031 + .suppress_bind_attrs = true, 1031 1032 }, 1032 1033 .probe = l2_cache_pmu_probe, 1033 1034 .remove = l2_cache_pmu_remove,
+1
drivers/perf/qcom_l3_pmu.c
··· 814 814 .driver = { 815 815 .name = "qcom-l3cache-pmu", 816 816 .acpi_match_table = ACPI_PTR(qcom_l3_cache_pmu_acpi_match), 817 + .suppress_bind_attrs = true, 817 818 }, 818 819 .probe = qcom_l3_cache_pmu_probe, 819 820 };
+1
drivers/perf/thunderx2_pmu.c
··· 1017 1017 .driver = { 1018 1018 .name = "tx2-uncore-pmu", 1019 1019 .acpi_match_table = ACPI_PTR(tx2_uncore_acpi_match), 1020 + .suppress_bind_attrs = true, 1020 1021 }, 1021 1022 .probe = tx2_uncore_probe, 1022 1023 .remove = tx2_uncore_remove,
+1
drivers/perf/xgene_pmu.c
··· 1975 1975 .name = "xgene-pmu", 1976 1976 .of_match_table = xgene_pmu_of_match, 1977 1977 .acpi_match_table = ACPI_PTR(xgene_pmu_acpi_match), 1978 + .suppress_bind_attrs = true, 1978 1979 }, 1979 1980 }; 1980 1981
+4 -2
include/asm-generic/mmiowb.h
··· 27 27 #include <asm/smp.h> 28 28 29 29 DECLARE_PER_CPU(struct mmiowb_state, __mmiowb_state); 30 - #define __mmiowb_state() this_cpu_ptr(&__mmiowb_state) 30 + #define __mmiowb_state() raw_cpu_ptr(&__mmiowb_state) 31 31 #else 32 32 #define __mmiowb_state() arch_mmiowb_state() 33 33 #endif /* arch_mmiowb_state */ ··· 35 35 static inline void mmiowb_set_pending(void) 36 36 { 37 37 struct mmiowb_state *ms = __mmiowb_state(); 38 - ms->mmiowb_pending = ms->nesting_count; 38 + 39 + if (likely(ms->nesting_count)) 40 + ms->mmiowb_pending = ms->nesting_count; 39 41 } 40 42 41 43 static inline void mmiowb_spin_lock(void)