Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 and cross-arch updates from Catalin Marinas: "Here's a slightly wider-spread set of updates for 5.9. Going outside the usual arch/arm64/ area is the removal of read_barrier_depends() series from Will and the MSI/IOMMU ID translation series from Lorenzo. The notable arm64 updates include ARMv8.4 TLBI range operations and translation level hint, time namespace support, and perf. Summary: - Removal of the tremendously unpopular read_barrier_depends() barrier, which is a NOP on all architectures apart from Alpha, in favour of allowing architectures to override READ_ONCE() and do whatever dance they need to do to ensure address dependencies provide LOAD -> LOAD/STORE ordering. This work also offers a potential solution if compilers are shown to convert LOAD -> LOAD address dependencies into control dependencies (e.g. under LTO), as weakly ordered architectures will effectively be able to upgrade READ_ONCE() to smp_load_acquire(). The latter case is not used yet, but will be discussed further at LPC. - Make the MSI/IOMMU input/output ID translation PCI agnostic, augment the MSI/IOMMU ACPI/OF ID mapping APIs to accept an input ID bus-specific parameter and apply the resulting changes to the device ID space provided by the Freescale FSL bus. - arm64 support for TLBI range operations and translation table level hints (part of the ARMv8.4 architecture version). - Time namespace support for arm64. - Export the virtual and physical address sizes in vmcoreinfo for makedumpfile and crash utilities. - CPU feature handling cleanups and checks for programmer errors (overlapping bit-fields). - ACPI updates for arm64: disallow AML accesses to EFI code regions and kernel memory. - perf updates for arm64. - Miscellaneous fixes and cleanups, most notably PLT counting optimisation for module loading, recordmcount fix to ignore relocations other than R_AARCH64_CALL26, CMA areas reserved for gigantic pages on 16K and 64K configurations. - Trivial typos, duplicate words" Link: http://lkml.kernel.org/r/20200710165203.31284-1-will@kernel.org Link: http://lkml.kernel.org/r/20200619082013.13661-1-lorenzo.pieralisi@arm.com * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (82 commits) arm64: use IRQ_STACK_SIZE instead of THREAD_SIZE for irq stack arm64/mm: save memory access in check_and_switch_context() fast switch path arm64: sigcontext.h: delete duplicated word arm64: ptrace.h: delete duplicated word arm64: pgtable-hwdef.h: delete duplicated words bus: fsl-mc: Add ACPI support for fsl-mc bus/fsl-mc: Refactor the MSI domain creation in the DPRC driver of/irq: Make of_msi_map_rid() PCI bus agnostic of/irq: make of_msi_map_get_device_domain() bus agnostic dt-bindings: arm: fsl: Add msi-map device-tree binding for fsl-mc bus of/device: Add input id to of_dma_configure() of/iommu: Make of_map_rid() PCI agnostic ACPI/IORT: Add an input ID to acpi_dma_configure() ACPI/IORT: Remove useless PCI bus walk ACPI/IORT: Make iort_msi_map_rid() PCI agnostic ACPI/IORT: Make iort_get_device_domain IRQ domain agnostic ACPI/IORT: Make iort_match_node_callback walk the ACPI namespace for NC arm64: enable time namespace support arm64/vdso: Restrict splitting VVAR VMA arm64/vdso: Handle faults on timens page ...
This commit is contained in:
@@ -45,6 +45,7 @@ mandatory-y += pci.h
|
||||
mandatory-y += percpu.h
|
||||
mandatory-y += pgalloc.h
|
||||
mandatory-y += preempt.h
|
||||
mandatory-y += rwonce.h
|
||||
mandatory-y += sections.h
|
||||
mandatory-y += serial.h
|
||||
mandatory-y += shmparam.h
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/rwonce.h>
|
||||
|
||||
#ifndef nop
|
||||
#define nop() asm volatile ("nop")
|
||||
@@ -46,10 +46,6 @@
|
||||
#define dma_wmb() wmb()
|
||||
#endif
|
||||
|
||||
#ifndef read_barrier_depends
|
||||
#define read_barrier_depends() do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifndef __smp_mb
|
||||
#define __smp_mb() mb()
|
||||
#endif
|
||||
@@ -62,10 +58,6 @@
|
||||
#define __smp_wmb() wmb()
|
||||
#endif
|
||||
|
||||
#ifndef __smp_read_barrier_depends
|
||||
#define __smp_read_barrier_depends() read_barrier_depends()
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#ifndef smp_mb
|
||||
@@ -80,10 +72,6 @@
|
||||
#define smp_wmb() __smp_wmb()
|
||||
#endif
|
||||
|
||||
#ifndef smp_read_barrier_depends
|
||||
#define smp_read_barrier_depends() __smp_read_barrier_depends()
|
||||
#endif
|
||||
|
||||
#else /* !CONFIG_SMP */
|
||||
|
||||
#ifndef smp_mb
|
||||
@@ -98,10 +86,6 @@
|
||||
#define smp_wmb() barrier()
|
||||
#endif
|
||||
|
||||
#ifndef smp_read_barrier_depends
|
||||
#define smp_read_barrier_depends() do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifndef __smp_store_mb
|
||||
@@ -196,7 +180,6 @@ do { \
|
||||
#define virt_mb() __smp_mb()
|
||||
#define virt_rmb() __smp_rmb()
|
||||
#define virt_wmb() __smp_wmb()
|
||||
#define virt_read_barrier_depends() __smp_read_barrier_depends()
|
||||
#define virt_store_mb(var, value) __smp_store_mb(var, value)
|
||||
#define virt_mb__before_atomic() __smp_mb__before_atomic()
|
||||
#define virt_mb__after_atomic() __smp_mb__after_atomic()
|
||||
|
90
include/asm-generic/rwonce.h
Normal file
90
include/asm-generic/rwonce.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Prevent the compiler from merging or refetching reads or writes. The
|
||||
* compiler is also forbidden from reordering successive instances of
|
||||
* READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
|
||||
* particular ordering. One way to make the compiler aware of ordering is to
|
||||
* put the two invocations of READ_ONCE or WRITE_ONCE in different C
|
||||
* statements.
|
||||
*
|
||||
* These two macros will also work on aggregate data types like structs or
|
||||
* unions.
|
||||
*
|
||||
* Their two major use cases are: (1) Mediating communication between
|
||||
* process-level code and irq/NMI handlers, all running on the same CPU,
|
||||
* and (2) Ensuring that the compiler does not fold, spindle, or otherwise
|
||||
* mutilate accesses that either do not require ordering or that interact
|
||||
* with an explicit memory barrier or atomic instruction that provides the
|
||||
* required ordering.
|
||||
*/
|
||||
#ifndef __ASM_GENERIC_RWONCE_H
|
||||
#define __ASM_GENERIC_RWONCE_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#include <linux/compiler_types.h>
|
||||
#include <linux/kasan-checks.h>
|
||||
#include <linux/kcsan-checks.h>
|
||||
|
||||
/*
|
||||
* Yes, this permits 64-bit accesses on 32-bit architectures. These will
|
||||
* actually be atomic in some cases (namely Armv7 + LPAE), but for others we
|
||||
* rely on the access being split into 2x32-bit accesses for a 32-bit quantity
|
||||
* (e.g. a virtual address) and a strong prevailing wind.
|
||||
*/
|
||||
#define compiletime_assert_rwonce_type(t) \
|
||||
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
|
||||
"Unsupported access size for {READ,WRITE}_ONCE().")
|
||||
|
||||
/*
|
||||
* Use __READ_ONCE() instead of READ_ONCE() if you do not require any
|
||||
* atomicity. Note that this may result in tears!
|
||||
*/
|
||||
#ifndef __READ_ONCE
|
||||
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
|
||||
#endif
|
||||
|
||||
#define READ_ONCE(x) \
|
||||
({ \
|
||||
compiletime_assert_rwonce_type(x); \
|
||||
__READ_ONCE(x); \
|
||||
})
|
||||
|
||||
#define __WRITE_ONCE(x, val) \
|
||||
do { \
|
||||
*(volatile typeof(x) *)&(x) = (val); \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_ONCE(x, val) \
|
||||
do { \
|
||||
compiletime_assert_rwonce_type(x); \
|
||||
__WRITE_ONCE(x, val); \
|
||||
} while (0)
|
||||
|
||||
static __no_sanitize_or_inline
|
||||
unsigned long __read_once_word_nocheck(const void *addr)
|
||||
{
|
||||
return __READ_ONCE(*(unsigned long *)addr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need to load a
|
||||
* word from memory atomically but without telling KASAN/KCSAN. This is
|
||||
* usually used by unwinding code when walking the stack of a running process.
|
||||
*/
|
||||
#define READ_ONCE_NOCHECK(x) \
|
||||
({ \
|
||||
compiletime_assert(sizeof(x) == sizeof(unsigned long), \
|
||||
"Unsupported access size for READ_ONCE_NOCHECK()."); \
|
||||
(typeof(x))__read_once_word_nocheck(&(x)); \
|
||||
})
|
||||
|
||||
static __no_kasan_or_inline
|
||||
unsigned long read_word_at_a_time(const void *addr)
|
||||
{
|
||||
kasan_check_read(addr, 1);
|
||||
return *(unsigned long *)addr;
|
||||
}
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ASM_GENERIC_RWONCE_H */
|
@@ -512,6 +512,38 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* tlb_flush_{pte|pmd|pud|p4d}_range() adjust the tlb->start and tlb->end,
|
||||
* and set corresponding cleared_*.
|
||||
*/
|
||||
static inline void tlb_flush_pte_range(struct mmu_gather *tlb,
|
||||
unsigned long address, unsigned long size)
|
||||
{
|
||||
__tlb_adjust_range(tlb, address, size);
|
||||
tlb->cleared_ptes = 1;
|
||||
}
|
||||
|
||||
static inline void tlb_flush_pmd_range(struct mmu_gather *tlb,
|
||||
unsigned long address, unsigned long size)
|
||||
{
|
||||
__tlb_adjust_range(tlb, address, size);
|
||||
tlb->cleared_pmds = 1;
|
||||
}
|
||||
|
||||
static inline void tlb_flush_pud_range(struct mmu_gather *tlb,
|
||||
unsigned long address, unsigned long size)
|
||||
{
|
||||
__tlb_adjust_range(tlb, address, size);
|
||||
tlb->cleared_puds = 1;
|
||||
}
|
||||
|
||||
static inline void tlb_flush_p4d_range(struct mmu_gather *tlb,
|
||||
unsigned long address, unsigned long size)
|
||||
{
|
||||
__tlb_adjust_range(tlb, address, size);
|
||||
tlb->cleared_p4ds = 1;
|
||||
}
|
||||
|
||||
#ifndef __tlb_remove_tlb_entry
|
||||
#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
|
||||
#endif
|
||||
@@ -525,19 +557,17 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
*/
|
||||
#define tlb_remove_tlb_entry(tlb, ptep, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
tlb->cleared_ptes = 1; \
|
||||
tlb_flush_pte_range(tlb, address, PAGE_SIZE); \
|
||||
__tlb_remove_tlb_entry(tlb, ptep, address); \
|
||||
} while (0)
|
||||
|
||||
#define tlb_remove_huge_tlb_entry(h, tlb, ptep, address) \
|
||||
do { \
|
||||
unsigned long _sz = huge_page_size(h); \
|
||||
__tlb_adjust_range(tlb, address, _sz); \
|
||||
if (_sz == PMD_SIZE) \
|
||||
tlb->cleared_pmds = 1; \
|
||||
tlb_flush_pmd_range(tlb, address, _sz); \
|
||||
else if (_sz == PUD_SIZE) \
|
||||
tlb->cleared_puds = 1; \
|
||||
tlb_flush_pud_range(tlb, address, _sz); \
|
||||
__tlb_remove_tlb_entry(tlb, ptep, address); \
|
||||
} while (0)
|
||||
|
||||
@@ -551,8 +581,7 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
|
||||
#define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, HPAGE_PMD_SIZE); \
|
||||
tlb->cleared_pmds = 1; \
|
||||
tlb_flush_pmd_range(tlb, address, HPAGE_PMD_SIZE); \
|
||||
__tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \
|
||||
} while (0)
|
||||
|
||||
@@ -566,8 +595,7 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
|
||||
#define tlb_remove_pud_tlb_entry(tlb, pudp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, HPAGE_PUD_SIZE); \
|
||||
tlb->cleared_puds = 1; \
|
||||
tlb_flush_pud_range(tlb, address, HPAGE_PUD_SIZE); \
|
||||
__tlb_remove_pud_tlb_entry(tlb, pudp, address); \
|
||||
} while (0)
|
||||
|
||||
@@ -592,9 +620,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
#ifndef pte_free_tlb
|
||||
#define pte_free_tlb(tlb, ptep, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
tlb_flush_pmd_range(tlb, address, PAGE_SIZE); \
|
||||
tlb->freed_tables = 1; \
|
||||
tlb->cleared_pmds = 1; \
|
||||
__pte_free_tlb(tlb, ptep, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
@@ -602,9 +629,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
#ifndef pmd_free_tlb
|
||||
#define pmd_free_tlb(tlb, pmdp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
tlb_flush_pud_range(tlb, address, PAGE_SIZE); \
|
||||
tlb->freed_tables = 1; \
|
||||
tlb->cleared_puds = 1; \
|
||||
__pmd_free_tlb(tlb, pmdp, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
@@ -612,9 +638,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
|
||||
#ifndef pud_free_tlb
|
||||
#define pud_free_tlb(tlb, pudp, address) \
|
||||
do { \
|
||||
__tlb_adjust_range(tlb, address, PAGE_SIZE); \
|
||||
tlb_flush_p4d_range(tlb, address, PAGE_SIZE); \
|
||||
tlb->freed_tables = 1; \
|
||||
tlb->cleared_p4ds = 1; \
|
||||
__pud_free_tlb(tlb, pudp, address); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user